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

252 lines
8.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}