diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx index 6edcc08..0aa4c3a 100644 --- a/frontend/src/app/App.tsx +++ b/frontend/src/app/App.tsx @@ -1,5 +1,10 @@ -import { DesignSystemPreview } from '@/features/design-system/DesignSystemPreview' +import { AppShell } from './layout/AppShell' +import { Router } from './router' export function App() { - return + return ( + + + + ) } diff --git a/frontend/src/app/layout/AppShell.tsx b/frontend/src/app/layout/AppShell.tsx index 5a77878..ca55491 100644 --- a/frontend/src/app/layout/AppShell.tsx +++ b/frontend/src/app/layout/AppShell.tsx @@ -13,7 +13,7 @@ export function AppShell({ children }: AppShellProps) {
-
{children}
+ {children}
) diff --git a/frontend/src/app/layout/Sidebar.tsx b/frontend/src/app/layout/Sidebar.tsx index 193c256..8eaf12b 100644 --- a/frontend/src/app/layout/Sidebar.tsx +++ b/frontend/src/app/layout/Sidebar.tsx @@ -1,9 +1,27 @@ export function Sidebar() { + const navItems = [ + { href: '#/tickets', label: 'Tickets' }, + { href: '#/tickets/new', label: 'Create Ticket' }, + { href: '#/solutions', label: 'Solutions' }, + { href: '#/design-system', label: 'Design System' } + ] + return ( ) } diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx index 1c57d86..eb33387 100644 --- a/frontend/src/app/router.tsx +++ b/frontend/src/app/router.tsx @@ -1,5 +1,30 @@ -import { App } from './App' +import * as React from 'react' + +import { DesignSystemPreview } from '@/features/design-system/DesignSystemPreview' + +function getRoute() { + return window.location.hash.replace(/^#/, '') || '/tickets' +} export function Router() { - return + const [route, setRoute] = React.useState(getRoute) + + React.useEffect(() => { + const handleHashChange = () => setRoute(getRoute()) + window.addEventListener('hashchange', handleHashChange) + return () => window.removeEventListener('hashchange', handleHashChange) + }, []) + + if (route === '/design-system') { + return + } + + return ( +
+
+

Route

+

{route}

+
+
+ ) } diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts new file mode 100644 index 0000000..8745e42 --- /dev/null +++ b/frontend/src/lib/api.ts @@ -0,0 +1,17 @@ +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:8000/api' + +export async function apiRequest(path: string, init?: RequestInit): Promise { + const response = await fetch(`${API_BASE_URL}${path}`, { + headers: { + 'content-type': 'application/json', + ...init?.headers + }, + ...init + }) + + if (!response.ok) { + throw new Error(`API request failed: ${response.status}`) + } + + return response.json() as Promise +} diff --git a/frontend/src/lib/format.ts b/frontend/src/lib/format.ts new file mode 100644 index 0000000..a1d2fe1 --- /dev/null +++ b/frontend/src/lib/format.ts @@ -0,0 +1,6 @@ +export function formatDateTime(value: string) { + return new Intl.DateTimeFormat('zh-CN', { + dateStyle: 'medium', + timeStyle: 'short' + }).format(new Date(value)) +} diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/frontend/src/vite-env.d.ts @@ -0,0 +1 @@ +///