diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 4c23aa9..89f7963 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -7,8 +7,10 @@ let mainWindow: BrowserWindow | null = null export function createMainWindow(): void { mainWindow = new BrowserWindow({ - width: 900, - height: 670, + width: 1280, + minWidth: 1280, + height: 832, + minHeight: 832, show: false, autoHideMenuBar: true, ...(process.platform === 'linux' ? { icon } : {}), diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index bfc1ccf..151090e 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -1,5 +1,5 @@ import { HashRouter, Route, Routes } from 'react-router-dom' -import { MainPage } from '@/components/main-page' +import { MainPage } from '@/components/workspace/main-page' import { ConnectionWizard } from '@/components/connection-wizard/wizard-modal' function App(): React.JSX.Element { diff --git a/src/renderer/src/components/layout/side-bar.tsx b/src/renderer/src/components/layout/side-bar.tsx new file mode 100644 index 0000000..73d1b9d --- /dev/null +++ b/src/renderer/src/components/layout/side-bar.tsx @@ -0,0 +1,62 @@ +import { Button } from '@/components/ui/button' +import AppIcon from '@renderer/assets/icon.svg' +import { Database, Plus, Settings, Tag } from 'lucide-react' +import { cn } from '@/lib/utils' +import type { NavItem } from '../workspace/types' + +const topNavItems: NavItem[] = [ + { id: 'database', icon: Database, active: true }, + { id: 'tags', icon: Tag, disabled: true } // TODO: DB 연결 후에 disabled: false +] + +const bottomNavItems: NavItem[] = [ + { id: 'settings', icon: Settings }, + { id: 'add', icon: Plus } +] + +function NavButton({ item }: { item: NavItem }): React.JSX.Element { + const Icon = item.icon + return ( + + ) +} + +export function Sidebar(): React.JSX.Element { + return ( + + ) +} diff --git a/src/renderer/src/components/main-page.tsx b/src/renderer/src/components/main-page.tsx deleted file mode 100644 index 074a419..0000000 --- a/src/renderer/src/components/main-page.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { JSX } from 'react' -import AppIcon from '@renderer/assets/icon.svg' -import { Button } from '@/components/ui/button' - -/** - * TODO: 메인 페이지 - */ -export function MainPage(): JSX.Element { - return ( -
- -

Qgenie

- -
- ) -} diff --git a/src/renderer/src/components/workspace/feature-card.tsx b/src/renderer/src/components/workspace/feature-card.tsx new file mode 100644 index 0000000..acf0720 --- /dev/null +++ b/src/renderer/src/components/workspace/feature-card.tsx @@ -0,0 +1,21 @@ +import type { FeatureCardData } from './types' + +interface FeatureCardProps { + card: FeatureCardData +} + +export function FeatureCard({ card }: FeatureCardProps): React.JSX.Element { + return ( +
+
+
+
+ {card.title} +
+
+ {card.description} +
+
+
+ ) +} diff --git a/src/renderer/src/components/workspace/main-page.tsx b/src/renderer/src/components/workspace/main-page.tsx new file mode 100644 index 0000000..df52568 --- /dev/null +++ b/src/renderer/src/components/workspace/main-page.tsx @@ -0,0 +1,11 @@ +import { Sidebar } from '../layout/side-bar' +import { WorkspaceEmptyState } from './workspace-empty-state' + +export function MainPage(): React.JSX.Element { + return ( +
+ + +
+ ) +} diff --git a/src/renderer/src/components/workspace/types.ts b/src/renderer/src/components/workspace/types.ts new file mode 100644 index 0000000..ac5f4a2 --- /dev/null +++ b/src/renderer/src/components/workspace/types.ts @@ -0,0 +1,15 @@ +import type { LucideIcon } from 'lucide-react' + +export interface NavItem { + id: string + icon: LucideIcon + active?: boolean + disabled?: boolean + onClick?: () => void +} + +export interface FeatureCardData { + title: string + description: React.ReactNode + image?: string +} diff --git a/src/renderer/src/components/workspace/workspace-empty-state.tsx b/src/renderer/src/components/workspace/workspace-empty-state.tsx new file mode 100644 index 0000000..459233f --- /dev/null +++ b/src/renderer/src/components/workspace/workspace-empty-state.tsx @@ -0,0 +1,77 @@ +import { Plus } from 'lucide-react' +import { FeatureCard } from './feature-card' +import type { FeatureCardData } from './types' + +const featureCards: FeatureCardData[] = [ + { + title: '자연어 질의', + description: ( + <> + SQL을 몰라도 질문할 수 있어요. +
+ 자연어로 입력하면 쿼리를 만들어줘요. + + ) + }, + { + title: '쿼리 실행 결과 확인', + description: ( + <> + 생성된 SQL을 직접 실행해볼 수 있어요. +
+ 결과는 표로 정리돼 한눈에 보여요. + + ) + }, + { + title: '자동 컬럼 설명 생성', + description: ( + <> + AI가 테이블과 컬럼을 분석해 +
+ 이해하기 쉬운 설명을 자동으로 생성해줘요. + + ) + } +] + +function handleConnectClick(): void { + window.api.send('open-sub-window', { + width: 800, + height: 610, + route: '/connection-wizard' + }) +} + +export function WorkspaceEmptyState(): React.JSX.Element { + return ( +
+
+

+ 데이터가 연결되지 않았어요 +

+

+ 데이터베이스를 연결하고 +
+ 질문하거나 쿼리를 작성해보세요. +

+
+ +
+ {featureCards.map((card) => ( + + ))} +
+ + +
+ ) +}