사이드바 디자인 다듬기

This commit is contained in:
dohyeons
2025-10-22 12:48:17 +09:00
parent 8a421cfced
commit 85987af65e
5 changed files with 414 additions and 370 deletions

View File

@@ -1,12 +1,11 @@
"use client";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { ChartDataSource } from "../types";
import { ExternalDbConnectionAPI, ExternalDbConnection } from "@/lib/api/externalDbConnection";
import { Card } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { ExternalLink, Database, Server } from "lucide-react";
interface DatabaseConfigProps {
@@ -20,6 +19,7 @@ interface DatabaseConfigProps {
* - 외부 커넥션 목록 불러오기
*/
export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
const router = useRouter();
const [connections, setConnections] = useState<ExternalDbConnection[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -49,93 +49,87 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
const selectedConnection = connections.find((conn) => String(conn.id) === dataSource.externalConnectionId);
return (
<div className="space-y-4">
<div>
<h3 className="text-lg font-semibold text-gray-800">2단계: 데이터베이스 </h3>
<p className="mt-1 text-sm text-gray-600"> </p>
</div>
<div className="space-y-3">
{/* 현재 DB vs 외부 DB 선택 */}
<Card className="p-4">
<Label className="mb-3 block text-sm font-medium text-gray-700"> </Label>
<div className="grid grid-cols-2 gap-3">
<Button
variant={dataSource.connectionType === "current" ? "default" : "outline"}
className="h-auto justify-start py-3"
<div>
<Label className="mb-2 block text-xs font-medium text-gray-700"> </Label>
<div className="flex gap-2">
<button
onClick={() => {
onChange({ connectionType: "current", externalConnectionId: undefined });
}}
className={`flex flex-1 items-center gap-1.5 rounded border px-2 py-1.5 text-xs transition-colors ${
dataSource.connectionType === "current"
? "bg-primary border-primary text-white"
: "border-gray-200 bg-white hover:bg-gray-50"
}`}
>
<Database className="mr-2 h-4 w-4" />
<div className="text-left">
<div className="font-medium"> DB</div>
<div className="text-xs opacity-80"> DB</div>
</div>
</Button>
<Database className="h-3 w-3" />
DB
</button>
<Button
variant={dataSource.connectionType === "external" ? "default" : "outline"}
className="h-auto justify-start py-3"
<button
onClick={() => {
onChange({ connectionType: "external" });
}}
className={`flex flex-1 items-center gap-1.5 rounded border px-2 py-1.5 text-xs transition-colors ${
dataSource.connectionType === "external"
? "bg-primary border-primary text-white"
: "border-gray-200 bg-white hover:bg-gray-50"
}`}
>
<Server className="mr-2 h-4 w-4" />
<div className="text-left">
<div className="font-medium"> DB</div>
<div className="text-xs opacity-80"> </div>
</div>
</Button>
<Server className="h-3 w-3" />
DB
</button>
</div>
</Card>
</div>
{/* 외부 DB 선택 시 커넥션 목록 */}
{dataSource.connectionType === "external" && (
<Card className="space-y-4 p-4">
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label className="text-sm font-medium text-gray-700"> </Label>
<Button
variant="ghost"
size="sm"
<Label className="text-xs font-medium text-gray-700"> </Label>
<button
onClick={() => {
window.open("/admin/external-connections", "_blank");
router.push("/admin/external-connections");
}}
className="text-xs"
className="flex items-center gap-1 text-[11px] text-blue-600 transition-colors hover:text-blue-700"
>
<ExternalLink className="mr-1 h-3 w-3" />
<ExternalLink className="h-3 w-3" />
</Button>
</button>
</div>
{loading && (
<div className="flex items-center justify-center py-4">
<div className="h-5 w-5 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" />
<span className="ml-2 text-sm text-gray-600"> ...</span>
<div className="flex items-center justify-center py-3">
<div className="h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" />
<span className="ml-2 text-xs text-gray-600"> ...</span>
</div>
)}
{error && (
<div className="rounded-lg border border-red-200 bg-red-50 p-3">
<div className="text-sm text-red-800"> {error}</div>
<Button variant="ghost" size="sm" onClick={loadExternalConnections} className="mt-2 text-xs">
<div className="rounded bg-red-50 px-2 py-1.5">
<div className="text-xs text-red-800">{error}</div>
<button
onClick={loadExternalConnections}
className="mt-1 text-[11px] text-red-600 underline hover:no-underline"
>
</Button>
</button>
</div>
)}
{!loading && !error && connections.length === 0 && (
<div className="rounded-lg border border-yellow-200 bg-yellow-50 p-4 text-center">
<div className="mb-2 text-sm text-yellow-800"> </div>
<Button
variant="outline"
size="sm"
<div className="rounded bg-yellow-50 px-2 py-2 text-center">
<div className="mb-1 text-xs text-yellow-800"> </div>
<button
onClick={() => {
window.open("/admin/external-connections", "_blank");
router.push("/admin/external-connections");
}}
className="text-[11px] text-yellow-700 underline hover:no-underline"
>
<ExternalLink className="mr-1 h-3 w-3" />
</Button>
</button>
</div>
)}
@@ -147,15 +141,15 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
onChange({ externalConnectionId: value });
}}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="커넥션 선택하세요" />
<SelectTrigger className="h-8 w-full text-xs">
<SelectValue placeholder="커넥션 선택" />
</SelectTrigger>
<SelectContent className="z-[9999]">
{connections.map((conn) => (
<SelectItem key={conn.id} value={String(conn.id)}>
<div className="flex items-center gap-2">
<SelectItem key={conn.id} value={String(conn.id)} className="text-xs">
<div className="flex items-center gap-1.5">
<span className="font-medium">{conn.connection_name}</span>
<span className="text-xs text-gray-500">({conn.db_type.toUpperCase()})</span>
<span className="text-[10px] text-gray-500">({conn.db_type.toUpperCase()})</span>
</div>
</SelectItem>
))}
@@ -163,31 +157,17 @@ export function DatabaseConfig({ dataSource, onChange }: DatabaseConfigProps) {
</Select>
{selectedConnection && (
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<div className="space-y-1 text-xs text-gray-600">
<div>
<span className="font-medium">:</span> {selectedConnection.connection_name}
</div>
<div>
<span className="font-medium">:</span> {selectedConnection.db_type.toUpperCase()}
</div>
<div className="space-y-0.5 rounded bg-gray-50 px-2 py-1.5 text-[11px] text-gray-600">
<div>
<span className="font-medium">:</span> {selectedConnection.connection_name}
</div>
<div>
<span className="font-medium">:</span> {selectedConnection.db_type.toUpperCase()}
</div>
</div>
)}
</>
)}
</Card>
)}
{/* 다음 단계 안내 */}
{(dataSource.connectionType === "current" ||
(dataSource.connectionType === "external" && dataSource.externalConnectionId)) && (
<div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
<div className="text-sm text-blue-800">
.
<br />
SQL .
</div>
</div>
)}
</div>