From e0dfb55c5457aec489fc084c4567e791b4c65eb1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 26 Mar 2025 00:37:41 +0000
Subject: 3/25 까지의 대표님 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/users/table/assign-roles-dialog.tsx | 194 ++++++++++++++++++++++++++++++++
 1 file changed, 194 insertions(+)
 create mode 100644 lib/users/table/assign-roles-dialog.tsx

(limited to 'lib/users/table/assign-roles-dialog.tsx')

diff --git a/lib/users/table/assign-roles-dialog.tsx b/lib/users/table/assign-roles-dialog.tsx
new file mode 100644
index 00000000..003f6500
--- /dev/null
+++ b/lib/users/table/assign-roles-dialog.tsx
@@ -0,0 +1,194 @@
+import * as React from "react"
+import { useForm } from "react-hook-form"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
+import { Input } from "@/components/ui/input"
+import {
+  Form,
+  FormControl,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from "@/components/ui/form"
+import {
+  Select,
+  SelectContent,
+  SelectGroup,
+  SelectItem,
+  SelectLabel,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import { Check, ChevronsUpDown, Loader, UserRoundPlus } from "lucide-react"
+import { cn } from "@/lib/utils"
+import { toast } from "sonner"
+
+import { Textarea } from "@/components/ui/textarea"
+import { Company } from "@/db/schema/companies"
+import { getAllCompanies } from "@/lib/admin-users/service"
+import {
+  Popover,
+  PopoverTrigger,
+  PopoverContent,
+} from "@/components/ui/popover"
+import {
+  Command,
+  CommandInput,
+  CommandList,
+  CommandGroup,
+  CommandItem,
+  CommandEmpty,
+} from "@/components/ui/command"
+import { assignRolesToUsers, getAllRoleView } from "@/lib/roles/services"
+import { RoleView } from "@/db/schema/users"
+import { type UserView } from "@/db/schema/users"
+import { type Row } from "@tanstack/react-table"
+import { createRoleAssignmentSchema, CreateRoleAssignmentSchema, createRoleSchema, CreateRoleSchema } from "@/lib/roles/validations"
+import { MultiSelect } from "@/components/ui/multi-select"
+
+interface AssignRoleDialogProps
+  extends React.ComponentPropsWithoutRef<typeof Dialog> {
+  users: Row<UserView>["original"][]
+
+}
+
+
+export function AssignRoleDialog({ users }: AssignRoleDialogProps) {
+  const [open, setOpen] = React.useState(false)
+  const [isAddPending, startAddTransition] = React.useTransition()
+  const [roles, setRoles] = React.useState<RoleView[]>([])  // 회사 목록
+  const [loading, setLoading] = React.useState(false)
+
+  const partnersRoles = roles.filter(v => v.domain === "partners")
+  const evcpRoles = roles.filter(v => v.domain === "evcp")
+
+
+  React.useEffect(() => {
+    getAllRoleView("evcp").then((res) => {
+      setRoles(res)
+    })
+  }, [])
+
+
+  const form = useForm<CreateRoleAssignmentSchema>({
+    resolver: zodResolver(createRoleAssignmentSchema),
+    defaultValues: {
+      evcpRoles: [],
+    },
+  })
+
+
+  function handleDialogOpenChange(nextOpen: boolean) {
+    if (!nextOpen) {
+      form.reset()
+    }
+    setOpen(nextOpen)
+  }
+
+  const evcpUsers = users.filter(v => v.user_domain === "evcp");
+
+
+  async function onSubmit(data: CreateRoleAssignmentSchema) {
+    console.log(data.evcpRoles.map((v)=>Number(v)))
+    startAddTransition(async () => {
+
+
+      // if(partnerUsers.length>0){
+      //   const result = await assignRolesToUsers( partnerUsers.map(v=>v.user_id) ,data.partnersRoles)
+
+      //   if (result.error) {
+      //     toast.error(`에러: ${result.error}`)
+      //     return
+      //   }
+      // }
+
+      if (evcpUsers.length > 0) {
+        const result = await assignRolesToUsers( data.evcpRoles.map((v)=>Number(v)), evcpUsers.map(v => v.user_id))
+
+        if (result.error) {
+          toast.error(`에러: ${result.error}`)
+          return
+        }
+      }
+
+      form.reset()
+      setOpen(false)
+      toast.success("Role assgined")
+    })
+  }
+
+  return (
+    <Dialog open={open} onOpenChange={handleDialogOpenChange}>
+      <DialogTrigger asChild>
+        <Button variant="default" size="sm">
+          <UserRoundPlus className="mr-2 size-4" aria-hidden="true" />
+          Assign Role ({users.length})
+        </Button>
+      </DialogTrigger>
+
+      <DialogContent>
+        <DialogHeader>
+          <DialogTitle>Assign Roles to {evcpUsers.length} Users</DialogTitle>
+          <DialogDescription>
+            Role을 Multi-select 하시기 바랍니다.
+          </DialogDescription>
+        </DialogHeader>
+
+
+        <Form {...form}>
+          <form onSubmit={form.handleSubmit(onSubmit)}>
+            <div className="space-y-4 py-4">
+              {/* evcp 롤 선택 */}
+              {evcpUsers.length > 0 &&
+                <FormField
+                  control={form.control}
+                  name="evcpRoles"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>eVCP Role</FormLabel>
+                      <FormControl>
+                        <MultiSelect
+                          options={evcpRoles.map((role) => ({ value: String(role.id), label: role.name }))}
+                          onValueChange={(values) => {
+                            field.onChange(values);
+                          }}
+
+                        />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+              }
+            </div>
+
+            <DialogFooter>
+              <Button
+                type="button"
+                variant="outline"
+                onClick={() => setOpen(false)}
+                disabled={isAddPending}
+              >
+                Cancel
+              </Button>
+              <Button
+                type="submit"
+                disabled={form.formState.isSubmitting || isAddPending}
+              >
+                {isAddPending && (
+                  <Loader
+                    className="mr-2 size-4 animate-spin"
+                    aria-hidden="true"
+                  />
+                )}
+                Assgin
+              </Button>
+            </DialogFooter>
+          </form>
+        </Form>
+      </DialogContent>
+    </Dialog>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

