147 lines
5.1 KiB
JavaScript
147 lines
5.1 KiB
JavaScript
import React from "react";
|
|
import { base44 } from "@/api/base44Client";
|
|
import { useMutation, useQueryClient, useQuery } from "@tanstack/react-query";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { createPageUrl } from "@/utils";
|
|
import EventFormWizard from "@/components/events/EventFormWizard";
|
|
import { useToast } from "@/components/ui/use-toast";
|
|
import { Button } from "@/components/ui/button";
|
|
import { X, AlertTriangle } from "lucide-react";
|
|
import { detectAllConflicts, ConflictAlert } from "@/components/scheduling/ConflictDetection";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
|
|
export default function CreateEvent() {
|
|
const navigate = useNavigate();
|
|
const queryClient = useQueryClient();
|
|
const { toast } = useToast();
|
|
const [pendingEvent, setPendingEvent] = React.useState(null);
|
|
const [showConflictWarning, setShowConflictWarning] = React.useState(false);
|
|
|
|
const { data: currentUser } = useQuery({
|
|
queryKey: ['current-user-create-event'],
|
|
queryFn: () => base44.auth.me(),
|
|
});
|
|
|
|
const { data: allEvents = [] } = useQuery({
|
|
queryKey: ['events-for-conflict-check'],
|
|
queryFn: () => base44.entities.Event.list(),
|
|
initialData: [],
|
|
});
|
|
|
|
const createEventMutation = useMutation({
|
|
mutationFn: (eventData) => base44.entities.Event.create(eventData),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['events'] });
|
|
queryClient.invalidateQueries({ queryKey: ['client-events'] });
|
|
toast({
|
|
title: "✅ Event Created",
|
|
description: "Your event has been created successfully.",
|
|
});
|
|
navigate(createPageUrl("Events"));
|
|
},
|
|
onError: (error) => {
|
|
toast({
|
|
title: "❌ Failed to Create Event",
|
|
description: error.message || "There was an error creating the event.",
|
|
variant: "destructive",
|
|
});
|
|
},
|
|
});
|
|
|
|
const handleSubmit = (eventData) => {
|
|
// Detect conflicts before creating
|
|
const conflicts = detectAllConflicts(eventData, allEvents);
|
|
|
|
if (conflicts.length > 0) {
|
|
setPendingEvent({ ...eventData, detected_conflicts: conflicts });
|
|
setShowConflictWarning(true);
|
|
} else {
|
|
createEventMutation.mutate(eventData);
|
|
}
|
|
};
|
|
|
|
const handleConfirmWithConflicts = () => {
|
|
if (pendingEvent) {
|
|
createEventMutation.mutate(pendingEvent);
|
|
setShowConflictWarning(false);
|
|
setPendingEvent(null);
|
|
}
|
|
};
|
|
|
|
const handleCancelConflicts = () => {
|
|
setShowConflictWarning(false);
|
|
setPendingEvent(null);
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100">
|
|
<div className="max-w-7xl mx-auto p-4 md:p-8">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between mb-6">
|
|
<div>
|
|
<h1 className="text-3xl font-bold text-[#1C323E]">Create Standard Order</h1>
|
|
<p className="text-slate-600 mt-1">
|
|
Fill out the details for your planned event
|
|
</p>
|
|
</div>
|
|
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => navigate(createPageUrl("ClientDashboard"))}
|
|
>
|
|
<X className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Conflict Warning Modal */}
|
|
{showConflictWarning && pendingEvent && (
|
|
<Card className="mb-6 border-2 border-orange-500">
|
|
<CardContent className="p-6">
|
|
<div className="flex items-start gap-4 mb-4">
|
|
<div className="w-12 h-12 bg-orange-100 rounded-full flex items-center justify-center flex-shrink-0">
|
|
<AlertTriangle className="w-6 h-6 text-orange-600" />
|
|
</div>
|
|
<div>
|
|
<h3 className="font-bold text-lg text-slate-900 mb-1">
|
|
Scheduling Conflicts Detected
|
|
</h3>
|
|
<p className="text-sm text-slate-600">
|
|
This event has {pendingEvent.detected_conflicts.length} potential conflict{pendingEvent.detected_conflicts.length !== 1 ? 's' : ''}
|
|
with existing bookings. Review the conflicts below and decide how to proceed.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mb-6">
|
|
<ConflictAlert conflicts={pendingEvent.detected_conflicts} />
|
|
</div>
|
|
|
|
<div className="flex gap-3 justify-end">
|
|
<Button
|
|
variant="outline"
|
|
onClick={handleCancelConflicts}
|
|
>
|
|
Go Back & Edit
|
|
</Button>
|
|
<Button
|
|
onClick={handleConfirmWithConflicts}
|
|
className="bg-orange-600 hover:bg-orange-700"
|
|
>
|
|
Create Anyway
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
<EventFormWizard
|
|
event={null}
|
|
onSubmit={handleSubmit}
|
|
isSubmitting={createEventMutation.isPending}
|
|
currentUser={currentUser}
|
|
onCancel={() => navigate(createPageUrl("ClientDashboard"))}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |