refactor: global modals to cards

This commit is contained in:
2024-05-23 15:01:30 +02:00
parent a529d6e9eb
commit 4c1fcf710b
7 changed files with 94 additions and 109 deletions
+8 -8
View File
@@ -1,8 +1,8 @@
<template> <template>
<div class="app_container"> <div class="app_container">
<UpdateModal <UpdateCard
:update-modal-open="isUpdateModalOpen" :is-update-card-open="isUpdateCardOpen"
@toggle-modal="() => (isUpdateModalOpen = false)" @toggle-card="() => (isUpdateCardOpen = false)"
/> />
<Tooltip /> <Tooltip />
@@ -27,7 +27,7 @@
&copy; &copy;
<a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a> <a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a>
{{ new Date().getUTCFullYear() }} | {{ new Date().getUTCFullYear() }} |
<button class="btn--text" @click="() => (isUpdateModalOpen = true)"> <button class="btn--text" @click="() => (isUpdateCardOpen = true)">
v{{ VERSION }}{{ isOnProductionHost ? '' : 'dev' }} v{{ VERSION }}{{ isOnProductionHost ? '' : 'dev' }}
</button> </button>
@@ -56,7 +56,7 @@ import StatusIndicator from './components/App/StatusIndicator.vue';
import AppHeader from './components/App/AppHeader.vue'; import AppHeader from './components/App/AppHeader.vue';
import TrainModal from './components/TrainsView/TrainModal.vue'; import TrainModal from './components/TrainsView/TrainModal.vue';
import Tooltip from './components/Tooltip/Tooltip.vue'; import Tooltip from './components/Tooltip/Tooltip.vue';
import UpdateModal from './components/App/UpdateModal.vue'; import UpdateCard from './components/App/UpdateCard.vue';
import StorageManager from './managers/storageManager'; import StorageManager from './managers/storageManager';
@@ -68,7 +68,7 @@ export default defineComponent({
StatusIndicator, StatusIndicator,
AppHeader, AppHeader,
TrainModal, TrainModal,
UpdateModal, UpdateCard,
Tooltip Tooltip
}, },
@@ -78,7 +78,7 @@ export default defineComponent({
apiStore: useApiStore(), apiStore: useApiStore(),
tooltipStore: useTooltipStore(), tooltipStore: useTooltipStore(),
isUpdateModalOpen: false, isUpdateCardOpen: false,
currentLang: 'pl', currentLang: 'pl',
isOnProductionHost: location.hostname == 'stacjownik-td2.web.app', isOnProductionHost: location.hostname == 'stacjownik-td2.web.app',
@@ -130,7 +130,7 @@ export default defineComponent({
releaseURL: releaseData.html_url releaseURL: releaseData.html_url
}; };
this.isUpdateModalOpen = this.isUpdateCardOpen =
storageVersion != version || import.meta.env.VITE_UPDATE_TEST === 'test'; storageVersion != version || import.meta.env.VITE_UPDATE_TEST === 'test';
} catch (error) { } catch (error) {
console.error(`Wystąpił błąd podczas pobierania danych z API GitHuba: ${error}`); console.error(`Wystąpił błąd podczas pobierania danych z API GitHuba: ${error}`);
@@ -1,12 +1,12 @@
<template> <template>
<AnimatedModal :is-open="updateModalOpen" @toggle-modal="toggleModal(false)"> <Card :is-open="isUpdateCardOpen" @toggle-card="toggleCard(false)">
<div class="modal-content"> <div class="content">
<h1 style="margin-bottom: 0.5em">🚀 {{ $t('update.title') }}</h1> <h1 style="margin-bottom: 0.5em">🚀 {{ $t('update.title') }}</h1>
<div class="features-body" v-if="htmlChangelog != ''" v-html="htmlChangelog"></div> <div class="features-body" v-if="htmlChangelog != ''" v-html="htmlChangelog"></div>
<div class="no-features" v-else>{{ $t('update.no-data') }}</div> <div class="no-features" v-else>{{ $t('update.no-data') }}</div>
<button class="btn btn--action" ref="confirm-btn" @click="toggleModal(false)"> <button class="btn btn--action" ref="confirm-btn" @click="toggleCard(false)">
{{ $t('update.confirm') }} {{ $t('update.confirm') }}
</button> </button>
@@ -16,7 +16,7 @@
<span v-html="$t('update.info-2')"></span> <span v-html="$t('update.info-2')"></span>
</p> </p>
</div> </div>
</AnimatedModal> </Card>
</template> </template>
<script lang="ts"> <script lang="ts">
@@ -25,21 +25,21 @@ import { useMainStore } from '../../store/mainStore';
import { version } from '../../../package.json'; import { version } from '../../../package.json';
import { Converter } from 'showdown'; import { Converter } from 'showdown';
import AnimatedModal from '../Global/AnimatedModal.vue'; import Card from '../Global/Card.vue';
const converter = new Converter(); const converter = new Converter();
export default defineComponent({ export default defineComponent({
components: { AnimatedModal }, components: { Card },
props: { props: {
updateModalOpen: { isUpdateCardOpen: {
type: Boolean, type: Boolean,
required: true required: true
} }
}, },
emits: ['toggleModal'], emits: ['toggleCard'],
data() { data() {
return { return {
@@ -49,7 +49,7 @@ export default defineComponent({
}, },
watch: { watch: {
updateModalOpen(val: boolean) { isUpdateCardOpen(val: boolean) {
this.$nextTick(() => { this.$nextTick(() => {
if (val) (this.$refs['confirm-btn'] as HTMLElement).focus(); if (val) (this.$refs['confirm-btn'] as HTMLElement).focus();
}); });
@@ -65,29 +65,33 @@ export default defineComponent({
}, },
methods: { methods: {
toggleModal(value: boolean) { toggleCard(value: boolean) {
this.$emit('toggleModal', value); this.$emit('toggleCard', value);
} }
} }
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/variables';
::v-deep(h1) { ::v-deep(h1) {
text-align: center; text-align: center;
color: $accentCol;
} }
::v-deep(h2) { ::v-deep(h2) {
padding: 0.25em 0; padding: 0.25em 0;
border-bottom: 1px solid #aaa;
} }
::v-deep(ul) { ::v-deep(ul) {
list-style: inside; list-style: initial;
padding: 0.5em; padding: 1em;
line-height: 1.5em; line-height: 1.5em;
} }
.modal-content { .content {
display: grid; display: grid;
grid-template-rows: auto 1fr auto; grid-template-rows: auto 1fr auto;
gap: 0.5em; gap: 0.5em;
@@ -95,6 +99,7 @@ export default defineComponent({
min-height: 700px; min-height: 700px;
overflow: auto; overflow: auto;
text-align: justify; text-align: justify;
max-width: 700px;
} }
.no-features { .no-features {
@@ -1,11 +1,11 @@
<template> <template>
<transition name="modal-anim" tag="div"> <transition name="modal-anim" tag="div">
<div class="modal" v-if="isOpen"> <div class="card" v-if="isOpen">
<div class="modal-background" @click="toggleModal(false)"></div> <div class="card-background" @click="toggleCard(false)"></div>
<div class="modal-wrapper" ref="wrapper" tabindex="0"> <div class="card-body" ref="wrapper" tabindex="0">
<slot></slot> <slot></slot>
</div> </div>
<div class="tab-exit" ref="exit" tabindex="0" @focus="toggleModal(false)"></div> <div class="tab-exit" ref="exit" tabindex="0" @focus="toggleCard(false)"></div>
</div> </div>
</transition> </transition>
</template> </template>
@@ -15,7 +15,7 @@ import { defineComponent } from 'vue';
import { useMainStore } from '../../store/mainStore'; import { useMainStore } from '../../store/mainStore';
export default defineComponent({ export default defineComponent({
emits: ['toggleModal'], emits: ['toggleCard'],
props: { props: {
isOpen: Boolean isOpen: Boolean
@@ -36,8 +36,8 @@ export default defineComponent({
}, },
methods: { methods: {
toggleModal(value: boolean) { toggleCard(value: boolean) {
this.$emit('toggleModal', value); this.$emit('toggleCard', value);
} }
} }
}); });
@@ -46,7 +46,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/responsive.scss'; @import '../../styles/responsive.scss';
.modal { .card {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@@ -56,7 +56,7 @@ export default defineComponent({
z-index: 200; z-index: 200;
} }
.modal-background { .card-background {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@@ -68,7 +68,7 @@ export default defineComponent({
background-color: rgba(0, 0, 0, 0.55); background-color: rgba(0, 0, 0, 0.55);
} }
.modal-wrapper { .card-body {
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
@@ -77,12 +77,11 @@ export default defineComponent({
overflow: auto; overflow: auto;
max-height: 95vh; max-height: 95vh;
box-shadow: 0 0 15px 10px #0e0e0e;
& > :slotted(div) { & > :slotted(div) {
background-color: #1a1a1a; background-color: #1a1a1a;
box-shadow: 0 0 15px 10px #0e0e0e;
width: 95vw; width: 95vw;
max-width: 850px;
} }
} }
</style> </style>
@@ -1,12 +1,7 @@
<template> <template>
<AnimatedModal <Card :isOpen="isCardOpen" @toggleCard="toggleCard" @keydown.esc="toggleCard(false)">
class="donation-modal" <div class="body">
:isOpen="isModalOpen" <div class="content">
@toggleModal="toggleModal"
@keydown.esc="toggleModal(false)"
>
<div class="modal_content">
<div class="modal_main">
<h1 v-html="$t('donations.header')"></h1> <h1 v-html="$t('donations.header')"></h1>
<div class="donators-slider" v-if="donatorList.length != 0"> <div class="donators-slider" v-if="donatorList.length != 0">
<span v-html="$t('donations.donator-title', { count: donatorList.length })"></span> <span v-html="$t('donations.donator-title', { count: donatorList.length })"></span>
@@ -61,9 +56,9 @@
</i> </i>
</div> </div>
<div class="modal_actions"> <div class="actions">
<a <a
class="modal-action a-button btn--image coffee" class="action a-button btn--image coffee"
href="https://buycoffee.to/spythere" href="https://buycoffee.to/spythere"
target="_blank" target="_blank"
ref="action" ref="action"
@@ -73,7 +68,7 @@
</a> </a>
<a <a
class="modal-action a-button btn--image paypal" class="action a-button btn--image paypal"
href="https://www.paypal.com/donate/?hosted_button_id=EDB3SKFAHXFTW" href="https://www.paypal.com/donate/?hosted_button_id=EDB3SKFAHXFTW"
target="_blank" target="_blank"
> >
@@ -81,30 +76,30 @@
{{ $t('donations.action-paypal') }} {{ $t('donations.action-paypal') }}
</a> </a>
<button class="modal-action btn--image exit" @click="toggleModal(false)"> <button class="action btn--image exit" @click="toggleCard(false)">
<img src="/images/icon-exit.svg" alt="dollar donation icon" /> <img src="/images/icon-exit.svg" alt="dollar donation icon" />
{{ $t('donations.action-exit') }} {{ $t('donations.action-exit') }}
</button> </button>
</div> </div>
</div> </div>
</AnimatedModal> </Card>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import AnimatedModal from './AnimatedModal.vue';
import { useApiStore } from '../../store/apiStore'; import { useApiStore } from '../../store/apiStore';
import Card from './Card.vue';
export default defineComponent({ export default defineComponent({
components: { AnimatedModal }, components: { Card },
props: { props: {
isModalOpen: Boolean isCardOpen: Boolean
}, },
emits: ['toggleModal'], emits: ['toggleCard'],
watch: { watch: {
isModalOpen(val: boolean) { isCardOpen(val: boolean) {
this.running = val; this.running = val;
this.lastUpdate = Date.now(); this.lastUpdate = Date.now();
@@ -138,8 +133,8 @@ export default defineComponent({
}, },
methods: { methods: {
toggleModal(value: boolean) { toggleCard(value: boolean) {
this.$emit('toggleModal', value); this.$emit('toggleCard', value);
}, },
runUpdate() { runUpdate() {
@@ -157,53 +152,53 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/responsive.scss'; @import '../../styles/responsive.scss';
.modal_content { .body {
display: grid; display: grid;
grid-template-rows: 1fr auto; grid-template-rows: 1fr auto;
gap: 1em; gap: 1em;
font-size: 1.1em; font-size: 1.1em;
& > div { max-width: 820px;
padding: 1em;
}
h1 {
font-size: 1.95em;
text-align: center;
}
p {
text-align: justify;
}
a.discord {
text-decoration: underline;
}
} }
.modal_main { .content {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
padding: 1em;
img {
max-height: 20px;
margin-right: 5px;
vertical-align: text-bottom;
}
} }
.modal_actions { img {
max-height: 20px;
margin-right: 5px;
vertical-align: text-bottom;
}
h1 {
font-size: 1.95em;
text-align: center;
}
p {
text-align: justify;
}
a.discord {
text-decoration: underline;
}
.actions {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 0.5em; gap: 0.5em;
padding: 1em;
form button { form button {
width: 100%; width: 100%;
} }
} }
.modal_actions > .modal-action { .actions > .action {
&.paypal { &.paypal {
$btnColor: #254069; $btnColor: #254069;
+4 -4
View File
@@ -122,7 +122,7 @@
<span v-if="station.onlineInfo?.dispatcherName"> <span v-if="station.onlineInfo?.dispatcherName">
<b <b
v-if="apiStore.donatorsData.includes(station.onlineInfo.dispatcherName)" v-if="apiStore.donatorsData.includes(station.onlineInfo.dispatcherName)"
@click.stop="openDonationModal" @click.stop="openDonationCard"
data-tooltip-type="DonatorTooltip" data-tooltip-type="DonatorTooltip"
:data-tooltip-content="$t('donations.dispatcher-message')" :data-tooltip-content="$t('donations.dispatcher-message')"
> >
@@ -329,7 +329,7 @@ import { ActiveSorter, HeadIdsType, headIconsIds, headIds } from './typings';
import { filterStations, sortStations } from './utils'; import { filterStations, sortStations } from './utils';
export default defineComponent({ export default defineComponent({
emits: ['toggleDonationModal'], emits: ['toggleDonationCard'],
components: { Loading, StationStatusBadge }, components: { Loading, StationStatusBadge },
mixins: [styleMixin, dateMixin], mixins: [styleMixin, dateMixin],
@@ -384,8 +384,8 @@ export default defineComponent({
}); });
}, },
openDonationModal(e: Event) { openDonationCard(e: Event) {
this.$emit('toggleDonationModal', true); this.$emit('toggleDonationCard', true);
this.mainStore.modalLastClickedTarget = e.target; this.mainStore.modalLastClickedTarget = e.target;
this.tooltipStore.hide(); this.tooltipStore.hide();
}, },
-14
View File
@@ -40,20 +40,6 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/responsive.scss'; @import '../../styles/responsive.scss';
@import '../../styles/card.scss';
.top-info-bar-anim {
&-enter-active,
&-leave-active {
transition: all 150ms ease-in-out;
}
&-enter-from,
&-leave-to {
transform: translate(-50%, -50%) scale(0.8);
opacity: 0;
}
}
.train-modal { .train-modal {
position: fixed; position: fixed;
+9 -9
View File
@@ -11,16 +11,16 @@
<button <button
class="btn-donation btn--image" class="btn-donation btn--image"
ref="btn" ref="btn"
@click="isDonationModalOpen = true" @click="isDonationCardOpen = true"
@focus="isDonationModalOpen = false" @focus="isDonationCardOpen = false"
> >
<img src="/images/icon-dollar.svg" alt="dollar donation icon" /> <img src="/images/icon-dollar.svg" alt="dollar donation icon" />
<span>{{ $t('donations.button-title') }}</span> <span>{{ $t('donations.button-title') }}</span>
</button> </button>
</div> </div>
<DonationModal :isModalOpen="isDonationModalOpen" @toggleModal="toggleDonationModal" /> <DonationCard :is-card-open="isDonationCardOpen" @toggle-card="toggleDonationCard" />
<StationTable @toggleDonationModal="toggleDonationModal" /> <StationTable @toggle-donation-card="toggleDonationCard" />
<StationStats /> <StationStats />
</div> </div>
</section> </section>
@@ -31,7 +31,7 @@ import { defineComponent } from 'vue';
import StationTable from '../components/StationsView/StationTable.vue'; import StationTable from '../components/StationsView/StationTable.vue';
import StationFilterCard from '../components/StationsView/StationFilterCard.vue'; import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
import { useMainStore } from '../store/mainStore'; import { useMainStore } from '../store/mainStore';
import DonationModal from '../components/Global/DonationModal.vue'; import DonationCard from '../components/Global/DonationCard.vue';
import StationStats from '../components/StationsView/StationStats.vue'; import StationStats from '../components/StationsView/StationStats.vue';
import { initFilters, setupFilters } from '../managers/stationFilterManager'; import { initFilters, setupFilters } from '../managers/stationFilterManager';
import { reactive } from 'vue'; import { reactive } from 'vue';
@@ -46,12 +46,12 @@ export default defineComponent({
StationTable, StationTable,
StationFilterCard, StationFilterCard,
StationStats, StationStats,
DonationModal DonationCard
}, },
data: () => ({ data: () => ({
filterCardOpen: false, filterCardOpen: false,
isDonationModalOpen: false, isDonationCardOpen: false,
mainStore: useMainStore() mainStore: useMainStore()
}), }),
@@ -69,8 +69,8 @@ export default defineComponent({
}, },
methods: { methods: {
toggleDonationModal(value: boolean) { toggleDonationCard(value: boolean) {
this.isDonationModalOpen = value; this.isDonationCardOpen = value;
} }
} }
}); });