MIF_E31221222/sigap-website/app/protected/(admin-pages)/_components/users/add-user.tsx

236 lines
6.8 KiB
TypeScript

"use client";
import { useState } from "react";
import { Button } from "@/app/_components/ui/button";
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
} from "@/app/_components/ui/sheet";
import { Input } from "@/app/_components/ui/input";
import { Label } from "@/app/_components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/app/_components/ui/select";
import { User } from "./users-table";
interface AddUserSheetProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSave: (
userData: Omit<User, "id" | "lastSignedIn"> & { password: string }
) => void;
}
export function AddUserSheet({
open,
onOpenChange,
onSave,
}: AddUserSheetProps) {
const [userData, setUserData] = useState<
Omit<User, "id" | "lastSignedIn"> & { password: string }
>({
email: "",
firstName: "",
lastName: "",
avatar: "/placeholder.svg?height=40&width=40",
role: "user",
status: "active",
password: "",
});
const [errors, setErrors] = useState<Record<string, string>>({});
const validateForm = () => {
const newErrors: Record<string, string> = {};
if (!userData.email) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(userData.email)) {
newErrors.email = "Email is invalid";
}
if (!userData.password) {
newErrors.password = "Password is required";
} else if (userData.password.length < 6) {
newErrors.password = "Password must be at least 6 characters";
}
if (!userData.firstName) {
newErrors.firstName = "First name is required";
}
if (!userData.lastName) {
newErrors.lastName = "Last name is required";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = () => {
if (validateForm()) {
onSave(userData);
// Reset form
setUserData({
email: "",
firstName: "",
lastName: "",
avatar: "/placeholder.svg?height=40&width=40",
role: "user",
status: "active",
password: "",
});
setErrors({});
}
};
const handleInputChange = (field: keyof typeof userData, value: string) => {
setUserData((prev) => ({ ...prev, [field]: value }));
// Clear error when field is edited
if (errors[field]) {
setErrors((prev) => {
const newErrors = { ...prev };
delete newErrors[field];
return newErrors;
});
}
};
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent className="sm:max-w-md">
<SheetHeader>
<SheetTitle>Add New User</SheetTitle>
<SheetDescription>
Create a new user account with Supabase authentication.
</SheetDescription>
</SheetHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="email" className="text-right">
Email
</Label>
<Input
id="email"
value={userData.email}
onChange={(e) => handleInputChange("email", e.target.value)}
className="col-span-3"
/>
{errors.email && (
<p className="col-span-3 col-start-2 text-sm text-red-500">
{errors.email}
</p>
)}
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="password" className="text-right">
Password
</Label>
<Input
id="password"
type="password"
value={userData.password}
onChange={(e) => handleInputChange("password", e.target.value)}
className="col-span-3"
/>
{errors.password && (
<p className="col-span-3 col-start-2 text-sm text-red-500">
{errors.password}
</p>
)}
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="firstName" className="text-right">
First Name
</Label>
<Input
id="firstName"
value={userData.firstName}
onChange={(e) => handleInputChange("firstName", e.target.value)}
className="col-span-3"
/>
{errors.firstName && (
<p className="col-span-3 col-start-2 text-sm text-red-500">
{errors.firstName}
</p>
)}
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="lastName" className="text-right">
Last Name
</Label>
<Input
id="lastName"
value={userData.lastName}
onChange={(e) => handleInputChange("lastName", e.target.value)}
className="col-span-3"
/>
{errors.lastName && (
<p className="col-span-3 col-start-2 text-sm text-red-500">
{errors.lastName}
</p>
)}
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="role" className="text-right">
Role
</Label>
<Select
value={userData.role}
onValueChange={(value: "admin" | "staff" | "user") =>
handleInputChange("role", value)
}
>
<SelectTrigger className="col-span-3">
<SelectValue placeholder="Select a role" />
</SelectTrigger>
<SelectContent>
<SelectItem value="admin">Admin</SelectItem>
<SelectItem value="staff">Staff</SelectItem>
<SelectItem value="user">User</SelectItem>
</SelectContent>
</Select>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="status" className="text-right">
Status
</Label>
<Select
value={userData.status}
onValueChange={(value: "active" | "inactive") =>
handleInputChange("status", value)
}
>
<SelectTrigger className="col-span-3">
<SelectValue placeholder="Select a status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="active">Active</SelectItem>
<SelectItem value="inactive">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<SheetFooter>
<Button type="submit" onClick={handleSubmit}>
Add User
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
);
}