From 7c910bdcdd271a87e5658863108704619ad59568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=ED=98=95=EC=A7=84?= Date: Tue, 22 Jul 2025 19:44:23 +0900 Subject: [PATCH 1/5] chore: resize main window --- src/main/windows/mainWindow.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 4c23aa9..6c22dcb 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -7,8 +7,8 @@ let mainWindow: BrowserWindow | null = null export function createMainWindow(): void { mainWindow = new BrowserWindow({ - width: 900, - height: 670, + width: 1280, + height: 832, show: false, autoHideMenuBar: true, ...(process.platform === 'linux' ? { icon } : {}), From cc60d0f8e62f77fd5008f194efc9a4d9a623596b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=ED=98=95=EC=A7=84?= Date: Tue, 22 Jul 2025 19:46:38 +0900 Subject: [PATCH 2/5] feat: declare type & implement reusable components --- .../src/components/layout/side-bar.tsx | 62 +++++++++++++++++++ .../src/components/workspace/feature-card.tsx | 21 +++++++ .../src/components/workspace/types.ts | 15 +++++ 3 files changed, 98 insertions(+) create mode 100644 src/renderer/src/components/layout/side-bar.tsx create mode 100644 src/renderer/src/components/workspace/feature-card.tsx create mode 100644 src/renderer/src/components/workspace/types.ts 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..95c46fe --- /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 } // 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/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/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 +} From e55039450c468591a07f1f317f6ce5d0a50b75db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=ED=98=95=EC=A7=84?= Date: Tue, 22 Jul 2025 19:49:21 +0900 Subject: [PATCH 3/5] feat: complete publishing --- src/renderer/src/App.tsx | 2 +- src/renderer/src/components/main-page.tsx | 27 ------- .../src/components/workspace/main-page.tsx | 11 +++ .../workspace/workspace-empty-state.tsx | 77 +++++++++++++++++++ 4 files changed, 89 insertions(+), 28 deletions(-) delete mode 100644 src/renderer/src/components/main-page.tsx create mode 100644 src/renderer/src/components/workspace/main-page.tsx create mode 100644 src/renderer/src/components/workspace/workspace-empty-state.tsx 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/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/main-page.tsx b/src/renderer/src/components/workspace/main-page.tsx new file mode 100644 index 0000000..57f68d8 --- /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/workspace-empty-state.tsx b/src/renderer/src/components/workspace/workspace-empty-state.tsx new file mode 100644 index 0000000..c82f1f5 --- /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) => ( + + ))} +
+ + +
+ ) +} From ab2ed6f77d7edd32bf6b8585e94eb5b1b5c017ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=ED=98=95=EC=A7=84?= Date: Tue, 22 Jul 2025 20:27:16 +0900 Subject: [PATCH 4/5] chore: add cursor hovering & TODO --- src/renderer/src/components/layout/side-bar.tsx | 2 +- src/renderer/src/components/workspace/workspace-empty-state.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/layout/side-bar.tsx b/src/renderer/src/components/layout/side-bar.tsx index 95c46fe..73d1b9d 100644 --- a/src/renderer/src/components/layout/side-bar.tsx +++ b/src/renderer/src/components/layout/side-bar.tsx @@ -6,7 +6,7 @@ import type { NavItem } from '../workspace/types' const topNavItems: NavItem[] = [ { id: 'database', icon: Database, active: true }, - { id: 'tags', icon: Tag, disabled: true } // DB 연결 후에 disabled: false + { id: 'tags', icon: Tag, disabled: true } // TODO: DB 연결 후에 disabled: false ] const bottomNavItems: NavItem[] = [ diff --git a/src/renderer/src/components/workspace/workspace-empty-state.tsx b/src/renderer/src/components/workspace/workspace-empty-state.tsx index c82f1f5..459233f 100644 --- a/src/renderer/src/components/workspace/workspace-empty-state.tsx +++ b/src/renderer/src/components/workspace/workspace-empty-state.tsx @@ -65,7 +65,7 @@ export function WorkspaceEmptyState(): React.JSX.Element {