diff --git a/attached_assets/Screenshot 2025-05-30 at 8.37.45 PM.png b/attached_assets/Screenshot 2025-05-30 at 8.37.45 PM.png new file mode 100644 index 0000000..8d4e643 Binary files /dev/null and b/attached_assets/Screenshot 2025-05-30 at 8.37.45 PM.png differ diff --git a/client/src/App.tsx b/client/src/App.tsx index 56e4d16..8925e7d 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -11,7 +11,7 @@ import LandingPage from "@/pages/LandingPage"; import DashboardPage from "@/pages/DashboardPage"; import LoginPage from "@/pages/LoginPage"; import ProfessionalDirectory from "@/pages/ProfessionalDirectory"; -// import OnboardingPage from "@/pages/OnboardingPage"; +import OnboardingPage from "@/pages/OnboardingPage"; import NotFound from "@/pages/not-found"; function Router() { @@ -20,6 +20,7 @@ function Router() { + diff --git a/client/src/pages/LoginPage.tsx b/client/src/pages/LoginPage.tsx index 9bbaff7..f3c6b5d 100644 --- a/client/src/pages/LoginPage.tsx +++ b/client/src/pages/LoginPage.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { Link, useLocation } from "wouter"; import { useAuth } from "@/hooks/useAuth"; import { useTheme } from "@/context/ThemeContext"; @@ -35,10 +35,11 @@ export default function LoginPage() { const [error, setError] = useState(""); // Redirect if already authenticated - if (user) { - setLocation("/dashboard"); - return null; - } + useEffect(() => { + if (user) { + setLocation("/dashboard"); + } + }, [user, setLocation]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); diff --git a/client/src/pages/OnboardingPage.tsx b/client/src/pages/OnboardingPage.tsx new file mode 100644 index 0000000..f22142f --- /dev/null +++ b/client/src/pages/OnboardingPage.tsx @@ -0,0 +1,349 @@ +import { useState } from "react"; +import { useAuth } from "@/hooks/useAuth"; +import { useLocation } from "wouter"; +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 { Textarea } from "@/components/ui/textarea"; +import { Badge } from "@/components/ui/badge"; +import { Separator } from "@/components/ui/separator"; +import { Switch } from "@/components/ui/switch"; +import { Progress } from "@/components/ui/progress"; +import { + CheckCircle, + ArrowRight, + User, + Briefcase, + Calendar, + Clock, + MapPin, + Phone, + Users +} from "lucide-react"; + +export default function OnboardingPage() { + const { user, updateProfile } = useAuth(); + const [, setLocation] = useLocation(); + const [currentStep, setCurrentStep] = useState(1); + const [formData, setFormData] = useState({ + // Professional profile fields + businessName: "", + bio: "", + specializations: "", + address: "", + phoneNumber: "", + allowAppointmentBooking: false, + + // Availability settings + workingHours: { + monday: { enabled: true, start: "09:00", end: "17:00" }, + tuesday: { enabled: true, start: "09:00", end: "17:00" }, + wednesday: { enabled: true, start: "09:00", end: "17:00" }, + thursday: { enabled: true, start: "09:00", end: "17:00" }, + friday: { enabled: true, start: "09:00", end: "17:00" }, + saturday: { enabled: false, start: "09:00", end: "17:00" }, + sunday: { enabled: false, start: "09:00", end: "17:00" }, + } + }); + + const totalSteps = user?.role === "pro" ? 3 : 2; + const progress = (currentStep / totalSteps) * 100; + + const handleInputChange = (field: string, value: any) => { + setFormData(prev => ({ ...prev, [field]: value })); + }; + + const handleNext = () => { + if (currentStep < totalSteps) { + setCurrentStep(currentStep + 1); + } + }; + + const handleBack = () => { + if (currentStep > 1) { + setCurrentStep(currentStep - 1); + } + }; + + const handleComplete = async () => { + try { + await updateProfile({ + onboardingComplete: true, + businessName: formData.businessName || null, + bio: formData.bio || null, + specializations: formData.specializations ? formData.specializations.split(',').map(s => s.trim()).join(',') : null, + address: formData.address || null, + phoneNumber: formData.phoneNumber || null, + allowAppointmentBooking: formData.allowAppointmentBooking, + }); + setLocation("/dashboard"); + } catch (error) { + console.error("Failed to complete onboarding:", error); + } + }; + + const renderStep1 = () => ( +
+
+
+ +
+

Welcome to TaskFin AI Suite!

+

+ Let's set up your account to get the most out of your experience. +

+
+ + + + Account Overview + Your account details and features + + +
+ Account Type + + {user?.role} + +
+ + +
+

Available Features:

+
+
+ + Task Management +
+
+ + Financial Tracking +
+
+ + Voice Commands (Arabic/English) +
+
+ + AI Insights +
+ {user?.role === "pro" && ( + <> +
+ + Professional Profiles +
+
+ + Appointment Booking +
+ + )} +
+
+
+
+
+ ); + + const renderStep2 = () => ( +
+
+
+ +
+

Professional Profile

+

+ Set up your professional information for better networking and discovery. +

+
+ + + + Business Information + Help others find and connect with you + + +
+ + handleInputChange("businessName", e.target.value)} + /> +
+ +
+ +