refactor: 전체 프론트엔드 하드코딩 색상 → CSS 변수 일괄 치환

447+ 파일, 4500+ 줄 변경:
- gray-* → border/bg-muted/text-foreground/text-muted-foreground
- blue-* → primary/ring
- red-* → destructive
- green-* → emerald (일관성)
- indigo-* → primary
- yellow/orange → amber (통일)
- dark mode 변형도 시맨틱 토큰으로 변환

Made-with: Cursor
This commit is contained in:
DDD1542
2026-03-09 14:31:59 +09:00
parent d967cf0a0d
commit 4f10b5e42d
447 changed files with 4520 additions and 4520 deletions

View File

@@ -250,16 +250,16 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
<AccordionItem
key={tab.tabId}
value={tab.tabId}
className="rounded-lg border bg-gray-50"
className="rounded-lg border bg-muted"
>
<AccordionTrigger className="px-3 py-2 hover:no-underline">
<div className="flex flex-1 items-center gap-2">
<GripVertical className="h-4 w-4 text-gray-400" />
<GripVertical className="h-4 w-4 text-muted-foreground/70" />
<span className="text-sm font-medium">
{tab.label || `${tabIndex + 1}`}
</span>
{tab.tableName && (
<span className="text-xs text-gray-500">({tab.tableName})</span>
<span className="text-xs text-muted-foreground">({tab.tableName})</span>
)}
</div>
</AccordionTrigger>
@@ -267,7 +267,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
<div className="space-y-4">
{/* ===== 1. 기본 정보 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1">
<Label className="text-xs"> </Label>
@@ -302,7 +302,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 2. 테이블 선택 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<div className="space-y-1">
<Label className="text-xs"> </Label>
<Popover>
@@ -345,7 +345,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 3. 표시 모드 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<div className="space-y-1">
<Label className="text-xs"> </Label>
<Select
@@ -390,8 +390,8 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 4. 컬럼 매핑 (연결 키) ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> ( )</Label>
<p className="text-[10px] text-gray-500">
<Label className="text-xs font-semibold text-primary"> ( )</Label>
<p className="text-[10px] text-muted-foreground">
</p>
<div className="mt-2 grid grid-cols-2 gap-2">
@@ -472,7 +472,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 5. 기능 버튼 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<div className="grid grid-cols-4 gap-2">
<div className="flex items-center gap-1">
<Checkbox
@@ -510,9 +510,9 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
</div>
{/* ===== 6. 표시 컬럼 설정 ===== */}
<div className="space-y-3 rounded-lg border border-green-200 bg-green-50 p-3">
<div className="space-y-3 rounded-lg border border-emerald-200 bg-emerald-50 p-3">
<div className="flex items-center justify-between">
<Label className="text-xs font-semibold text-green-700"> </Label>
<Label className="text-xs font-semibold text-emerald-700"> </Label>
<Button
size="sm"
variant="outline"
@@ -528,14 +528,14 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
</Button>
</div>
<p className="text-[10px] text-gray-600">
<p className="text-[10px] text-muted-foreground">
. .
</p>
{/* 테이블 미선택 상태 */}
{!tab.tableName && (
<div className="rounded-md border border-dashed border-gray-300 bg-white p-3 text-center">
<p className="text-xs text-gray-500"> </p>
<div className="rounded-md border border-dashed border-input bg-white p-3 text-center">
<p className="text-xs text-muted-foreground"> </p>
</div>
)}
@@ -544,16 +544,16 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
<div className="space-y-2">
{/* 로딩 상태 */}
{loadingTabColumns && (
<div className="rounded-md border border-dashed border-gray-300 bg-white p-3 text-center">
<p className="text-xs text-gray-500"> ...</p>
<div className="rounded-md border border-dashed border-input bg-white p-3 text-center">
<p className="text-xs text-muted-foreground"> ...</p>
</div>
)}
{/* 설정된 컬럼이 없을 때 */}
{!loadingTabColumns && (tab.columns || []).length === 0 && (
<div className="rounded-md border border-dashed border-gray-300 bg-white p-3 text-center">
<p className="text-xs text-gray-500"> </p>
<p className="mt-1 text-[10px] text-gray-400"> </p>
<div className="rounded-md border border-dashed border-input bg-white p-3 text-center">
<p className="text-xs text-muted-foreground"> </p>
<p className="mt-1 text-[10px] text-muted-foreground/70"> </p>
</div>
)}
@@ -593,7 +593,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
>
<ArrowDown className="h-3 w-3" />
</Button>
<span className="text-[10px] text-gray-400">#{colIndex + 1}</span>
<span className="text-[10px] text-muted-foreground/70">#{colIndex + 1}</span>
</div>
<Button
size="sm"
@@ -602,7 +602,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
const newColumns = (tab.columns || []).filter((_, i) => i !== colIndex);
updateTab({ columns: newColumns });
}}
className="h-6 w-6 p-0 text-red-500 hover:bg-red-50 hover:text-red-600"
className="h-6 w-6 p-0 text-destructive hover:bg-destructive/10 hover:text-destructive"
>
<X className="h-3 w-3" />
</Button>
@@ -610,7 +610,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* 컬럼 선택 */}
<div className="space-y-1">
<Label className="text-[10px] text-gray-500"></Label>
<Label className="text-[10px] text-muted-foreground"></Label>
<Select
value={col.name}
onValueChange={(value) => {
@@ -631,7 +631,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{tabColumns.map((column) => (
<SelectItem key={column.columnName} value={column.columnName}>
{column.columnLabel || column.columnName}
<span className="ml-1 text-[10px] text-gray-400">({column.columnName})</span>
<span className="ml-1 text-[10px] text-muted-foreground/70">({column.columnName})</span>
</SelectItem>
))}
</SelectContent>
@@ -641,7 +641,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* 라벨 + 너비 */}
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label className="text-[10px] text-gray-500"></Label>
<Label className="text-[10px] text-muted-foreground"></Label>
<Input
value={col.label}
onChange={(e) => {
@@ -654,7 +654,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
/>
</div>
<div className="space-y-1">
<Label className="text-[10px] text-gray-500"> (px)</Label>
<Label className="text-[10px] text-muted-foreground"> (px)</Label>
<Input
type="number"
value={col.width || 100}
@@ -698,8 +698,8 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
<div className="space-y-2">
{(tab.addModalColumns || []).length === 0 ? (
<div className="rounded-md border border-dashed border-gray-300 bg-white p-3 text-center">
<p className="text-xs text-gray-500"> </p>
<div className="rounded-md border border-dashed border-input bg-white p-3 text-center">
<p className="text-xs text-muted-foreground"> </p>
</div>
) : (
(tab.addModalColumns || []).map((col, colIndex) => (
@@ -756,7 +756,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
const newColumns = (tab.addModalColumns || []).filter((_, i) => i !== colIndex);
updateTab({ addModalColumns: newColumns });
}}
className="h-8 w-8 p-0 text-red-500"
className="h-8 w-8 p-0 text-destructive"
>
<X className="h-3 w-3" />
</Button>
@@ -769,7 +769,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 8. 데이터 필터링 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<DataFilterConfigPanel
tableName={tab.tableName}
columns={tabColumns}
@@ -782,7 +782,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 9. 중복 데이터 제거 ===== */}
<div className="space-y-3 rounded-lg border bg-white p-3">
<div className="flex items-center justify-between">
<Label className="text-xs font-semibold text-blue-600"> </Label>
<Label className="text-xs font-semibold text-primary"> </Label>
<Switch
checked={tab.deduplication?.enabled ?? false}
onCheckedChange={(checked) => {
@@ -874,8 +874,8 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 10. 수정 버튼 설정 ===== */}
{tab.showEdit && (
<div className="space-y-3 rounded-lg border border-blue-200 bg-blue-50 p-3">
<Label className="text-xs font-semibold text-blue-700"> </Label>
<div className="space-y-3 rounded-lg border border-primary/20 bg-primary/10 p-3">
<Label className="text-xs font-semibold text-primary"> </Label>
<div className="space-y-2">
<div className="space-y-1">
<Label className="text-[10px]"> </Label>
@@ -950,7 +950,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* 그룹핑 기준 컬럼 */}
<div className="space-y-1">
<Label className="text-[10px]"> </Label>
<p className="text-[9px] text-gray-500"> </p>
<p className="text-[9px] text-muted-foreground"> </p>
<div className="max-h-[120px] space-y-1 overflow-y-auto rounded-md border bg-white p-2">
{tabColumns.map((col) => (
<div key={col.columnName} className="flex items-center gap-2">
@@ -980,8 +980,8 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
{/* ===== 11. 삭제 버튼 설정 ===== */}
{tab.showDelete && (
<div className="space-y-3 rounded-lg border border-red-200 bg-red-50 p-3">
<Label className="text-xs font-semibold text-red-700"> </Label>
<div className="space-y-3 rounded-lg border border-destructive/20 bg-destructive/10 p-3">
<Label className="text-xs font-semibold text-destructive"> </Label>
<div className="space-y-2">
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
@@ -1041,7 +1041,7 @@ const AdditionalTabConfigPanel: React.FC<AdditionalTabConfigPanelProps> = ({
<Button
variant="ghost"
size="sm"
className="text-red-500 hover:bg-red-50 hover:text-red-600"
className="text-destructive hover:bg-destructive/10 hover:text-destructive"
onClick={() => {
const newTabs = config.rightPanel?.additionalTabs?.filter((_, i) => i !== tabIndex) || [];
updateRightPanel({ additionalTabs: newTabs });
@@ -1356,7 +1356,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
return (
<div className="rounded-lg border p-4">
<p className="text-sm font-medium"> .</p>
<p className="mt-1 text-xs text-gray-600">
<p className="mt-1 text-xs text-muted-foreground">
.
</p>
</div>
@@ -1399,13 +1399,13 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
<SelectItem value="detail">
<div className="flex flex-col">
<span className="font-medium"> (DETAIL)</span>
<span className="text-xs text-gray-500"> ( )</span>
<span className="text-xs text-muted-foreground"> ( )</span>
</div>
</SelectItem>
<SelectItem value="join">
<div className="flex flex-col">
<span className="font-medium"> (FILTERED)</span>
<span className="text-xs text-gray-500"> </span>
<span className="text-xs text-muted-foreground"> </span>
</div>
</SelectItem>
</SelectContent>
@@ -1465,7 +1465,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
config.leftPanel?.tableName === screenTableName ? "opacity-100" : "opacity-0"
)}
/>
<Database className="mr-2 h-3.5 w-3.5 text-blue-500" />
<Database className="mr-2 h-3.5 w-3.5 text-primary" />
{allTables.find((t) => (t.tableName || t.table_name) === screenTableName)?.tableLabel ||
allTables.find((t) => (t.tableName || t.table_name) === screenTableName)?.displayName ||
screenTableName}
@@ -1556,13 +1556,13 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
<SelectItem value="list">
<div className="flex flex-col">
<span className="font-medium"> (LIST)</span>
<span className="text-xs text-gray-500"> ()</span>
<span className="text-xs text-muted-foreground"> ()</span>
</div>
</SelectItem>
<SelectItem value="table">
<div className="flex flex-col">
<span className="font-medium"> (TABLE)</span>
<span className="text-xs text-gray-500"> </span>
<span className="text-xs text-muted-foreground"> </span>
</div>
</SelectItem>
</SelectContent>
@@ -1793,11 +1793,11 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
// 상세 모드: 좌측과 동일한 테이블 (자동 설정)
<div className="space-y-2">
<Label> ( )</Label>
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<p className="text-sm font-medium text-gray-900">
<div className="rounded-lg border border-border bg-muted p-3">
<p className="text-sm font-medium text-foreground">
{config.leftPanel?.tableName || screenTableName || "테이블이 지정되지 않음"}
</p>
<p className="mt-1 text-xs text-gray-500"> </p>
<p className="mt-1 text-xs text-muted-foreground"> </p>
</div>
</div>
) : (
@@ -1837,7 +1837,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
)}
/>
{table.displayName || table.tableName}
{table.displayName && <span className="ml-2 text-xs text-gray-500">({table.tableName})</span>}
{table.displayName && <span className="ml-2 text-xs text-muted-foreground">({table.tableName})</span>}
</CommandItem>
))}
</CommandGroup>
@@ -1860,13 +1860,13 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
<SelectItem value="list">
<div className="flex flex-col">
<span className="font-medium"> (LIST)</span>
<span className="text-xs text-gray-500"> ()</span>
<span className="text-xs text-muted-foreground"> ()</span>
</div>
</SelectItem>
<SelectItem value="table">
<div className="flex flex-col">
<span className="font-medium"> (TABLE)</span>
<span className="text-xs text-gray-500"> </span>
<span className="text-xs text-muted-foreground"> </span>
</div>
</SelectItem>
</SelectContent>
@@ -1875,7 +1875,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
{/* 요약 표시 설정 (LIST 모드에서만) */}
{(config.rightPanel?.displayMode || "list") === "list" && (
<div className="space-y-3 rounded-lg border border-gray-200 bg-gray-50 p-3">
<div className="space-y-3 rounded-lg border border-border bg-muted p-3">
<Label className="text-sm font-semibold"> </Label>
<div className="space-y-2">
@@ -1891,13 +1891,13 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
}}
className="bg-white"
/>
<p className="text-xs text-gray-500"> (기본: 3개)</p>
<p className="text-xs text-muted-foreground"> (기본: 3개)</p>
</div>
<div className="flex items-center justify-between space-x-2">
<div className="flex-1">
<Label className="text-xs"> </Label>
<p className="text-xs text-gray-500"> </p>
<p className="text-xs text-muted-foreground"> </p>
</div>
<Checkbox
checked={config.rightPanel?.summaryShowLabel ?? true}
@@ -2418,7 +2418,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
</div>
{/* 🆕 우측 패널 삭제 버튼 설정 */}
<div className="space-y-3 rounded-lg border border-red-200 bg-red-50 p-3">
<div className="space-y-3 rounded-lg border border-destructive/20 bg-destructive/10 p-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<h3 className="text-sm font-semibold"> </h3>
@@ -2568,7 +2568,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
</Accordion>
) : (
<div className="rounded-lg border border-dashed p-4 text-center">
<p className="text-xs text-gray-500">
<p className="text-xs text-muted-foreground">
. [ ] .
</p>
</div>