migrate datepickers to shadcn, Fixes #877, #807

This commit is contained in:
Gregor Vostrak
2026-02-05 15:02:01 +01:00
parent f82f5e780c
commit 66681066bc
14 changed files with 613 additions and 93 deletions

View File

@@ -12,6 +12,8 @@ import { api } from '@/packages/api/src';
import { Checkbox } from '@/packages/ui/src';
import DatePicker from '@/packages/ui/src/Input/DatePicker.vue';
import { useNotificationsStore } from '@/utils/notification';
import { getDayJsInstance } from '@/packages/ui/src/utils/time';
import { router } from '@inertiajs/vue3';
const show = defineModel('show', { default: false });
const saving = ref(false);
@@ -44,10 +46,14 @@ const report = ref({
const { handleApiRequestNotifications } = useNotificationsStore();
async function submit() {
const publicUntil = report.value.public_until
? getDayJsInstance()(report.value.public_until).utc().format()
: null;
await handleApiRequestNotifications(
() =>
createReportMutation.mutateAsync({
...report.value,
public_until: publicUntil,
properties: { ...props.properties },
}),
'Success',
@@ -60,6 +66,7 @@ async function submit() {
public_until: null,
};
show.value = false;
router.visit(route('reporting.shared'));
}
);
}
@@ -97,7 +104,7 @@ async function submit() {
<InputLabel for="public_until" value="Expires at" />
<div class="text-text-tertiary font-medium">(optional)</div>
</div>
<DatePicker id="public_until"></DatePicker>
<DatePicker v-model="report.public_until"></DatePicker>
</div>
</div>
</div>

View File

@@ -2,7 +2,7 @@
import TextInput from '../../../packages/ui/src/Input/TextInput.vue';
import SecondaryButton from '../../../packages/ui/src/Buttons/SecondaryButton.vue';
import DialogModal from '@/packages/ui/src/DialogModal.vue';
import { ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import PrimaryButton from '../../../packages/ui/src/Buttons/PrimaryButton.vue';
import InputLabel from '../../../packages/ui/src/Input/InputLabel.vue';
import type { UpdateReportBody } from '@/packages/api/src';
@@ -13,6 +13,7 @@ import { Checkbox } from '@/packages/ui/src';
import DatePicker from '@/packages/ui/src/Input/DatePicker.vue';
import { useNotificationsStore } from '@/utils/notification';
import type { Report } from '@/packages/api/src';
import { getDayJsInstance, getLocalizedDayJs } from '@/packages/ui/src/utils/time';
const show = defineModel('show', { default: false });
const saving = ref(false);
@@ -61,9 +62,21 @@ watch(
}
);
// Intermediate local variable for DatePicker (converts between UTC and localized)
const localPublicUntil = computed({
get: () => {
if (!report.value.public_until) return null;
return getLocalizedDayJs(report.value.public_until).format();
},
set: (value: string | null) => {
report.value.public_until = value ? getDayJsInstance()(value).utc().format() : null;
},
});
const { handleApiRequestNotifications } = useNotificationsStore();
async function submit() {
// public_until is already in UTC format from the computed setter
await handleApiRequestNotifications(
() => updateReportMutation.mutateAsync(report.value),
'Success',
@@ -111,7 +124,7 @@ async function submit() {
</div>
<div v-if="report.is_public" class="flex items-center space-x-4">
<InputLabel for="public_until" value="Expires at" />
<DatePicker id="public_until"></DatePicker>
<DatePicker v-model="localPublicUntil"></DatePicker>
</div>
</div>
</div>

View File

@@ -22,7 +22,7 @@ const forwardedProps = useForwardProps(delegatedProps);
'h-8 w-8 p-0 font-normal',
'[&[data-today]:not([data-selected])]:border-accent [&[data-today]:not([data-selected])]:border [&[data-today]:not([data-selected])]:text-accent-foreground',
// Selected
'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
'data-[selected]:bg-quaternary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-quaternary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
// Disabled
'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
// Unavailable