import React, { useState } from "react"; import { base44 } from "@/api/base44Client"; import { useQuery, useMutation } from "@tanstack/react-query"; import { useNavigate } from "react-router-dom"; import { createPageUrl } from "@/utils"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { CheckCircle2, UserPlus, User, Lock, Briefcase } from "lucide-react"; import { useToast } from "@/components/ui/use-toast"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; export default function Onboarding() { const navigate = useNavigate(); const { toast } = useToast(); const urlParams = new URLSearchParams(window.location.search); const inviteCode = urlParams.get('invite'); const [step, setStep] = useState(1); const [formData, setFormData] = useState({ first_name: "", last_name: "", email: "", phone: "", title: "", department: "", hub: "", password: "", confirmPassword: "" }); // Fetch invite details if invite code exists const { data: invite } = useQuery({ queryKey: ['team-invite', inviteCode], queryFn: async () => { const allInvites = await base44.entities.TeamMemberInvite.list(); const foundInvite = allInvites.find(inv => inv.invite_code === inviteCode && inv.invite_status === 'pending'); if (foundInvite) { // Pre-fill form with invite data const nameParts = (foundInvite.full_name || "").split(' '); setFormData(prev => ({ ...prev, email: foundInvite.email, first_name: nameParts[0] || "", last_name: nameParts.slice(1).join(' ') || "" })); } return foundInvite; }, enabled: !!inviteCode, }); // Fetch available hubs for the team const { data: hubs = [] } = useQuery({ queryKey: ['team-hubs-onboarding', invite?.team_id], queryFn: async () => { if (!invite?.team_id) return []; const allHubs = await base44.entities.TeamHub.list(); return allHubs.filter(h => h.team_id === invite.team_id && h.is_active); }, enabled: !!invite?.team_id, initialData: [], }); const registerMutation = useMutation({ mutationFn: async (data) => { if (!invite) { throw new Error("Invalid invitation. Please contact your team administrator."); } // Check if invite was already accepted if (invite.invite_status !== 'pending') { throw new Error("This invitation has already been used. Please contact your team administrator for a new invitation."); } // Check for duplicate email in TeamMember const allMembers = await base44.entities.TeamMember.list(); const existingMemberByEmail = allMembers.find(m => m.email?.toLowerCase() === data.email.toLowerCase() && m.team_id === invite.team_id ); if (existingMemberByEmail) { throw new Error(`A team member with email ${data.email} already exists in this team. Please contact your team administrator.`); } // Check for duplicate phone in TeamMember if (data.phone) { const existingMemberByPhone = allMembers.find(m => m.phone === data.phone && m.team_id === invite.team_id ); if (existingMemberByPhone) { throw new Error(`A team member with phone number ${data.phone} already exists in this team. Please contact your team administrator.`); } } // Create team member record const member = await base44.entities.TeamMember.create({ team_id: invite.team_id, member_name: `${data.first_name} ${data.last_name}`.trim(), email: data.email, phone: data.phone, title: data.title, department: data.department, hub: data.hub, role: invite.role || "member", is_active: true, }); // Update invite status to accepted await base44.entities.TeamMemberInvite.update(invite.id, { invite_status: "accepted", accepted_date: new Date().toISOString() }); return { member, invite }; }, onSuccess: () => { setStep(4); toast({ title: "✅ Registration Successful!", description: "You've been added to the team successfully.", }); }, onError: (error) => { toast({ title: "❌ Registration Failed", description: error.message, variant: "destructive", }); }, }); const handleNext = () => { if (step === 1) { // Validate basic info if (!formData.first_name || !formData.last_name || !formData.email || !formData.phone) { toast({ title: "Missing Information", description: "Please fill in your name, email, and phone number", variant: "destructive", }); return; } setStep(2); } else if (step === 2) { // Validate additional info if (!formData.title || !formData.department) { toast({ title: "Missing Information", description: "Please fill in your title and department", variant: "destructive", }); return; } setStep(3); } else if (step === 3) { // Validate password if (!formData.password || formData.password !== formData.confirmPassword) { toast({ title: "Password Mismatch", description: "Passwords do not match", variant: "destructive", }); return; } if (formData.password.length < 6) { toast({ title: "Password Too Short", description: "Password must be at least 6 characters", variant: "destructive", }); return; } registerMutation.mutate(formData); } }; if (!inviteCode || !invite) { return (
This invitation link is invalid or has expired. Please contact your team administrator for a new invitation.
This invitation has already been accepted. If you need access, please contact your team administrator.
You've been invited by {invite.invited_by} as a {invite.role}
Minimum 6 characters
Name: {formData.first_name} {formData.last_name}
Email: {formData.email}
Phone: {formData.phone}
Title: {formData.title}
Department: {formData.department}
{formData.hub &&Hub: {formData.hub}
}Role: {invite.role}
Your account has been created successfully!
Name: {formData.first_name} {formData.last_name}
Email: {formData.email}
Title: {formData.title}
Department: {formData.department}
{formData.hub &&Hub: {formData.hub}
}Team: {invite.team_name}