diff --git a/apps/admin/app/signup/page.tsx b/apps/admin/app/signup/page.tsx new file mode 100644 index 0000000..abfda4a --- /dev/null +++ b/apps/admin/app/signup/page.tsx @@ -0,0 +1,598 @@ +"use client" + +import { useState } from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import * as z from "zod" +import { Button } from "@workspace/ui/components/button" +import { Input } from "@workspace/ui/components/input" +import { Textarea } from "@workspace/ui/components/textarea" +import { Progress } from "@workspace/ui/components/progress" +import { Separator } from "@workspace/ui/components/separator" +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription } from "@workspace/ui/components/form" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@workspace/ui/components/select" +import { Card, CardContent, CardHeader, CardTitle } from "@workspace/ui/components/card" + +// Form schema +const formSchema = z.object({ + // Personal Details + firstName: z.string().min(1, "First name is required"), + lastName: z.string().min(1, "Last name is required"), + fathersName: z.string().optional(), + mothersName: z.string().optional(), + email: z.string().email("Invalid email address"), + rollNumber: z.string().min(1, "Roll number is required"), + phoneNumber: z.string().min(10, "Phone number must be at least 10 digits"), + address: z.string().min(1, "Address is required"), + + // Academic Details + degree: z.string().min(1, "Degree is required"), + year: z.string().min(1, "Year is required"), + branch: z.string().min(1, "Branch is required"), + ssc: z.string().min(1, "SSC percentage is required"), + hsc: z.string().min(1, "HSC percentage is required"), + + // Semester Grades + sem1: z.string().min(1, "Semester 1 grade is required"), + sem1KT: z.string().min(1, "Semester 1 KT status is required"), + sem2: z.string().min(1, "Semester 2 grade is required"), + sem2KT: z.string().min(1, "Semester 2 KT status is required"), + + // Additional Details + linkedin: z.string().url("Invalid LinkedIn URL"), + github: z.string().url("Invalid GitHub URL"), + skills: z.string().optional(), +}) + +type FormData = z.infer + +const steps = [ + { + id: 1, + title: "Personal Details", + fields: ["firstName", "lastName", "fathersName", "mothersName", "email", "rollNumber", "phoneNumber", "address"], + }, + { id: 2, title: "Academic Details", fields: ["degree", "year", "branch", "ssc", "hsc"] }, + { id: 3, title: "Semester Grades", fields: ["sem1", "sem1KT", "sem2", "sem2KT"] }, + { id: 4, title: "Additional Details", fields: ["linkedin", "github", "skills"] }, +] + +export default function StudentRegistrationForm() { + const [currentStep, setCurrentStep] = useState(1) + const [isSubmitting, setIsSubmitting] = useState(false) + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + firstName: "", + lastName: "", + fathersName: "", + mothersName: "", + email: "", + rollNumber: "", + phoneNumber: "", + address: "", + degree: "", + year: "", + branch: "", + ssc: "", + hsc: "", + sem1: "", + sem1KT: "", + sem2: "", + sem2KT: "", + linkedin: "", + github: "", + skills: "", + }, + }) + + const validateCurrentStep = async () => { + const currentStepData = steps.find((step) => step.id === currentStep) + if (!currentStepData) return false + + const result = await form.trigger(currentStepData.fields as any) + return result + } + + const nextStep = async () => { + const isValid = await validateCurrentStep() + if (isValid && currentStep < steps.length) { + setCurrentStep(currentStep + 1) + } + } + + const prevStep = () => { + if (currentStep > 1) { + setCurrentStep(currentStep - 1) + } + } + + const onSubmit = async (data: FormData) => { + setIsSubmitting(true) + try { + // Simulate API call + await new Promise((resolve) => setTimeout(resolve, 2000)) + console.log("Form submitted:", data) + alert("Form submitted successfully!") + } catch (error) { + console.error("Submission error:", error) + alert("Submission failed. Please try again.") + } finally { + setIsSubmitting(false) + } + } + + const renderStep = () => { + switch (currentStep) { + case 1: + return + case 2: + return + case 3: + return + case 4: + return + default: + return null + } + } + + const progress = (currentStep / steps.length) * 100 + + return ( +
+
+ + + Student Registration Form +
+
+ + Step {currentStep} of {steps.length} + + {steps[currentStep - 1]?.title} +
+ +
+
+ +
+ + {renderStep()} + +
+ + + {currentStep === steps.length ? ( + + ) : ( + + )} +
+
+ +
+
+
+
+ ) +} + +function PersonalDetailsStep({ form }: { form: any }) { + return ( +
+

Personal Details

+ +
+ ( + + First Name * + + + + + + )} + /> + ( + + Last Name * + + + + + + )} + /> +
+ +
+ ( + + Father's Name + + + + + + )} + /> + ( + + Mother's Name + + + + + + )} + /> +
+ + + +
+ ( + + Email * + + + + + + )} + /> + ( + + Roll Number * + + + + + + )} + /> +
+ + ( + + Phone Number * + + + + Without country code + + + )} + /> + + ( + + Address * + +