mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-02-24 02:46:11 -05:00
Enhance event creation with locale-aware date formatting and improved translations
This commit is contained in:
@@ -8,7 +8,7 @@ import {api} from 'web/lib/api'
|
||||
import {APIError} from "common/api/utils";
|
||||
import clsx from "clsx";
|
||||
import {Col} from "web/components/layout/col";
|
||||
import {useT} from 'web/lib/locale';
|
||||
import {useLocale, useT} from 'web/lib/locale';
|
||||
|
||||
import {Event} from 'web/hooks/use-events'
|
||||
|
||||
@@ -22,6 +22,7 @@ export function CreateEventModal(props: {
|
||||
const {open, setOpen, onClose, onSuccess, event} = props
|
||||
const isEditing = !!event
|
||||
const t = useT()
|
||||
const {locale} = useLocale()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
@@ -76,8 +77,8 @@ export function CreateEventModal(props: {
|
||||
title: formData.title,
|
||||
description: formData.description || undefined,
|
||||
locationType: formData.locationType,
|
||||
locationAddress: formData.locationAddress || undefined,
|
||||
locationUrl: formData.locationUrl || undefined,
|
||||
locationAddress: formData.locationType === 'in_person' && formData.locationAddress || undefined,
|
||||
locationUrl: formData.locationType === 'online' && formData.locationUrl || undefined,
|
||||
eventStartTime: formData.eventStartTime!.toISOString(),
|
||||
eventEndTime: formData.eventEndTime
|
||||
? formData.eventEndTime.toISOString()
|
||||
@@ -91,8 +92,8 @@ export function CreateEventModal(props: {
|
||||
title: formData.title,
|
||||
description: formData.description || undefined,
|
||||
locationType: formData.locationType,
|
||||
locationAddress: formData.locationAddress || undefined,
|
||||
locationUrl: formData.locationUrl || undefined,
|
||||
locationAddress: formData.locationType === 'in_person' && formData.locationAddress || undefined,
|
||||
locationUrl: formData.locationType === 'online' && formData.locationUrl || undefined,
|
||||
eventStartTime: formData.eventStartTime!.toISOString(),
|
||||
eventEndTime: formData.eventEndTime
|
||||
? formData.eventEndTime.toISOString()
|
||||
@@ -136,6 +137,9 @@ export function CreateEventModal(props: {
|
||||
setFormData((prev) => ({...prev, [name]: value}))
|
||||
}
|
||||
|
||||
const dateFormat = locale === 'en' ? "MMM d, yyyy h:mm aa" : "dd MMM yyyy, HH:mm"
|
||||
const timeFormat = "HH:mm"
|
||||
|
||||
return (
|
||||
<Modal open={open} setOpen={setOpen} onClose={onClose} size="lg">
|
||||
<Col className={clsx("", MODAL_CLASS)}>
|
||||
@@ -231,10 +235,11 @@ export function CreateEventModal(props: {
|
||||
<div className="grid grid-cols-1 xs:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="mb-1 block text-sm font-medium">
|
||||
{t('events.start_time', 'Start Time')} *
|
||||
{t('events.start_time', 'Start')} *
|
||||
</label>
|
||||
<DatePicker
|
||||
selected={formData.eventStartTime}
|
||||
locale={locale}
|
||||
onChange={(date: Date | null) => {
|
||||
if (!date) return
|
||||
setFormData((prev) => {
|
||||
@@ -245,21 +250,22 @@ export function CreateEventModal(props: {
|
||||
})
|
||||
}}
|
||||
showTimeSelect
|
||||
timeFormat="HH:mm"
|
||||
timeFormat={timeFormat}
|
||||
timeIntervals={15}
|
||||
dateFormat="MMM d, yyyy h:mm aa"
|
||||
dateFormat={dateFormat}
|
||||
minDate={new Date()}
|
||||
required
|
||||
placeholderText="Select date and time"
|
||||
placeholderText={t('events.select_start_datetime', 'Select date and time')}
|
||||
className="bg-canvas-50 border-canvas-300 focus:border-primary-500 focus:ring-primary-500 w-full rounded-md border px-3 py-2"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="mb-1 block text-sm font-medium">
|
||||
{t('events.end_time', 'End Time')}
|
||||
{t('events.end_time', 'End')}
|
||||
</label>
|
||||
<DatePicker
|
||||
selected={formData.eventEndTime}
|
||||
locale={locale}
|
||||
onChange={(date: Date | null) => {
|
||||
setFormData((prev) => {
|
||||
const startTime = prev.eventStartTime
|
||||
@@ -271,11 +277,11 @@ export function CreateEventModal(props: {
|
||||
})
|
||||
}}
|
||||
showTimeSelect
|
||||
timeFormat="HH:mm"
|
||||
timeFormat={timeFormat}
|
||||
timeIntervals={15}
|
||||
dateFormat="MMM d, yyyy h:mm aa"
|
||||
dateFormat={dateFormat}
|
||||
minDate={formData.eventStartTime || new Date()}
|
||||
placeholderText="Select end time (optional)"
|
||||
placeholderText={t('events.select_end_datetime', 'Select end time (optional)')}
|
||||
className="bg-canvas-50 border-canvas-300 focus:border-primary-500 focus:ring-primary-500 w-full rounded-md border px-3 py-2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,94 @@ import {getLocale} from "web/lib/locale-cookie";
|
||||
dayjs.extend(relativeTime)
|
||||
dayjs.extend(localizedFormat)
|
||||
|
||||
export const DATEPICKER_LOCALE_IMPORTS: Record<string, () => Promise<any>> = {
|
||||
af: () => import('date-fns/locale/af'),
|
||||
ar: () => import('date-fns/locale/ar'),
|
||||
'ar-dz': () => import('date-fns/locale/ar-DZ'),
|
||||
'ar-ma': () => import('date-fns/locale/ar-MA'),
|
||||
'ar-sa': () => import('date-fns/locale/ar-SA'),
|
||||
'ar-tn': () => import('date-fns/locale/ar-TN'),
|
||||
az: () => import('date-fns/locale/az'),
|
||||
be: () => import('date-fns/locale/be'),
|
||||
bg: () => import('date-fns/locale/bg'),
|
||||
bn: () => import('date-fns/locale/bn'),
|
||||
bs: () => import('date-fns/locale/bs'),
|
||||
ca: () => import('date-fns/locale/ca'),
|
||||
cs: () => import('date-fns/locale/cs'),
|
||||
cy: () => import('date-fns/locale/cy'),
|
||||
da: () => import('date-fns/locale/da'),
|
||||
de: () => import('date-fns/locale/de'),
|
||||
'de-at': () => import('date-fns/locale/de-AT'),
|
||||
el: () => import('date-fns/locale/el'),
|
||||
en: () => import('date-fns/locale/en-US'),
|
||||
'en-au': () => import('date-fns/locale/en-AU'),
|
||||
'en-ca': () => import('date-fns/locale/en-CA'),
|
||||
'en-gb': () => import('date-fns/locale/en-GB'),
|
||||
'en-ie': () => import('date-fns/locale/en-IE'),
|
||||
'en-in': () => import('date-fns/locale/en-IN'),
|
||||
'en-nz': () => import('date-fns/locale/en-NZ'),
|
||||
eo: () => import('date-fns/locale/eo'),
|
||||
es: () => import('date-fns/locale/es'),
|
||||
et: () => import('date-fns/locale/et'),
|
||||
eu: () => import('date-fns/locale/eu'),
|
||||
fi: () => import('date-fns/locale/fi'),
|
||||
fr: () => import('date-fns/locale/fr'),
|
||||
'fr-ca': () => import('date-fns/locale/fr-CA'),
|
||||
'fr-ch': () => import('date-fns/locale/fr-CH'),
|
||||
fy: () => import('date-fns/locale/fy'),
|
||||
gd: () => import('date-fns/locale/gd'),
|
||||
gl: () => import('date-fns/locale/gl'),
|
||||
gu: () => import('date-fns/locale/gu'),
|
||||
he: () => import('date-fns/locale/he'),
|
||||
hi: () => import('date-fns/locale/hi'),
|
||||
hr: () => import('date-fns/locale/hr'),
|
||||
ht: () => import('date-fns/locale/ht'),
|
||||
hu: () => import('date-fns/locale/hu'),
|
||||
id: () => import('date-fns/locale/id'),
|
||||
is: () => import('date-fns/locale/is'),
|
||||
it: () => import('date-fns/locale/it'),
|
||||
'it-ch': () => import('date-fns/locale/it-CH'),
|
||||
ja: () => import('date-fns/locale/ja'),
|
||||
ka: () => import('date-fns/locale/ka'),
|
||||
kk: () => import('date-fns/locale/kk'),
|
||||
km: () => import('date-fns/locale/km'),
|
||||
kn: () => import('date-fns/locale/kn'),
|
||||
ko: () => import('date-fns/locale/ko'),
|
||||
lb: () => import('date-fns/locale/lb'),
|
||||
lt: () => import('date-fns/locale/lt'),
|
||||
lv: () => import('date-fns/locale/lv'),
|
||||
mk: () => import('date-fns/locale/mk'),
|
||||
mn: () => import('date-fns/locale/mn'),
|
||||
ms: () => import('date-fns/locale/ms'),
|
||||
mt: () => import('date-fns/locale/mt'),
|
||||
nb: () => import('date-fns/locale/nb'),
|
||||
nl: () => import('date-fns/locale/nl'),
|
||||
'nl-be': () => import('date-fns/locale/nl-BE'),
|
||||
nn: () => import('date-fns/locale/nn'),
|
||||
pl: () => import('date-fns/locale/pl'),
|
||||
pt: () => import('date-fns/locale/pt'),
|
||||
'pt-br': () => import('date-fns/locale/pt-BR'),
|
||||
ro: () => import('date-fns/locale/ro'),
|
||||
ru: () => import('date-fns/locale/ru'),
|
||||
sk: () => import('date-fns/locale/sk'),
|
||||
sl: () => import('date-fns/locale/sl'),
|
||||
sq: () => import('date-fns/locale/sq'),
|
||||
sr: () => import('date-fns/locale/sr'),
|
||||
sv: () => import('date-fns/locale/sv'),
|
||||
ta: () => import('date-fns/locale/ta'),
|
||||
te: () => import('date-fns/locale/te'),
|
||||
th: () => import('date-fns/locale/th'),
|
||||
tr: () => import('date-fns/locale/tr'),
|
||||
uk: () => import('date-fns/locale/uk'),
|
||||
uz: () => import('date-fns/locale/uz'),
|
||||
vi: () => import('date-fns/locale/vi'),
|
||||
zh: () => import('date-fns/locale/zh-CN'),
|
||||
'zh-cn': () => import('date-fns/locale/zh-CN'),
|
||||
'zh-hk': () => import('date-fns/locale/zh-HK'),
|
||||
'zh-tw': () => import('date-fns/locale/zh-TW'),
|
||||
zh_tw: () => import('date-fns/locale/zh-TW'),
|
||||
}
|
||||
|
||||
export const DAYJS_LOCALE_IMPORTS: Record<string, () => Promise<unknown>> = {
|
||||
af: () => import('dayjs/locale/af'),
|
||||
am: () => import('dayjs/locale/am'),
|
||||
@@ -154,5 +242,6 @@ export const DAYJS_LOCALE_IMPORTS: Record<string, () => Promise<unknown>> = {
|
||||
}
|
||||
|
||||
DAYJS_LOCALE_IMPORTS[getLocale()]?.()
|
||||
DATEPICKER_LOCALE_IMPORTS[getLocale()]?.()
|
||||
|
||||
export default dayjs
|
||||
|
||||
@@ -556,6 +556,8 @@
|
||||
"events.location_url": "Orts-URL",
|
||||
"events.start_time": "Startzeit",
|
||||
"events.end_time": "Endzeit",
|
||||
"events.select_start_datetime": "Datum und Uhrzeit auswählen",
|
||||
"events.select_end_datetime": "Endzeit auswählen (optional)",
|
||||
"events.max_participants": "Max. Teilnehmer (optional)",
|
||||
"events.leave_empty": "Leer lassen für unbegrenzt",
|
||||
"events.in_person": "In Person",
|
||||
|
||||
@@ -554,8 +554,10 @@
|
||||
"events.location_type": "Type de lieu",
|
||||
"events.location_address": "Adresse du lieu",
|
||||
"events.location_url": "URL du lieu",
|
||||
"events.start_time": "Heure de début",
|
||||
"events.end_time": "Heure de fin",
|
||||
"events.start_time": "Début",
|
||||
"events.end_time": "Fin",
|
||||
"events.select_start_datetime": "Sélectionner la date",
|
||||
"events.select_end_datetime": "Sélectionner (optionnel)",
|
||||
"events.max_participants": "Participants max (optionnel)",
|
||||
"events.leave_empty": "Laisser vide pour illimité",
|
||||
"events.in_person": "En personne",
|
||||
|
||||
@@ -24,7 +24,7 @@ import {I18nContext} from "web/lib/locale"
|
||||
import {HiddenProfilesProvider} from 'web/hooks/use-hidden-profiles'
|
||||
import {updateStatusBar} from "web/hooks/use-theme"
|
||||
import {useFontPreferenceManager} from "web/hooks/use-font-preference"
|
||||
import {DAYJS_LOCALE_IMPORTS} from "web/lib/dayjs";
|
||||
import {DATEPICKER_LOCALE_IMPORTS, DAYJS_LOCALE_IMPORTS} from "web/lib/dayjs";
|
||||
import 'web/lib/dayjs'
|
||||
|
||||
if (Capacitor.isNativePlatform()) {
|
||||
@@ -104,6 +104,7 @@ function MyApp(props: AppProps<PageProps>) {
|
||||
setLocaleState(newLocale)
|
||||
resetCachedLocale()
|
||||
DAYJS_LOCALE_IMPORTS[newLocale]?.()
|
||||
DATEPICKER_LOCALE_IMPORTS[newLocale]?.()
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user