summaryrefslogtreecommitdiff
path: root/lib/rfq-last/vendor-response/participation-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last/vendor-response/participation-dialog.tsx')
-rw-r--r--lib/rfq-last/vendor-response/participation-dialog.tsx230
1 files changed, 230 insertions, 0 deletions
diff --git a/lib/rfq-last/vendor-response/participation-dialog.tsx b/lib/rfq-last/vendor-response/participation-dialog.tsx
new file mode 100644
index 00000000..a7337ac2
--- /dev/null
+++ b/lib/rfq-last/vendor-response/participation-dialog.tsx
@@ -0,0 +1,230 @@
+// components/vendor/participation-dialog.tsx
+
+"use client"
+
+import * as React from "react"
+import { useRouter } from "next/navigation"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
+import { Textarea } from "@/components/ui/textarea"
+import { Label } from "@/components/ui/label"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "@/components/ui/alert-dialog"
+import { useToast } from "@/hooks/use-toast"
+import { updateParticipationStatus } from "@/lib/rfq-last/vendor-response/service"
+import { CheckCircle, XCircle } from "lucide-react"
+
+interface ParticipationDialogProps {
+ rfqId: number
+ rfqCode: string
+ rfqLastDetailsId: number
+ currentStatus?: string
+ onClose: () => void
+}
+
+export function ParticipationDialog({
+ rfqId,
+ rfqCode,
+ rfqLastDetailsId,
+ currentStatus,
+ onClose,
+}: ParticipationDialogProps) {
+ const router = useRouter()
+ const [showDeclineDialog, setShowDeclineDialog] = React.useState(false)
+ const [showConfirmDialog, setShowConfirmDialog] = React.useState(false)
+ const [declineReason, setDeclineReason] = React.useState("")
+ const [isLoading, setIsLoading] = React.useState(false)
+ const { toast } = useToast();
+
+ const handleParticipate = () => {
+ setShowConfirmDialog(true)
+ }
+
+ const handleDecline = () => {
+ setShowDeclineDialog(true)
+ }
+
+ const confirmParticipation = async () => {
+ setIsLoading(true)
+ try {
+ const result = await updateParticipationStatus({
+ rfqId,
+ rfqLastDetailsId,
+ participationStatus: "참여",
+ })
+
+ if (result.success) {
+ toast({
+ title: "참여 확정",
+ description: result.message,
+ })
+ // router.push(`/partners/rfq-last/${rfqId}`)
+ router.refresh()
+ } else {
+ toast({
+ title: "오류",
+ description: result.message,
+ variant: "destructive",
+ })
+ }
+ } catch (error) {
+ toast({
+ title: "오류",
+ description: "참여 처리 중 오류가 발생했습니다.",
+ variant: "destructive",
+ })
+ } finally {
+ setIsLoading(false)
+ onClose()
+ }
+ }
+
+ const confirmDecline = async () => {
+ if (!declineReason.trim()) {
+ toast({
+ title: "불참 사유 필요",
+ description: "불참 사유를 입력해주세요.",
+ variant: "destructive",
+ })
+ return
+ }
+
+ setIsLoading(true)
+ try {
+ const result = await updateParticipationStatus({
+ rfqId,
+ rfqLastDetailsId,
+ participationStatus: "불참",
+ nonParticipationReason: declineReason,
+ })
+
+ if (result.success) {
+ toast({
+ title: "불참 처리 완료",
+ description: result.message,
+ })
+ router.refresh()
+ } else {
+ toast({
+ title: "오류",
+ description: result.message,
+ variant: "destructive",
+ })
+ }
+ } catch (error) {
+ toast({
+ title: "오류",
+ description: "불참 처리 중 오류가 발생했습니다.",
+ variant: "destructive",
+ })
+ } finally {
+ setIsLoading(false)
+ onClose()
+ }
+ }
+
+ return (
+ <>
+ {/* 메인 다이얼로그 */}
+ <AlertDialog open={true} onOpenChange={onClose}>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>견적 참여 여부 결정</AlertDialogTitle>
+ <AlertDialogDescription>
+ {rfqCode} 견적 요청에 참여하시겠습니까?
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel>취소</AlertDialogCancel>
+ <Button
+ variant="outline"
+ onClick={handleDecline}
+ disabled={isLoading}
+ >
+ <XCircle className="mr-2 h-4 w-4" />
+ 불참
+ </Button>
+ <Button
+ onClick={handleParticipate}
+ disabled={isLoading}
+ >
+ <CheckCircle className="mr-2 h-4 w-4" />
+ 참여
+ </Button>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+
+ {/* 참여 확인 다이얼로그 */}
+ <AlertDialog open={showConfirmDialog} onOpenChange={setShowConfirmDialog}>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>견적 참여 확정</AlertDialogTitle>
+ <AlertDialogDescription>
+ 견적 참여를 확정하시면 견적서 작성 페이지로 이동합니다.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel>취소</AlertDialogCancel>
+ <AlertDialogAction onClick={confirmParticipation}>
+ 확정
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+
+ {/* 불참 사유 입력 다이얼로그 */}
+ <Dialog open={showDeclineDialog} onOpenChange={setShowDeclineDialog}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>견적 불참</DialogTitle>
+ <DialogDescription>
+ 불참 사유를 입력해주세요.
+ </DialogDescription>
+ </DialogHeader>
+ <div className="grid gap-4 py-4">
+ <div className="grid gap-2">
+ <Label htmlFor="reason">불참 사유</Label>
+ <Textarea
+ id="reason"
+ placeholder="불참 사유를 입력하세요..."
+ value={declineReason}
+ onChange={(e) => setDeclineReason(e.target.value)}
+ rows={4}
+ />
+ </div>
+ </div>
+ <DialogFooter>
+ <Button
+ variant="outline"
+ onClick={() => setShowDeclineDialog(false)}
+ >
+ 취소
+ </Button>
+ <Button
+ onClick={confirmDecline}
+ disabled={isLoading || !declineReason.trim()}
+ >
+ 불참 확정
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ </>
+ )
+} \ No newline at end of file