163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||
|
|
import { Input } from "@/components/ui/input";
|
||
|
|
import { Label } from "@/components/ui/label";
|
||
|
|
import { Button } from "@/components/ui/button";
|
||
|
|
import { Trash2 } from "lucide-react";
|
||
|
|
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
|
||
|
|
|
||
|
|
export function ReportDesignerRightPanel() {
|
||
|
|
const { selectedComponentId, components, updateComponent, removeComponent } = useReportDesigner();
|
||
|
|
|
||
|
|
const selectedComponent = components.find((c) => c.id === selectedComponentId);
|
||
|
|
|
||
|
|
if (!selectedComponent) {
|
||
|
|
return (
|
||
|
|
<div className="w-80 border-l bg-white">
|
||
|
|
<div className="flex h-full items-center justify-center p-4 text-center text-sm text-gray-500">
|
||
|
|
컴포넌트를 선택하면 속성을 편집할 수 있습니다
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="w-80 border-l bg-white">
|
||
|
|
<ScrollArea className="h-full">
|
||
|
|
<div className="space-y-4 p-4">
|
||
|
|
{/* 컴포넌트 정보 */}
|
||
|
|
<Card>
|
||
|
|
<CardHeader className="pb-3">
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<CardTitle className="text-sm">컴포넌트 속성</CardTitle>
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
size="sm"
|
||
|
|
onClick={() => removeComponent(selectedComponent.id)}
|
||
|
|
className="text-destructive hover:bg-destructive/10 h-8 w-8 p-0"
|
||
|
|
>
|
||
|
|
<Trash2 className="h-4 w-4" />
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent className="space-y-3">
|
||
|
|
{/* 타입 */}
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">타입</Label>
|
||
|
|
<div className="mt-1 text-sm font-medium capitalize">{selectedComponent.type}</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 위치 */}
|
||
|
|
<div className="grid grid-cols-2 gap-2">
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">X</Label>
|
||
|
|
<Input
|
||
|
|
type="number"
|
||
|
|
value={Math.round(selectedComponent.x)}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
x: parseInt(e.target.value) || 0,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">Y</Label>
|
||
|
|
<Input
|
||
|
|
type="number"
|
||
|
|
value={Math.round(selectedComponent.y)}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
y: parseInt(e.target.value) || 0,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 크기 */}
|
||
|
|
<div className="grid grid-cols-2 gap-2">
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">너비</Label>
|
||
|
|
<Input
|
||
|
|
type="number"
|
||
|
|
value={Math.round(selectedComponent.width)}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
width: parseInt(e.target.value) || 50,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">높이</Label>
|
||
|
|
<Input
|
||
|
|
type="number"
|
||
|
|
value={Math.round(selectedComponent.height)}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
height: parseInt(e.target.value) || 30,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 글꼴 크기 */}
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">글꼴 크기</Label>
|
||
|
|
<Input
|
||
|
|
type="number"
|
||
|
|
value={selectedComponent.fontSize || 13}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
fontSize: parseInt(e.target.value) || 13,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 글꼴 색상 */}
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">글꼴 색상</Label>
|
||
|
|
<Input
|
||
|
|
type="color"
|
||
|
|
value={selectedComponent.fontColor || "#000000"}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
fontColor: e.target.value,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 배경 색상 */}
|
||
|
|
<div>
|
||
|
|
<Label className="text-xs">배경 색상</Label>
|
||
|
|
<Input
|
||
|
|
type="color"
|
||
|
|
value={selectedComponent.backgroundColor || "#ffffff"}
|
||
|
|
onChange={(e) =>
|
||
|
|
updateComponent(selectedComponent.id, {
|
||
|
|
backgroundColor: e.target.value,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
className="h-8"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
</ScrollArea>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|