ERP-node/frontend/components/barcode/designer/BarcodeDesignerRightPanel.tsx

252 lines
8.1 KiB
TypeScript
Raw Normal View History

2026-03-04 20:51:00 +09:00
"use client";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Trash2 } from "lucide-react";
import { useBarcodeDesigner } from "@/contexts/BarcodeDesignerContext";
import { BarcodeLabelComponent } from "@/types/barcode";
export function BarcodeDesignerRightPanel() {
const {
components,
selectedComponentId,
updateComponent,
removeComponent,
selectComponent,
widthMm,
heightMm,
setWidthMm,
setHeightMm,
} = useBarcodeDesigner();
const selected = components.find((c) => c.id === selectedComponentId);
if (!selected) {
return (
<div className="w-72 border-l bg-white p-4">
<p className="text-muted-foreground text-sm"> .</p>
<div className="mt-4 space-y-2">
<Label className="text-xs"> (mm)</Label>
<div className="flex gap-2">
<Input
type="number"
min={10}
max={200}
value={widthMm}
onChange={(e) => setWidthMm(Number(e.target.value) || 50)}
/>
<span className="py-2">×</span>
<Input
type="number"
min={10}
max={200}
value={heightMm}
onChange={(e) => setHeightMm(Number(e.target.value) || 30)}
/>
</div>
</div>
</div>
);
}
const update = (updates: Partial<BarcodeLabelComponent>) =>
updateComponent(selected.id, updates);
return (
<div className="w-72 border-l bg-white">
<div className="border-b p-2 flex items-center justify-between">
<span className="text-sm font-medium"></span>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-destructive"
onClick={() => {
removeComponent(selected.id);
selectComponent(null);
}}
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
<div className="space-y-4 p-4">
<div className="grid grid-cols-2 gap-2">
<div>
<Label className="text-xs">X (px)</Label>
<Input
type="number"
value={Math.round(selected.x)}
onChange={(e) => update({ x: Number(e.target.value) || 0 })}
/>
</div>
<div>
<Label className="text-xs">Y (px)</Label>
<Input
type="number"
value={Math.round(selected.y)}
onChange={(e) => update({ y: Number(e.target.value) || 0 })}
/>
</div>
<div>
<Label className="text-xs"></Label>
<Input
type="number"
min={4}
value={Math.round(selected.width)}
onChange={(e) => update({ width: Number(e.target.value) || 10 })}
/>
</div>
<div>
<Label className="text-xs"></Label>
<Input
type="number"
min={4}
value={Math.round(selected.height)}
onChange={(e) => update({ height: Number(e.target.value) || 10 })}
/>
</div>
</div>
{selected.type === "text" && (
<>
<div>
<Label className="text-xs"></Label>
<Input
value={selected.content || ""}
onChange={(e) => update({ content: e.target.value })}
placeholder="텍스트"
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={6}
max={72}
value={selected.fontSize || 10}
onChange={(e) => update({ fontSize: Number(e.target.value) || 10 })}
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="color"
value={selected.fontColor || "#000000"}
onChange={(e) => update({ fontColor: e.target.value })}
className="h-9 w-20 p-1"
/>
</div>
</>
)}
{selected.type === "barcode" && (
<>
<div>
<Label className="text-xs"> </Label>
<Select
value={selected.barcodeType || "CODE128"}
onValueChange={(v) => update({ barcodeType: v })}
>
<SelectTrigger className="h-9">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="CODE128">CODE128</SelectItem>
<SelectItem value="CODE39">CODE39</SelectItem>
<SelectItem value="EAN13">EAN13</SelectItem>
<SelectItem value="EAN8">EAN8</SelectItem>
<SelectItem value="QR">QR </SelectItem>
</SelectContent>
</Select>
</div>
<div>
<Label className="text-xs"></Label>
<Input
value={selected.barcodeValue || ""}
onChange={(e) => update({ barcodeValue: e.target.value })}
placeholder="123456789"
/>
</div>
<div className="flex items-center gap-2">
<Switch
checked={selected.showBarcodeText !== false}
onCheckedChange={(v) => update({ showBarcodeText: v })}
/>
<Label className="text-xs"> (1D)</Label>
</div>
</>
)}
{selected.type === "line" && (
<>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={1}
value={selected.lineWidth || 1}
onChange={(e) => update({ lineWidth: Number(e.target.value) || 1 })}
/>
</div>
<div>
<Label className="text-xs"></Label>
<Input
type="color"
value={selected.lineColor || "#000000"}
onChange={(e) => update({ lineColor: e.target.value })}
className="h-9 w-20 p-1"
/>
</div>
</>
)}
{selected.type === "rectangle" && (
<>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={0}
value={selected.lineWidth ?? 1}
onChange={(e) => update({ lineWidth: Number(e.target.value) || 0 })}
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="color"
value={selected.lineColor || "#000000"}
onChange={(e) => update({ lineColor: e.target.value })}
className="h-9 w-20 p-1"
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="color"
value={selected.backgroundColor || "#ffffff"}
onChange={(e) => update({ backgroundColor: e.target.value })}
className="h-9 w-20 p-1"
/>
</div>
</>
)}
{selected.type === "image" && (
<div>
<Label className="text-xs"> URL</Label>
<Input
value={selected.imageUrl || ""}
onChange={(e) => update({ imageUrl: e.target.value })}
placeholder="https://..."
/>
<p className="text-muted-foreground mt-1 text-xs"> </p>
</div>
)}
</div>
</div>
);
}