Booking flow: required terms and privacy checkbox with i18n

Also includes admin, dashboard, and API updates; PWA icon assets; and
assorted layout and utility changes on dev.
This commit is contained in:
Michilis
2026-04-27 03:21:15 +00:00
parent f8ebc3760d
commit 3dfb1689ad
35 changed files with 575 additions and 106 deletions
+17 -10
View File
@@ -14,6 +14,7 @@ import { PlusIcon, PencilIcon, TrashIcon, EyeIcon, PhotoIcon, DocumentDuplicateI
import { StarIcon as StarIconSolid } from '@heroicons/react/24/solid';
import toast from 'react-hot-toast';
import clsx from 'clsx';
import { parseDate, EVENT_TIMEZONE } from '@/lib/utils';
export default function AdminEventsPage() {
const router = useRouter();
@@ -123,13 +124,19 @@ export default function AdminEventsPage() {
};
const isoToLocalDatetime = (isoString: string): string => {
const date = new Date(isoString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day}T${hours}:${minutes}`;
const date = parseDate(isoString);
const parts = new Intl.DateTimeFormat('en-US', {
timeZone: EVENT_TIMEZONE,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
}).formatToParts(date);
const get = (type: string) => parts.find(p => p.type === type)!.value;
const h = get('hour') === '24' ? '00' : get('hour');
return `${get('year')}-${get('month')}-${get('day')}T${h}:${get('minute')}`;
};
const handleEdit = (event: Event) => {
@@ -167,8 +174,8 @@ export default function AdminEventsPage() {
title: formData.title, titleEs: formData.titleEs || undefined,
description: formData.description, descriptionEs: formData.descriptionEs || undefined,
shortDescription: formData.shortDescription || undefined, shortDescriptionEs: formData.shortDescriptionEs || undefined,
startDatetime: new Date(formData.startDatetime).toISOString(),
endDatetime: formData.endDatetime ? new Date(formData.endDatetime).toISOString() : undefined,
startDatetime: formData.startDatetime,
endDatetime: formData.endDatetime || undefined,
location: formData.location, locationUrl: formData.locationUrl || undefined,
price: formData.price, currency: formData.currency, capacity: formData.capacity,
status: formData.status, bannerUrl: formData.bannerUrl || undefined,
@@ -214,7 +221,7 @@ export default function AdminEventsPage() {
};
const formatDate = (dateStr: string) => {
return new Date(dateStr).toLocaleDateString(locale === 'es' ? 'es-ES' : 'en-US', {
return parseDate(dateStr).toLocaleDateString(locale === 'es' ? 'es-ES' : 'en-US', {
month: 'short', day: 'numeric', year: 'numeric', timeZone: 'America/Asuncion',
});
};