feat: enhance event modal for desktop and mobile views
This commit is contained in:
@@ -683,6 +683,25 @@ export default function CalendarPage() {
|
||||
|
||||
{renderView()}
|
||||
|
||||
{/* Desktop event panel */}
|
||||
{!isMobile && showEventModal && (
|
||||
<div className="w-[400px] border-l border-border flex-shrink-0 overflow-hidden">
|
||||
<EventModal
|
||||
event={editEvent}
|
||||
calendars={calendars}
|
||||
defaultDate={defaultModalDate}
|
||||
defaultEndDate={defaultModalEndDate}
|
||||
onSave={handleSaveEvent}
|
||||
onDelete={handleDeleteEvent}
|
||||
onDuplicate={handleDuplicateEvent}
|
||||
onRsvp={handleRsvp}
|
||||
onClose={() => { setShowEventModal(false); setEditEvent(null); }}
|
||||
currentUserEmails={currentUserEmails}
|
||||
isMobile={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Floating Create Event Button (mobile) */}
|
||||
{isMobile && (
|
||||
<Button
|
||||
@@ -718,7 +737,7 @@ export default function CalendarPage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{showEventModal && (
|
||||
{showEventModal && isMobile && (
|
||||
<EventModal
|
||||
event={editEvent}
|
||||
calendars={calendars}
|
||||
@@ -730,6 +749,7 @@ export default function CalendarPage() {
|
||||
onRsvp={handleRsvp}
|
||||
onClose={() => { setShowEventModal(false); setEditEvent(null); }}
|
||||
currentUserEmails={currentUserEmails}
|
||||
isMobile={true}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ interface EventModalProps {
|
||||
onRsvp?: (eventId: string, participantId: string, status: CalendarParticipant['participationStatus']) => void;
|
||||
onClose: () => void;
|
||||
currentUserEmails?: string[];
|
||||
isMobile?: boolean;
|
||||
}
|
||||
|
||||
function formatDateInput(d: Date): string {
|
||||
@@ -68,6 +69,7 @@ export function EventModal({
|
||||
onRsvp,
|
||||
onClose,
|
||||
currentUserEmails = [],
|
||||
isMobile = false,
|
||||
}: EventModalProps) {
|
||||
const t = useTranslations("calendar");
|
||||
const isEdit = !!event;
|
||||
@@ -374,16 +376,15 @@ export function EventModal({
|
||||
const participants = getParticipantList(event);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div className="absolute inset-0 bg-black/50 backdrop-blur-[1px]" onClick={onClose} aria-hidden="true" />
|
||||
<div ref={modalRef} role="dialog" aria-modal="true" aria-label={event.title || t("events.no_title")} className="relative bg-background border border-border rounded-lg shadow-xl w-full max-w-lg mx-4 max-h-[90vh] overflow-y-auto animate-in zoom-in-95 duration-200">
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-border">
|
||||
<div ref={modalRef} role="dialog" aria-modal={isMobile || undefined} aria-label={event.title || t("events.no_title")} className={isMobile ? "fixed inset-0 z-50 flex flex-col bg-background" : "flex flex-col h-full bg-background"}>
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-border flex-shrink-0">
|
||||
<h2 className="text-lg font-semibold truncate">{event.title || t("events.no_title")}</h2>
|
||||
<button onClick={onClose} className="p-1.5 rounded-md hover:bg-muted transition-colors duration-150 text-muted-foreground hover:text-foreground" aria-label={t("form.cancel")}>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<div className="px-6 py-4 space-y-3">
|
||||
<div className="flex items-start gap-3 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-950/50 px-4 py-3">
|
||||
<CalendarDays className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" />
|
||||
@@ -431,8 +432,9 @@ export function EventModal({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-6 py-4 border-t border-border">
|
||||
<div className="px-6 py-4 border-t border-border flex-shrink-0">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-medium">{t("participants.rsvp_label")}</span>
|
||||
<div className="flex gap-2">
|
||||
@@ -472,16 +474,13 @@ export function EventModal({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div className="absolute inset-0 bg-black/50 backdrop-blur-[1px]" onClick={onClose} aria-hidden="true" />
|
||||
<div ref={modalRef} role="dialog" aria-modal="true" aria-label={isEdit ? t("events.edit") : t("events.create")} className="relative bg-background border border-border rounded-lg shadow-xl w-full max-w-lg mx-4 max-h-[90vh] overflow-y-auto animate-in zoom-in-95 duration-200">
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-border">
|
||||
<div ref={modalRef} role="dialog" aria-modal={isMobile || undefined} aria-label={isEdit ? t("events.edit") : t("events.create")} className={isMobile ? "fixed inset-0 z-50 flex flex-col bg-background" : "flex flex-col h-full bg-background"}>
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-border flex-shrink-0">
|
||||
<h2 className="text-lg font-semibold">
|
||||
{isEdit ? t("events.edit") : t("events.create")}
|
||||
</h2>
|
||||
@@ -490,6 +489,7 @@ export function EventModal({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<div className="px-6 py-4 space-y-4">
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-1 block">{t("form.title")}</label>
|
||||
@@ -665,8 +665,9 @@ export function EventModal({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between px-6 py-4 border-t border-border">
|
||||
<div className="flex items-center justify-between px-6 py-4 border-t border-border flex-shrink-0">
|
||||
<div className="flex items-center gap-1">
|
||||
{isEdit && onDelete && (
|
||||
showDeleteConfirm ? (
|
||||
@@ -727,7 +728,6 @@ export function EventModal({
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user