From 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Tue, 25 Mar 2025 15:55:45 +0900
Subject: initial commit

---
 lib/admin-users/table/update-auser-sheet.tsx | 225 +++++++++++++++++++++++++++
 1 file changed, 225 insertions(+)
 create mode 100644 lib/admin-users/table/update-auser-sheet.tsx

(limited to 'lib/admin-users/table/update-auser-sheet.tsx')

diff --git a/lib/admin-users/table/update-auser-sheet.tsx b/lib/admin-users/table/update-auser-sheet.tsx
new file mode 100644
index 00000000..ddf1f932
--- /dev/null
+++ b/lib/admin-users/table/update-auser-sheet.tsx
@@ -0,0 +1,225 @@
+"use client"
+
+import * as React from "react"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { Loader } from "lucide-react"
+import { useForm } from "react-hook-form"
+import { toast } from "sonner"
+
+import {
+  Sheet,
+  SheetClose,
+  SheetContent,
+  SheetDescription,
+  SheetFooter,
+  SheetHeader,
+  SheetTitle,
+} from "@/components/ui/sheet"
+import { Button } from "@/components/ui/button"
+import {
+  Form,
+  FormControl,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from "@/components/ui/form"
+import { Input } from "@/components/ui/input"
+import {
+  Select,
+  SelectTrigger,
+  SelectContent,
+  SelectItem,
+  SelectValue,
+  SelectGroup,
+} from "@/components/ui/select"
+// import your MultiSelect or other role selection
+import { MultiSelect } from "@/components/ui/multi-select"
+
+import { userRoles, type UserView } from "@/db/schema/users"
+import { updateUserSchema, type UpdateUserSchema } from "@/lib/admin-users/validations"
+import { modifiUser } from "@/lib/admin-users/service"
+
+export interface UpdateAuserSheetProps
+  extends React.ComponentPropsWithRef<typeof Sheet> {
+  user: UserView | null
+}
+
+const languageOptions = [
+  { value: "ko", label: "한국어" },
+  { value: "en", label: "English" },
+]
+
+
+export function UpdateAuserSheet({ user, ...props }: UpdateAuserSheetProps) {
+  const [isUpdatePending, startUpdateTransition] = React.useTransition()
+  
+  // 1) RHF 설정
+  const form = useForm<UpdateUserSchema & { language?: string }>({
+    resolver: zodResolver(updateUserSchema),
+    defaultValues: {
+      name: user?.user_name ?? "",
+      email: user?.user_email ?? "",
+      companyId: user?.company_id ?? null,
+      roles: user?.roles ?? [],
+      language:'en',
+    },
+  })
+
+  // 2) user prop 바뀔 때마다 form.reset
+  React.useEffect(() => {
+    if (user) {
+      form.reset({
+        name: user.user_name,
+        email: user.user_email,
+        companyId: user.company_id,
+        roles: user.roles,
+      })
+    }
+  }, [user, form])
+
+
+  // 3) onSubmit
+  async function onSubmit(input: UpdateUserSchema & { language?: string }) {
+    startUpdateTransition(async () => {
+      if (!user) return
+
+      const { error } = await modifiUser({
+        id: user.user_id, // user.userId
+        ...input,
+      })
+
+      if (error) {
+        toast.error(error)
+        return
+      }
+
+      // 성공 시
+      form.reset()
+      props.onOpenChange?.(false)
+      toast.success("User updated successfully!")
+    })
+  }
+
+  return (
+    <Sheet {...props}>
+      <SheetContent className="flex flex-col gap-6 sm:max-w-md">
+        <SheetHeader className="text-left">
+          <SheetTitle>Update user</SheetTitle>
+          <SheetDescription>
+            Update the user details and save the changes
+          </SheetDescription>
+        </SheetHeader>
+
+        {/* 4) RHF Form */}
+        <Form {...form}>
+          <form
+            onSubmit={form.handleSubmit(onSubmit)}
+            className="flex flex-col gap-4"
+          >
+            {/* name */}
+            <FormField
+              control={form.control}
+              name="name"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>User Name</FormLabel>
+                  <FormControl>
+                    <Input placeholder="e.g. dujin" {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            {/* email */}
+            <FormField
+              control={form.control}
+              name="email"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>Email</FormLabel>
+                  <FormControl>
+                    <Input type="email" placeholder="user@example.com" {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            {/* roles */}
+            <FormField
+              control={form.control}
+              name="roles"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>Roles</FormLabel>
+                  <FormControl>
+                    <MultiSelect
+                      // 예: userRoles.role.enumValues = ["admin","normal"]
+                      defaultValue={form?.getValues().roles}
+                      options={[ 
+                        { value: "999999999", label: "admin" } 
+                      ]}
+                      value={field.value}
+                      onValueChange={(vals) => field.onChange(vals)}
+                    />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            <FormField
+              control={form.control}
+              name="language"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>Language</FormLabel>
+                  <FormControl>
+                    <Select
+                      onValueChange={field.onChange}
+                      // 'value'로 현재 값 연결. defaultValue 대신 Controlled 컴포넌트로
+                      value={field.value}
+                    >
+                      <SelectTrigger>
+                        <SelectValue placeholder="Select language" />
+                      </SelectTrigger>
+                      <SelectContent>
+                        {languageOptions.map((v, index) => (
+                          <SelectItem key={index} value={v.value}>
+                            {v.label}
+                          </SelectItem>
+                        ))}
+                      </SelectContent>
+                    </Select>
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            {/* 5) Footer: Cancel, Save */}
+            <SheetFooter className="gap-2 pt-2 sm:space-x-0">
+              <SheetClose asChild>
+                <Button type="button" variant="outline">
+                  Cancel
+                </Button>
+              </SheetClose>
+
+              <Button type="submit" disabled={isUpdatePending}>
+                {isUpdatePending && (
+                  <Loader
+                    className="mr-2 size-4 animate-spin"
+                    aria-hidden="true"
+                  />
+                )}
+                Save
+              </Button>
+            </SheetFooter>
+          </form>
+        </Form>
+      </SheetContent>
+    </Sheet>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

