feat: Initialize monorepo structure and comprehensive documentation
This commit establishes the new monorepo architecture for the KROW Workforce platform. Key changes include: - Reorganized project into `frontend-web`, `mobile-apps`, `firebase`, `scripts`, and `secrets` directories. - Updated `Makefile` to support the new monorepo layout and automate Base44 export integration. - Fixed `scripts/prepare-export.js` for ES module compatibility and global component import resolution. - Created and updated `CONTRIBUTING.md` for developer onboarding. - Restructured, renamed, and translated all `docs/` files for clarity and consistency. - Implemented an interactive internal launchpad with diagram viewing capabilities. - Configured base Firebase project files (`firebase.json`, security rules). - Updated `README.md` to reflect the new project structure and documentation overview.
This commit is contained in:
149
frontend-web/src/pages/CreateEvent.jsx
Normal file
149
frontend-web/src/pages/CreateEvent.jsx
Normal file
@@ -0,0 +1,149 @@
|
||||
import React, { useState } 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 AIOrderAssistant from "../components/events/AIOrderAssistant";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Sparkles, FileText, X } from "lucide-react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
export default function CreateEvent() {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
const { toast } = useToast();
|
||||
const [useAI, setUseAI] = useState(false);
|
||||
const [aiExtractedData, setAiExtractedData] = useState(null);
|
||||
|
||||
const { data: currentUser } = useQuery({
|
||||
queryKey: ['current-user-create-event'],
|
||||
queryFn: () => base44.auth.me(),
|
||||
});
|
||||
|
||||
const createEventMutation = useMutation({
|
||||
mutationFn: (eventData) => base44.entities.Event.create(eventData),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['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) => {
|
||||
createEventMutation.mutate(eventData);
|
||||
};
|
||||
|
||||
const handleAIDataExtracted = (extractedData) => {
|
||||
setAiExtractedData(extractedData);
|
||||
setUseAI(false);
|
||||
};
|
||||
|
||||
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 with AI Toggle */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-[#1C323E]">Create New Order</h1>
|
||||
<p className="text-slate-600 mt-1">
|
||||
{useAI ? "Use AI to create your order naturally" : "Fill out the form to create your order"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant={useAI ? "default" : "outline"}
|
||||
onClick={() => setUseAI(true)}
|
||||
className={useAI ? "bg-gradient-to-r from-[#0A39DF] to-purple-600" : ""}
|
||||
>
|
||||
<Sparkles className="w-4 h-4 mr-2" />
|
||||
AI Assistant
|
||||
</Button>
|
||||
<Button
|
||||
variant={!useAI ? "default" : "outline"}
|
||||
onClick={() => setUseAI(false)}
|
||||
className={!useAI ? "bg-[#1C323E]" : ""}
|
||||
>
|
||||
<FileText className="w-4 h-4 mr-2" />
|
||||
Form
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => navigate(createPageUrl("Events"))}
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI Assistant Interface */}
|
||||
<AnimatePresence>
|
||||
{useAI && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
>
|
||||
<AIOrderAssistant
|
||||
onOrderDataExtracted={handleAIDataExtracted}
|
||||
onClose={() => setUseAI(false)}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
{/* Wizard Form */}
|
||||
{!useAI && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
>
|
||||
{aiExtractedData && (
|
||||
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-xl">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Sparkles className="w-5 h-5 text-green-600" />
|
||||
<span className="font-semibold text-green-900">AI Pre-filled Data</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700 mb-3">
|
||||
The form has been pre-filled with information from your conversation. Review and edit as needed.
|
||||
</p>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setAiExtractedData(null);
|
||||
setUseAI(true);
|
||||
}}
|
||||
className="border-green-300 text-green-700 hover:bg-green-100"
|
||||
>
|
||||
<Sparkles className="w-4 h-4 mr-2" />
|
||||
Chat with AI Again
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<EventFormWizard
|
||||
event={aiExtractedData}
|
||||
onSubmit={handleSubmit}
|
||||
isSubmitting={createEventMutation.isPending}
|
||||
currentUser={currentUser}
|
||||
onCancel={() => navigate(createPageUrl("Events"))}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user