diff --git a/ems-client/app/dashboard/admin/events/create/page.tsx b/ems-client/app/dashboard/admin/events/create/page.tsx index 59f542e..16217df 100644 --- a/ems-client/app/dashboard/admin/events/create/page.tsx +++ b/ems-client/app/dashboard/admin/events/create/page.tsx @@ -1,26 +1,22 @@ 'use client'; import { useAuth } from "@/lib/auth-context"; -import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { - ArrowLeft, - Save, - Eye, - Calendar, - MapPin, - Clock, - AlertCircle, - CheckCircle -} from "lucide-react"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { useLogger } from "@/lib/logger/LoggerProvider"; import { eventAPI } from "@/lib/api/event.api"; import { CreateEventRequest, VenueResponse } from "@/lib/api/types/event.types"; import { withAdminAuth } from "@/components/hoc/withAuth"; +import { PageHeader } from "@/components/admin/events/PageHeader"; +import { InfoBanner } from "@/components/admin/events/InfoBanner"; +import { ErrorAlert } from "@/components/admin/events/ErrorAlert"; +import { BasicInfoSection } from "@/components/admin/events/BasicInfoSection"; +import { VenueSection } from "@/components/admin/events/VenueSection"; +import { DateTimeSection } from "@/components/admin/events/DateTimeSection"; +import { ActionButtons } from "@/components/admin/events/ActionButtons"; +import { SuccessState } from "@/components/admin/events/SuccessState"; +import { LoadingState } from "@/components/admin/events/LoadingState"; const LOGGER_COMPONENT_NAME = 'AdminCreateEventPage'; @@ -42,12 +38,34 @@ function AdminCreateEventPage() { bookingEndDate: '' }); + // Date state for DateTimeSelector (uses Date objects) + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date(Date.now() + 24 * 60 * 60 * 1000)); // Tomorrow + const [venues, setVenues] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const [errors, setErrors] = useState>({}); const [isLoadingVenues, setIsLoadingVenues] = useState(true); const [showSuccess, setShowSuccess] = useState(false); + // Sync date state with form data + useEffect(() => { + const formatDateForAPI = (date: Date) => { + 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}`; + }; + + setFormData(prev => ({ + ...prev, + bookingStartDate: formatDateForAPI(startDate), + bookingEndDate: formatDateForAPI(endDate) + })); + }, [startDate, endDate]); + useEffect(() => { logger.debug(LOGGER_COMPONENT_NAME, 'Auth state changed', { isAuthenticated, isLoading, user }); @@ -108,17 +126,13 @@ function AdminCreateEventPage() { newErrors.bookingEndDate = 'End date is required'; } - if (formData.bookingStartDate && formData.bookingEndDate) { - const startDate = new Date(formData.bookingStartDate); - const endDate = new Date(formData.bookingEndDate); - - if (startDate >= endDate) { - newErrors.bookingEndDate = 'End date must be after start date'; - } + // Validate date range using Date objects + if (startDate >= endDate) { + newErrors.bookingEndDate = 'End date must be after start date'; + } - if (startDate < new Date()) { - newErrors.bookingStartDate = 'Start date cannot be in the past'; - } + if (startDate < new Date()) { + newErrors.bookingStartDate = 'Start date cannot be in the past'; } setErrors(newErrors); @@ -147,14 +161,14 @@ function AdminCreateEventPage() { try { // Create event - backend auto-publishes for admin users const createResponse = await eventAPI.createEventAsAdmin(formData); - + if (!createResponse.success) { throw new Error('Failed to create event'); } - logger.info(LOGGER_COMPONENT_NAME, 'Event created and auto-published successfully', { + logger.info(LOGGER_COMPONENT_NAME, 'Event created and auto-published successfully', { eventId: createResponse.data.id, - status: createResponse.data.status + status: createResponse.data.status }); // Show success message @@ -166,8 +180,8 @@ function AdminCreateEventPage() { }, 2000); } catch (error) { logger.error(LOGGER_COMPONENT_NAME, 'Failed to create event', error as Error); - setErrors({ - general: error instanceof Error ? error.message : 'Failed to create event. Please try again.' + setErrors({ + general: error instanceof Error ? error.message : 'Failed to create event. Please try again.' }); } finally { setIsSubmitting(false); @@ -180,14 +194,7 @@ function AdminCreateEventPage() { }; if (isLoading) { - return ( -
-
-
-

Loading...

-
-
- ); + return ; } if (!isAuthenticated || user?.role !== 'ADMIN') { @@ -196,69 +203,15 @@ function AdminCreateEventPage() { // Success state if (showSuccess) { - return ( -
- - - -

- Event Created & Published! -

-

- The event has been successfully created and published. It's now visible to all users. -

-

- Redirecting to events list... -

-
-
-
- ); + return ; } return (
- {/* Header */} -
-
-
-
- -

- Create New Event (Admin) -

-
-
-
-
- - {/* Main Content */} + +
- {/* Info Banner */} - - -
- -
-

- Admin Event Creation -

-

- Events created by admins are automatically published and will be immediately visible to all users. - They bypass the approval workflow that speaker-created events go through. -

-
-
-
-
+ @@ -270,215 +223,38 @@ function AdminCreateEventPage() { - {errors.general && ( -
-
- -

{errors.general}

-
-
- )} + {errors.general && }
- {/* Basic Information */} -
-

- - Basic Information -

- -
-
- - handleInputChange('name', e.target.value)} - placeholder="Enter event name" - className={errors.name ? 'border-red-500' : ''} - /> - {errors.name && ( -

{errors.name}

- )} -
- -
- - handleInputChange('category', e.target.value)} - placeholder="e.g., Technology, Business, Education" - className={errors.category ? 'border-red-500' : ''} - /> - {errors.category && ( -

{errors.category}

- )} -
-
- -
- -