ERP-node/frontend/components/screen/panels/GridPanel.tsx

197 lines
6.7 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 React from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { Slider } from "@/components/ui/slider";
import { Grid3X3, RotateCcw, Eye, EyeOff, Zap } from "lucide-react";
import { GridSettings, ScreenResolution } from "@/types/screen";
interface GridPanelProps {
gridSettings: GridSettings;
onGridSettingsChange: (settings: GridSettings) => void;
onResetGrid: () => void;
screenResolution?: ScreenResolution;
}
export const GridPanel: React.FC<GridPanelProps> = ({
gridSettings,
onGridSettingsChange,
onResetGrid,
screenResolution,
}) => {
const updateSetting = (key: keyof GridSettings, value: any) => {
onGridSettingsChange({
...gridSettings,
[key]: value,
});
};
return (
<div className="flex h-full flex-col">
{/* 헤더 */}
<div className="border-b p-4">
<div className="mb-3 flex items-center justify-between">
<div className="flex items-center gap-2">
<Grid3X3 className="text-muted-foreground h-4 w-4" />
<h3 className="text-sm font-semibold"> </h3>
</div>
<Button size="sm" variant="outline" onClick={onResetGrid} className="h-7 px-2 text-xs">
<RotateCcw className="mr-1 h-3 w-3" />
</Button>
</div>
{/* 주요 토글들 */}
<div className="space-y-2.5">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{gridSettings.showGrid ? (
<Eye className="text-primary h-3.5 w-3.5" />
) : (
<EyeOff className="text-muted-foreground h-3.5 w-3.5" />
)}
<Label htmlFor="showGrid" className="text-xs font-medium">
</Label>
</div>
<Checkbox
id="showGrid"
checked={gridSettings.showGrid}
onCheckedChange={(checked) => updateSetting("showGrid", checked)}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Zap className="text-primary h-3.5 w-3.5" />
<Label htmlFor="snapToGrid" className="text-xs font-medium">
</Label>
</div>
<Checkbox
id="snapToGrid"
checked={gridSettings.snapToGrid}
onCheckedChange={(checked) => updateSetting("snapToGrid", checked)}
/>
</div>
</div>
</div>
{/* 설정 영역 */}
<div className="flex-1 space-y-4 overflow-y-auto p-4">
{/* 10px 단위 스냅 안내 */}
<div className="space-y-3">
<h4 className="text-xs font-semibold"> </h4>
<div className="bg-muted/50 rounded-md p-3">
<p className="text-xs text-muted-foreground">
10px .
</p>
</div>
</div>
<Separator />
{/* 격자 스타일 */}
<div className="space-y-4">
<h4 className="text-xs font-semibold"> </h4>
<div>
<Label htmlFor="gridColor" className="text-xs font-medium">
</Label>
<div className="mt-1 flex items-center space-x-2">
<Input
id="gridColor"
type="color"
value={gridSettings.gridColor || "#d1d5db"}
onChange={(e) => updateSetting("gridColor", e.target.value)}
className="h-8 w-12 rounded border p-1"
/>
<Input
type="text"
value={gridSettings.gridColor || "#d1d5db"}
onChange={(e) => updateSetting("gridColor", e.target.value)}
placeholder="#d1d5db"
className="flex-1 text-xs"
/>
</div>
</div>
<div>
<Label htmlFor="gridOpacity" className="mb-2 block text-xs font-medium">
: {Math.round((gridSettings.gridOpacity || 0.5) * 100)}%
</Label>
<Slider
id="gridOpacity"
min={0.1}
max={1}
step={0.1}
value={[gridSettings.gridOpacity || 0.5]}
onValueChange={([value]) => updateSetting("gridOpacity", value)}
className="w-full"
/>
<div className="mt-1 flex justify-between text-xs text-muted-foreground">
<span>10%</span>
<span>100%</span>
</div>
</div>
</div>
<Separator />
{/* 미리보기 */}
<div className="space-y-3">
<h4 className="text-xs font-semibold"></h4>
<div
className="rounded-md border bg-white p-4"
style={{
backgroundImage: gridSettings.showGrid
? `linear-gradient(to right, ${gridSettings.gridColor || "#d1d5db"} 1px, transparent 1px),
linear-gradient(to bottom, ${gridSettings.gridColor || "#d1d5db"} 1px, transparent 1px)`
: "none",
backgroundSize: gridSettings.showGrid ? "10px 10px" : "none",
opacity: gridSettings.gridOpacity || 0.5,
}}
>
<div className="bg-primary/20 flex h-16 items-center justify-center rounded border-2 border-dashed border-blue-300">
<span className="text-primary text-xs">10px </span>
</div>
</div>
</div>
</div>
{/* 푸터 */}
<div className="border-t bg-muted/30 p-3">
{screenResolution && (
<div className="space-y-2">
<h4 className="text-xs font-semibold"> </h4>
<div className="space-y-2 text-xs">
<div className="flex justify-between">
<span className="text-muted-foreground">:</span>
<span className="font-mono">
{screenResolution.width} × {screenResolution.height}
</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground"> :</span>
<span className="font-mono text-primary">10px</span>
</div>
</div>
</div>
)}
</div>
</div>
);
};
export default GridPanel;