summaryrefslogtreecommitdiff
path: root/lib/gtc-contract/status/create-new-revision-dialog.tsx
blob: e18e635224709cd4e18f276c23c5ff164d78f073 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"use client"

import * as React from "react"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"

import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Loader } from "lucide-react"
import { toast } from "sonner"

import { createNewRevisionSchema, type CreateNewRevisionSchema } from "@/lib/gtc-contract/validations"
import { createNewRevision } from "@/lib/gtc-contract/service"
import { type GtcDocumentWithRelations } from "@/db/schema/gtc"

interface CreateNewRevisionDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  originalDocument: GtcDocumentWithRelations | null
}

export function CreateNewRevisionDialog({
  open,
  onOpenChange,
  originalDocument,
}: CreateNewRevisionDialogProps) {
  const [isCreatePending, startCreateTransition] = React.useTransition()

  const form = useForm<CreateNewRevisionSchema>({
    resolver: zodResolver(createNewRevisionSchema),
    defaultValues: {
      editReason: "",
    },
  })

  // 다이얼로그가 열릴 때마다 폼 초기화
  React.useEffect(() => {
    if (open && originalDocument) {
      form.reset({
        editReason: "",
      })
    }
  }, [open, originalDocument, form])

  async function onSubmit(data: CreateNewRevisionSchema) {
    if (!originalDocument) {
      toast.error("원본 문서 정보가 없습니다.")
      return
    }

    startCreateTransition(async () => {
      try {
        const result = await createNewRevision(originalDocument.id, data)
        
        if (result.error) {
          toast.error(`에러: ${result.error}`)
          return
        }

        form.reset()
        onOpenChange(false)
        toast.success(`새 리비전 v${result.revision}이 생성되었습니다.`)
      } catch (error) {
        toast.error("리비전 생성 중 오류가 발생했습니다.")
      }
    })
  }

  function handleDialogOpenChange(nextOpen: boolean) {
    if (!nextOpen) {
      form.reset()
    }
    onOpenChange(nextOpen)
  }

  if (!originalDocument) return null

  return (
    <Dialog open={open} onOpenChange={handleDialogOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>Create New Revision</DialogTitle>
          <DialogDescription>
            기존 문서의 새로운 리비전을 생성합니다.
          </DialogDescription>
        </DialogHeader>

        {/* 원본 문서 정보 표시 */}
        <div className="space-y-2 p-3 bg-muted/50 rounded-lg">
          <div className="text-sm font-medium">원본 문서 정보</div>
          <div className="text-xs text-muted-foreground space-y-1">
            <div>구분: {originalDocument.type === "standard" ? "표준" : "프로젝트"}</div>
            {originalDocument.project && (
              <div>프로젝트: {originalDocument.project.name} ({originalDocument.project.code})</div>
            )}
            <div>현재 리비전: v{originalDocument.revision}</div>
          </div>
        </div>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)}>
            <div className="space-y-4 py-4">
              {/* 편집 사유 (필수) */}
              <FormField
                control={form.control}
                name="editReason"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>편집 사유 *</FormLabel>
                    <FormControl>
                      <Textarea
                        placeholder="새 리비전 생성 사유를 입력하세요..."
                        {...field}
                        rows={3}
                        required
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <DialogFooter>
              <Button
                type="button"
                variant="outline"
                onClick={() => onOpenChange(false)}
                disabled={isCreatePending}
              >
                Cancel
              </Button>
              <Button type="submit" disabled={isCreatePending}>
                {isCreatePending && (
                  <Loader
                    className="mr-2 size-4 animate-spin"
                    aria-hidden="true"
                  />
                )}
                Create Revision
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  )
}