summaryrefslogtreecommitdiff
path: root/lib/email-template/table/template-table-toolbar-actions.tsx
blob: a7e107c635f379beb6705c4e8dd897181a2c72cf (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
115
"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 TemplateListView } from "@/db/schema/template-views"
import { DeleteTemplateDialog } from "./delete-template-dialog"
import { toast } from "sonner"

interface TemplateTableToolbarActionsProps {
  table: Table<TemplateListView>
  onCreateTemplate: () => void
}

export function TemplateTableToolbarActions({
  table,
  onCreateTemplate,
}: TemplateTableToolbarActionsProps) {
  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 = ['이름', 'Slug', '카테고리', '변수 개수', '버전', '생성일', '수정일']
    const csvData = [
      headers,
      ...table.getFilteredRowModel().rows.map(row => {
        const template = row.original
        return [
          template.name,
          template.slug,
          template.categoryDisplayName || '미분류',
          template.variableCount.toString(),
          template.version.toString(),
          new Date(template.createdAt).toLocaleDateString('ko-KR'),
          new Date(template.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', `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>

          {/* 일괄 삭제 Dialog */}
          <DeleteTemplateDialog
            open={showDeleteDialog}
            onOpenChange={setShowDeleteDialog}
            templates={selectedTemplates}
            showTrigger={false}
            onSuccess={() => {
              table.toggleAllRowsSelected(false)
              setShowDeleteDialog(false)
            }}
          />
        </>
      )}
    </div>
  )
}