From 280033b0e12558302cf23f77d65c159d2cb4eeba Mon Sep 17 00:00:00 2001 From: vergiLgood1 Date: Mon, 10 Mar 2025 23:54:28 +0700 Subject: [PATCH] add custom date time picker --- .../_components/data-table.tsx | 29 +- .../user-management/_components/sheet.tsx | 2 +- .../_components/update-user.tsx | 609 +++++++----------- .../_components/user-management.tsx | 132 ++-- .../dashboard/user-management/action.ts | 33 +- .../app/_components/date-time-picker.tsx | 417 ++++++++++++ .../app/_components/form-section.tsx | 18 + .../app/_components/form-wrapper.tsx | 156 +++++ sigap-website/app/_components/ui/button.tsx | 1 + .../app/_components/ui/date-picker.tsx | 118 ++++ sigap-website/package-lock.json | 28 + sigap-website/package.json | 1 + sigap-website/src/models/users/users.model.ts | 38 +- 13 files changed, 1106 insertions(+), 476 deletions(-) create mode 100644 sigap-website/app/_components/date-time-picker.tsx create mode 100644 sigap-website/app/_components/form-section.tsx create mode 100644 sigap-website/app/_components/form-wrapper.tsx create mode 100644 sigap-website/app/_components/ui/date-picker.tsx diff --git a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/data-table.tsx b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/data-table.tsx index 29e65c2..3f47d79 100644 --- a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/data-table.tsx +++ b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/data-table.tsx @@ -200,38 +200,11 @@ export function DataTable({ {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} - {/* {onActionClick && ( - - - - - )} */} )) ) : ( - + No results. diff --git a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/sheet.tsx b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/sheet.tsx index d36afd1..f485b2c 100644 --- a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/sheet.tsx +++ b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/sheet.tsx @@ -381,7 +381,7 @@ export function UserDetailSheet({ ) : ( <> - {user.banned_until ? "Unban user" : "Ban user"} + {user.banned_until ? "Unban user" : "Ban user"} )} diff --git a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/update-user.tsx b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/update-user.tsx index fb969ef..fe60b6e 100644 --- a/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/update-user.tsx +++ b/sigap-website/app/(protected)/(admin)/dashboard/user-management/_components/update-user.tsx @@ -1,80 +1,63 @@ -import { FormDescription } from "@/app/_components/ui/form"; -import { useState } from "react"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm } from "react-hook-form"; -import * as z from "zod"; -import { format } from "date-fns"; -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, -} from "@/app/_components/ui/sheet"; +import type React from "react" + +import { useState } from "react" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import type * as z from "zod" + +import { Loader2 } from "lucide-react" + +import { UpdateUserParamsSchema, type User, UserSchema } from "@/src/models/users/users.model" + +// UI Components +import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/app/_components/ui/sheet" import { Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/app/_components/ui/form"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/app/_components/ui/select"; -import { Input } from "@/app/_components/ui/input"; -import { Button } from "@/app/_components/ui/button"; -import { Textarea } from "@/app/_components/ui/textarea"; -import { Calendar } from "@/app/_components/ui/calendar"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/app/_components/ui/popover"; -import { cn } from "@/lib/utils"; -import { CalendarIcon, Loader2 } from "lucide-react"; -import { Switch } from "@/app/_components/ui/switch"; -import { User, UserSchema } from "@/src/models/users/users.model"; +} from "@/app/_components/ui/form" -type UserProfileFormValues = z.infer; +import { Button } from "@/app/_components/ui/button" +import { FormSection } from "@/app/_components/form-section" +import { FormFieldWrapper } from "@/app/_components/form-wrapper" +import { useMutation } from "@tanstack/react-query" +import { updateUser } from "../action" +import { toast } from "sonner" + + +type UserProfileFormValues = z.infer interface UserProfileSheetProps { - open: boolean; - onOpenChange: (open: boolean) => void; - userData?: User; // Replace with your user data type - onSave: (data: UserProfileFormValues) => Promise; + open: boolean + onOpenChange: (open: boolean) => void + userData?: User } -export function UserProfileSheet({ - open, - onOpenChange, - userData, - onSave, -}: UserProfileSheetProps) { - const [isSaving, setIsSaving] = useState(false); - +export function UserProfileSheet({ open, onOpenChange, userData }: UserProfileSheetProps) { + const [isSaving, setIsSaving] = useState(false) // Initialize form with user data const form = useForm({ - resolver: zodResolver(UserSchema), + resolver: zodResolver(UpdateUserParamsSchema), defaultValues: { email: userData?.email || "", + password_hash: userData?.password_hash || "", + role: (userData?.role as "user" | "staff" | "admin") || "user", phone: userData?.phone || "", - role: userData?.role || "user", + invited_at: userData?.invited_at || undefined, + confirmed_at: userData?.confirmed_at || undefined, + recovery_sent_at: userData?.recovery_sent_at || undefined, + last_sign_in_at: userData?.last_sign_in_at || undefined, + created_at: userData?.created_at || undefined, + updated_at: userData?.updated_at || undefined, is_anonymous: userData?.is_anonymous || false, + banned_until: userData?.banned_until ? String(userData.banned_until) : undefined, profile: { + id: userData?.profile?.id || "", + user_id: userData?.profile?.user_id || "", + avatar: userData?.profile?.avatar || "", username: userData?.profile?.username || "", first_name: userData?.profile?.first_name || "", last_name: userData?.profile?.last_name || "", bio: userData?.profile?.bio || "", - birth_date: userData?.profile?.birth_date - ? new Date(userData.profile.birth_date) - : null, - avatar: userData?.profile?.avatar || "", address: userData?.profile?.address || { street: "", city: "", @@ -82,368 +65,246 @@ export function UserProfileSheet({ country: "", postal_code: "", }, + birth_date: userData?.profile?.birth_date ? new Date(userData.profile.birth_date) : undefined, }, }, - }); + }) + + const { mutate: updateUserMutation, isPending } = useMutation({ + mutationKey: ["updateUser"], + mutationFn: (data: UserProfileFormValues) => { + if (!userData?.id) { + throw new Error("User ID is required"); + } + return updateUser(userData.id, data); + }, + onError: (error) => { + toast("Failed to update user"); + }, + onSuccess: () => { + toast("User updated"); + }, + }) async function onSubmit(data: UserProfileFormValues) { try { - setIsSaving(true); - await onSave(data); - onOpenChange(false); + setIsSaving(true) + await updateUserMutation(data) + onOpenChange(false) } catch (error) { - console.error("Error saving user profile:", error); + console.error("Error saving user profile:", error) } finally { - setIsSaving(false); + setIsSaving(false) } } return ( - - + + Update User Profile - - Make changes to the user profile here. Click save when you're - done. - + Make changes to the user profile here. Click save when you're done.
{/* User Information Section */} -
-

User Information

- - + ( - - Email - - - - - - )} - /> - - + ( - - Phone - - - - - - )} - /> - - + ( - - Role - - - - )} - /> - - ( - -
- - Anonymous User - - - Make this user anonymous in the system - -
- - - -
- )} + options={[ + { value: "user", label: "User" }, + { value: "admin", label: "Admin" }, + { value: "staff", label: "Staff" }, + ]} /> -
+ + + + + + + + + + {/* Profile Information Section */} -
-

Profile Information

- - + ( - - Username - - - - - - )} - /> - -
- ( - - First Name - - - - - - )} - /> - - ( - - Last Name - - - - - - )} - /> -
- - + + + ( - - Bio - -