summaryrefslogtreecommitdiff
path: root/lib/approval-template/table/approval-template-table-toolbar-actions.tsx
blob: 08aba97a69ad27afb7d5b855abd827e4d0266339 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"use client"

import * as React from "react"
import { type Table } from "@tanstack/react-table"
import { Download, Plus, Trash } from "lucide-react"

import { Button } from "@/components/ui/button"
import { type ApprovalTemplate } from "@/lib/approval-template/service"
import { toast } from "sonner"
import { DeleteApprovalTemplateDialog } from "./delete-approval-template-dialog"

interface ApprovalTemplateTableToolbarActionsProps {
  table: Table<ApprovalTemplate>
  onCreateTemplate: () => void
}

export function ApprovalTemplateTableToolbarActions({
  table,
  onCreateTemplate,
}: ApprovalTemplateTableToolbarActionsProps) {
  const [showDeleteDialog, setShowDeleteDialog] = React.useState(false)

  const selectedRows = table.getFilteredSelectedRowModel().rows
  const selectedTemplates = selectedRows.map((row) => row.original)

  // CSV 내보내기
  const exportToCsv = React.useCallback(() => {
    const headers = [
      "이름",
      "제목",
      "카테고리",
      "생성일",
      "수정일",
    ]

    const csvData = [
      headers,
      ...table.getFilteredRowModel().rows.map((row) => {
        const t = row.original
        return [
          t.name,
          t.subject,
          t.category ?? "-",
          new Date(t.createdAt).toLocaleDateString("ko-KR"),
          new Date(t.updatedAt).toLocaleDateString("ko-KR"),
        ]
      }),
    ]

    const csvContent = csvData
      .map((row) => row.map((field) => `"${field}"`).join(","))
      .join("\n")

    const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" })
    const link = document.createElement("a")

    if (link.download !== undefined) {
      const url = URL.createObjectURL(blob)
      link.setAttribute("href", url)
      link.setAttribute(
        "download",
        `approval_templates_${new Date().toISOString().split("T")[0]}.csv`,
      )
      link.style.visibility = "hidden"
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }

    toast.success("템플릿 목록이 CSV로 내보내졌습니다.")
  }, [table])

  return (
    <div className="flex items-center gap-2">
      {/* 새 템플릿 버튼 */}
      <Button variant="default" size="sm" onClick={onCreateTemplate}>
        <Plus className="mr-2 size-4" aria-hidden="true" />
        새 템플릿
      </Button>

      {/* CSV 내보내기 */}
      <Button variant="outline" size="sm" onClick={exportToCsv}>
        <Download className="mr-2 size-4" aria-hidden="true" />
        내보내기
      </Button>

      {/* 일괄 삭제 */}
      {selectedTemplates.length > 0 && (
        <>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setShowDeleteDialog(true)}
            className="text-destructive hover:text-destructive"
          >
            <Trash className="mr-2 size-4" aria-hidden="true" />
            삭제 ({selectedTemplates.length})
          </Button>

          <DeleteApprovalTemplateDialog
            open={showDeleteDialog}
            onOpenChange={setShowDeleteDialog}
            templates={selectedTemplates}
            showTrigger={false}
            onSuccess={() => {
              table.toggleAllRowsSelected(false)
              setShowDeleteDialog(false)
            }}
          />
        </>
      )}
    </div>
  )
}