diff options
Diffstat (limited to 'lib/shi-signature/signature-list.tsx')
| -rw-r--r-- | lib/shi-signature/signature-list.tsx | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/shi-signature/signature-list.tsx b/lib/shi-signature/signature-list.tsx new file mode 100644 index 00000000..93cd3dbe --- /dev/null +++ b/lib/shi-signature/signature-list.tsx @@ -0,0 +1,149 @@ +'use client'; + +import { useState } from 'react'; +import { BuyerSignature } from '@/db/schemae'; +import { setActiveSignature, deleteSignature } from './buyer-signature'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; +import { Badge } from '@/components/ui/badge'; +import { Trash2, CheckCircle, Circle,Loader2 } from 'lucide-react'; +import { toast } from 'sonner'; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from '@/components/ui/alert-dialog'; + +interface SignatureListProps { + signatures: BuyerSignature[]; +} + +export function SignatureList({ signatures }: SignatureListProps) { + const [isUpdating, setIsUpdating] = useState<number | null>(null); + + const handleSetActive = async (id: number) => { + setIsUpdating(id); + try { + const result = await setActiveSignature(id); + if (result.success) { + toast.success('활성 서명이 변경되었습니다.'); + } else { + toast.error(result.error || '변경에 실패했습니다.'); + } + } catch (error) { + toast.error('오류가 발생했습니다.'); + } finally { + setIsUpdating(null); + } + }; + + const handleDelete = async (id: number) => { + try { + const result = await deleteSignature(id); + if (result.success) { + toast.success('서명이 삭제되었습니다.'); + } else { + toast.error(result.error || '삭제에 실패했습니다.'); + } + } catch (error) { + toast.error('오류가 발생했습니다.'); + } + }; + + if (signatures.length === 0) { + return ( + <Card> + <CardContent className="py-8 text-center text-muted-foreground"> + 아직 업로드된 서명이 없습니다. + </CardContent> + </Card> + ); + } + + return ( + <Card> + <CardHeader> + <CardTitle>서명 목록</CardTitle> + </CardHeader> + <CardContent className="space-y-4"> + {signatures.map((signature) => ( + <div + key={signature.id} + className="flex items-center justify-between p-4 border rounded-lg" + > + <div className="flex items-center space-x-4"> + <img + src={signature.imageUrl} + alt="서명" + className="h-12 object-contain border rounded p-1" + /> + <div> + <div className="flex items-center space-x-2"> + <span className="font-medium">{signature.name}</span> + {signature.isActive && ( + <Badge variant="default" className="text-xs"> + 활성 + </Badge> + )} + </div> + <p className="text-sm text-muted-foreground"> + {new Date(signature.createdAt).toLocaleDateString()} + </p> + </div> + </div> + + <div className="flex items-center space-x-2"> + {!signature.isActive && ( + <Button + variant="outline" + size="sm" + onClick={() => handleSetActive(signature.id)} + disabled={isUpdating === signature.id} + > + {isUpdating === signature.id ? ( + <Loader2 className="h-4 w-4 animate-spin" /> + ) : ( + <Circle className="h-4 w-4" /> + )} + <span className="ml-2">활성화</span> + </Button> + )} + + <AlertDialog> + <AlertDialogTrigger asChild> + <Button + variant="outline" + size="sm" + disabled={signature.isActive} + > + <Trash2 className="h-4 w-4" /> + </Button> + </AlertDialogTrigger> + <AlertDialogContent> + <AlertDialogHeader> + <AlertDialogTitle>서명 삭제</AlertDialogTitle> + <AlertDialogDescription> + 이 서명을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다. + </AlertDialogDescription> + </AlertDialogHeader> + <AlertDialogFooter> + <AlertDialogCancel>취소</AlertDialogCancel> + <AlertDialogAction onClick={() => handleDelete(signature.id)}> + 삭제 + </AlertDialogAction> + </AlertDialogFooter> + </AlertDialogContent> + </AlertDialog> + </div> + </div> + ))} + </CardContent> + </Card> + ); +}
\ No newline at end of file |
