Skip to content

Commit 569d94b

Browse files
committed
move TimezonMismatchModal to ui package
1 parent ca94021 commit 569d94b

File tree

3 files changed

+120
-71
lines changed

3 files changed

+120
-71
lines changed
Lines changed: 9 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,23 @@
11
<script setup lang="ts">
2-
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
3-
import DialogModal from '@/packages/ui/src/DialogModal.vue';
4-
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
5-
import { onMounted, ref } from 'vue';
6-
import { getUserTimezone } from '@/packages/ui/src/utils/settings';
7-
import { getDayJsInstance } from '@/packages/ui/src/utils/time';
2+
import { ref } from 'vue';
83
import { useForm, usePage } from '@inertiajs/vue3';
94
import type { User } from '@/types/models';
10-
import { useSessionStorage } from '@vueuse/core';
5+
import TimezoneMismatchModal from '@/packages/ui/src/TimezoneMismatchModal.vue';
116
127
const show = defineModel('show', { default: false });
13-
const saving = defineModel('saving', { default: false });
14-
15-
const timezone = ref('');
16-
const userTimezone = ref('');
8+
const saving = ref(false);
179
1810
const page = usePage<{
1911
auth: {
2012
user: User;
2113
};
2214
}>();
2315
24-
const hideTimezoneMismatchModal = useSessionStorage<boolean>('hide-timezone-mismatch-modal', false);
25-
26-
onMounted(() => {
27-
timezone.value = Intl.DateTimeFormat().resolvedOptions().timeZone;
28-
userTimezone.value = getUserTimezone();
29-
30-
const now = getDayJsInstance()();
31-
32-
if (
33-
now.tz(timezone.value).format() !== now.tz(userTimezone.value).format() &&
34-
!hideTimezoneMismatchModal.value
35-
) {
36-
show.value = true;
37-
}
38-
});
39-
40-
function submit() {
16+
function handleUpdate(timezone: string) {
4117
saving.value = true;
4218
const form = useForm({
4319
_method: 'PUT',
44-
timezone: timezone.value,
20+
timezone: timezone,
4521
name: page.props.auth.user.name,
4622
email: page.props.auth.user.email,
4723
week_start: page.props.auth.user.week_start,
@@ -55,53 +31,15 @@ function submit() {
5531
show.value = false;
5632
location.reload();
5733
},
34+
onError: () => {
35+
saving.value = false;
36+
},
5837
});
5938
}
60-
61-
function cancel() {
62-
show.value = false;
63-
hideTimezoneMismatchModal.value = true;
64-
}
6539
</script>
6640

6741
<template>
68-
<DialogModal closeable :show="show" @close="show = false">
69-
<template #title>
70-
<div class="flex justify-center">
71-
<span> Timezone mismatch detected </span>
72-
</div>
73-
</template>
74-
<template #content>
75-
<div class="flex items-center space-x-4">
76-
<div class="col-span-6 sm:col-span-4 flex-1 space-y-2">
77-
<p>
78-
The timezone of your device does not match the timezone in your user
79-
settings. <br />
80-
<strong
81-
>We highly recommend that you update your timezone settings to your
82-
current timezone.</strong
83-
>
84-
</p>
85-
86-
<p>
87-
Want to change your timezone setting from
88-
<strong>{{ userTimezone }}</strong> to <strong>{{ timezone }}</strong
89-
>.
90-
</p>
91-
</div>
92-
</div>
93-
</template>
94-
<template #footer>
95-
<SecondaryButton @click="cancel"> Cancel</SecondaryButton>
96-
<PrimaryButton
97-
class="ms-3"
98-
:class="{ 'opacity-25': saving }"
99-
:disabled="saving"
100-
@click="submit()">
101-
Update timezone
102-
</PrimaryButton>
103-
</template>
104-
</DialogModal>
42+
<TimezoneMismatchModal v-model:show="show" :saving="saving" @update="handleUpdate" />
10543
</template>
10644

10745
<style scoped></style>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<script setup lang="ts">
2+
import SecondaryButton from './Buttons/SecondaryButton.vue';
3+
import DialogModal from './DialogModal.vue';
4+
import PrimaryButton from './Buttons/PrimaryButton.vue';
5+
import { onMounted, ref } from 'vue';
6+
import { getUserTimezone } from './utils/settings';
7+
import { getDayJsInstance } from './utils/time';
8+
import { useSessionStorage } from '@vueuse/core';
9+
10+
const show = defineModel('show', { default: false });
11+
12+
const emit = defineEmits<{
13+
update: [timezone: string];
14+
cancel: [];
15+
}>();
16+
17+
defineProps<{
18+
saving?: boolean;
19+
}>();
20+
21+
const timezone = ref('');
22+
const userTimezone = ref('');
23+
const shouldShow = ref(false);
24+
25+
const hideTimezoneMismatchModal = useSessionStorage<boolean>('hide-timezone-mismatch-modal', false);
26+
27+
/**
28+
* Check if timezone mismatch exists and should be shown
29+
*/
30+
function checkTimezoneMismatch(): boolean {
31+
timezone.value = Intl.DateTimeFormat().resolvedOptions().timeZone;
32+
userTimezone.value = getUserTimezone();
33+
34+
const now = getDayJsInstance()();
35+
36+
const hasMismatch =
37+
now.tz(timezone.value).format() !== now.tz(userTimezone.value).format() &&
38+
!hideTimezoneMismatchModal.value;
39+
40+
shouldShow.value = hasMismatch;
41+
return hasMismatch;
42+
}
43+
44+
onMounted(() => {
45+
checkTimezoneMismatch();
46+
if (shouldShow.value) {
47+
show.value = true;
48+
}
49+
});
50+
51+
function submit() {
52+
emit('update', timezone.value);
53+
}
54+
55+
function cancel() {
56+
show.value = false;
57+
hideTimezoneMismatchModal.value = true;
58+
emit('cancel');
59+
}
60+
61+
// Expose methods for parent component
62+
defineExpose({
63+
checkTimezoneMismatch,
64+
currentTimezone: timezone,
65+
userTimezone,
66+
});
67+
</script>
68+
69+
<template>
70+
<DialogModal closeable :show="show && shouldShow" @close="cancel">
71+
<template #title>
72+
<div class="flex justify-center">
73+
<span> Timezone mismatch detected </span>
74+
</div>
75+
</template>
76+
<template #content>
77+
<div class="flex items-center space-x-4">
78+
<div class="col-span-6 sm:col-span-4 flex-1 space-y-2">
79+
<p>
80+
The timezone of your device does not match the timezone in your user
81+
settings. <br />
82+
<strong
83+
>We highly recommend that you update your timezone settings to your
84+
current timezone.</strong
85+
>
86+
</p>
87+
88+
<p>
89+
Want to change your timezone setting from
90+
<strong>{{ userTimezone }}</strong> to <strong>{{ timezone }}</strong
91+
>.
92+
</p>
93+
</div>
94+
</div>
95+
</template>
96+
<template #footer>
97+
<SecondaryButton @click="cancel"> Cancel</SecondaryButton>
98+
<PrimaryButton
99+
class="ms-3"
100+
:class="{ 'opacity-25': saving }"
101+
:disabled="saving"
102+
@click="submit()">
103+
Update timezone
104+
</PrimaryButton>
105+
</template>
106+
</DialogModal>
107+
</template>
108+
109+
<style scoped></style>

resources/js/packages/ui/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import FullCalendarEventContent from './FullCalendar/FullCalendarEventContent.vu
3838
import FullCalendarDayHeader from './FullCalendar/FullCalendarDayHeader.vue';
3939
import TimeEntryCalendar from './FullCalendar/TimeEntryCalendar.vue';
4040
import DateRangePicker from './Input/DateRangePicker.vue';
41+
import TimezoneMismatchModal from './TimezoneMismatchModal.vue';
4142
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip/index';
4243
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './accordion/index';
4344
import { Popover, PopoverContent, PopoverTrigger, PopoverAnchor } from './popover/index';
@@ -74,6 +75,7 @@ export {
7475
FullCalendarDayHeader,
7576
TimeEntryCalendar,
7677
DateRangePicker,
78+
TimezoneMismatchModal,
7779
Tooltip,
7880
TooltipContent,
7981
TooltipProvider,

0 commit comments

Comments
 (0)