diff options
Diffstat (limited to 'lib/tag-numbering/table/meta-sheet.tsx')
| -rw-r--r-- | lib/tag-numbering/table/meta-sheet.tsx | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/lib/tag-numbering/table/meta-sheet.tsx b/lib/tag-numbering/table/meta-sheet.tsx new file mode 100644 index 00000000..4221837c --- /dev/null +++ b/lib/tag-numbering/table/meta-sheet.tsx @@ -0,0 +1,226 @@ +"use client" + +import * as React from "react" +import { useEffect, useState } from "react" +import { Copy } from "lucide-react" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle +} from "@/components/ui/sheet" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow +} from "@/components/ui/table" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, + CardFooter +} from "@/components/ui/card" +import { Separator } from "@/components/ui/separator" +import { ViewTagSubfields } from "@/db/schema/vendorData" +import { fetchTagSubfieldOptions } from "../service" + +interface TagOption { + id: number + attributesId: string + code: string + label: string + createdAt?: Date + updatedAt?: Date +} + +interface ViewTagOptionsProps { + open: boolean + onOpenChange: (open: boolean) => void + tagSubfield: ViewTagSubfields | null +} + +export function ViewTagOptions({ + open, + onOpenChange, + tagSubfield +}: ViewTagOptionsProps) { + const [options, setOptions] = useState<TagOption[]>([]) + const [loading, setLoading] = useState(false) + const [copied, setCopied] = useState<string | null>(null) + + // 옵션 데이터 가져오기 + useEffect(() => { + async function fetchOptions() { + if (!tagSubfield || !open) return + + setLoading(true) + try { + // 서버 액션 호출 - attributesId와 일치하는 모든 옵션 가져오기 + const optionsData = await fetchTagSubfieldOptions(tagSubfield.attributesId) + setOptions(optionsData || []) + } catch (error) { + console.error("Error fetching tag options:", error) + setOptions([]) + } finally { + setLoading(false) + } + } + + fetchOptions() + }, [tagSubfield, open]) + + // 코드 복사 기능 + const copyToClipboard = (text: string, type: string) => { + navigator.clipboard.writeText(text).then(() => { + setCopied(type) + setTimeout(() => setCopied(null), 2000) + }) + } + + if (!tagSubfield) return null + + return ( + <Sheet open={open} onOpenChange={onOpenChange}> + <SheetContent className="sm:max-w-xl md:max-w-3xl lg:max-w-4xl xl:max-w-5xl overflow-y-auto"> + + <SheetHeader className="mb-6"> + <SheetTitle className="text-xl flex items-center gap-2"> + Field Options + <Badge variant="outline" className="ml-2"> + {options.length} options + </Badge> + </SheetTitle> + <SheetDescription className="mb-4"> + Field information and available options + </SheetDescription> + + <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4"> + <div className="space-y-2"> + <div className="flex items-center justify-between"> + <span className="text-sm font-medium">Attributes ID:</span> + <div className="flex items-center gap-1"> + <Badge variant="secondary"> + {tagSubfield.attributesId} + </Badge> + <Button + variant="ghost" + size="icon" + className="h-6 w-6" + onClick={() => copyToClipboard(tagSubfield.attributesId, 'attributesId')} + > + <Copy className="h-3 w-3" /> + </Button> + {copied === 'attributesId' && ( + <span className="text-xs text-green-600">Copied</span> + )} + </div> + </div> + <div className="flex items-center justify-between"> + <span className="text-sm font-medium">Tag Type:</span> + <Badge>{tagSubfield.tagTypeCode}</Badge> + </div> + </div> + <div className="space-y-2"> + <div className="flex items-center justify-between"> + <span className="text-sm font-medium">Description:</span> + <span className="text-sm">{tagSubfield.attributesDescription}</span> + </div> + <div className="flex items-center justify-between"> + <span className="text-sm font-medium">Expression:</span> + <code className="bg-muted px-2 py-1 rounded text-xs"> + {tagSubfield.expression || 'N/A'} + </code> + </div> + </div> + </div> + {tagSubfield.tagTypeDescription && ( + <div className="mt-4 text-sm bg-muted p-2 rounded"> + <span className="font-medium">Type Description: </span> + {tagSubfield.tagTypeDescription} + </div> + )} + + </SheetHeader> + + <Separator className="my-4" /> + + {loading ? ( + <div className="flex items-center justify-center h-40"> + <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div> + </div> + ) : options.length > 0 ? ( + <Card> + <CardHeader> + <CardTitle>Available Options</CardTitle> + <CardDescription> + All available options for field {tagSubfield.attributesId} + </CardDescription> + </CardHeader> + <CardContent> + <Table> + <TableHeader> + <TableRow> + <TableHead className="w-24">Code</TableHead> + <TableHead>Label</TableHead> + <TableHead className="text-right">Actions</TableHead> + </TableRow> + </TableHeader> + <TableBody> + {options.map((option) => ( + <TableRow key={option.id}> + <TableCell className="font-mono"> + {option.code} + </TableCell> + <TableCell>{option.label}</TableCell> + <TableCell className="text-right"> + <Button + variant="ghost" + size="sm" + className="h-8 w-8 p-0" + onClick={() => copyToClipboard(`${option.code} - ${option.label}`, `option-${option.id}`)} + > + <Copy className="h-4 w-4" /> + {copied === `option-${option.id}` && ( + <span className="absolute -top-2 -right-2 text-xs text-green-600 bg-white px-1 rounded-sm"> + Copied + </span> + )} + </Button> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> + </CardContent> + <CardFooter className="flex justify-between text-sm text-muted-foreground"> + <div> + {options.length} options found for {tagSubfield.attributesId} + </div> + {tagSubfield.delimiter && ( + <div> + Delimiter: <code className="bg-muted px-2 py-1 rounded text-xs">{tagSubfield.delimiter}</code> + </div> + )} + </CardFooter> + </Card> + ) : ( + <div className="text-center py-8"> + <div className="text-lg font-medium">No options found</div> + <p className="text-muted-foreground mt-2"> + This field ({tagSubfield.attributesId}) has no defined options. + </p> + </div> + )} + + </SheetContent> + </Sheet> + ) +}
\ No newline at end of file |
