diff --git a/driver-pwa/frontend/src/App.test.tsx b/driver-pwa/frontend/src/App.test.tsx new file mode 100644 index 0000000..db011f2 --- /dev/null +++ b/driver-pwa/frontend/src/App.test.tsx @@ -0,0 +1,25 @@ +import { describe, it, expect, beforeEach } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { MemoryRouter } from "react-router-dom"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import App from "./App"; +import { useAuth } from "@/store/auth"; + +function renderAt(path: string) { + const qc = new QueryClient(); + return render( + + + + + + ); +} + +describe("routing guard", () => { + beforeEach(() => useAuth.getState().clear()); + it("redirects to login when no token", () => { + renderAt("/"); + expect(screen.getByText(/Вход в приложение/i)).toBeInTheDocument(); + }); +}); diff --git a/driver-pwa/frontend/src/App.tsx b/driver-pwa/frontend/src/App.tsx index 1bdfc74..d0b4dc0 100644 --- a/driver-pwa/frontend/src/App.tsx +++ b/driver-pwa/frontend/src/App.tsx @@ -1,3 +1,30 @@ +import type { ReactNode } from "react"; +import { Navigate, Route, Routes } from "react-router-dom"; +import { useAuth } from "@/store/auth"; +import { LoginPage } from "@/pages/LoginPage"; +import { OnboardingPage } from "@/pages/OnboardingPage"; +import { BalancePage } from "@/pages/BalancePage"; +import { TopupPage } from "@/pages/TopupPage"; +import { PaymentPage } from "@/pages/PaymentPage"; +import { HistoryPage } from "@/pages/HistoryPage"; + +function RequireAuth({ children }: { children: ReactNode }) { + const token = useAuth((s) => s.token); + return token ? <>{children} : ; +} + export default function App() { - return
Премиум Водитель
; + return ( +
+ + } /> + } /> + } /> + } /> + } /> + } /> + } /> + +
+ ); } diff --git a/driver-pwa/frontend/src/components/AppHeader.tsx b/driver-pwa/frontend/src/components/AppHeader.tsx new file mode 100644 index 0000000..1752530 --- /dev/null +++ b/driver-pwa/frontend/src/components/AppHeader.tsx @@ -0,0 +1,12 @@ +export function AppHeader({ initials }: { initials?: string }) { + return ( +
+ Премиум Водитель + {initials && ( + + {initials} + + )} +
+ ); +} diff --git a/driver-pwa/frontend/src/components/Segment.tsx b/driver-pwa/frontend/src/components/Segment.tsx new file mode 100644 index 0000000..633b095 --- /dev/null +++ b/driver-pwa/frontend/src/components/Segment.tsx @@ -0,0 +1,19 @@ +interface Props { value: string; options: { value: string; label: string }[]; onChange: (v: string) => void; } +export function Segment({ value, options, onChange }: Props) { + return ( +
+ {options.map((o) => ( + + ))} +
+ ); +} diff --git a/driver-pwa/frontend/src/components/Spinner.tsx b/driver-pwa/frontend/src/components/Spinner.tsx new file mode 100644 index 0000000..a4ae38e --- /dev/null +++ b/driver-pwa/frontend/src/components/Spinner.tsx @@ -0,0 +1,3 @@ +export function Spinner() { + return ; +} diff --git a/driver-pwa/frontend/src/pages/BalancePage.tsx b/driver-pwa/frontend/src/pages/BalancePage.tsx new file mode 100644 index 0000000..0ceefa4 --- /dev/null +++ b/driver-pwa/frontend/src/pages/BalancePage.tsx @@ -0,0 +1 @@ +export function BalancePage() { return null; } diff --git a/driver-pwa/frontend/src/pages/HistoryPage.tsx b/driver-pwa/frontend/src/pages/HistoryPage.tsx new file mode 100644 index 0000000..e963843 --- /dev/null +++ b/driver-pwa/frontend/src/pages/HistoryPage.tsx @@ -0,0 +1 @@ +export function HistoryPage() { return null; } diff --git a/driver-pwa/frontend/src/pages/LoginPage.tsx b/driver-pwa/frontend/src/pages/LoginPage.tsx new file mode 100644 index 0000000..363dac5 --- /dev/null +++ b/driver-pwa/frontend/src/pages/LoginPage.tsx @@ -0,0 +1,3 @@ +export function LoginPage() { + return
Вход в приложение
; +} diff --git a/driver-pwa/frontend/src/pages/OnboardingPage.tsx b/driver-pwa/frontend/src/pages/OnboardingPage.tsx new file mode 100644 index 0000000..ea25e3f --- /dev/null +++ b/driver-pwa/frontend/src/pages/OnboardingPage.tsx @@ -0,0 +1 @@ +export function OnboardingPage() { return null; } diff --git a/driver-pwa/frontend/src/pages/PaymentPage.tsx b/driver-pwa/frontend/src/pages/PaymentPage.tsx new file mode 100644 index 0000000..c093dad --- /dev/null +++ b/driver-pwa/frontend/src/pages/PaymentPage.tsx @@ -0,0 +1 @@ +export function PaymentPage() { return null; } diff --git a/driver-pwa/frontend/src/pages/TopupPage.tsx b/driver-pwa/frontend/src/pages/TopupPage.tsx new file mode 100644 index 0000000..5e3b567 --- /dev/null +++ b/driver-pwa/frontend/src/pages/TopupPage.tsx @@ -0,0 +1 @@ +export function TopupPage() { return null; }