react prototype arch to generic logistic management web applications
  • TypeScript 88.1%
  • Python 8.1%
  • JavaScript 2%
  • CSS 1.4%
  • HTML 0.4%
Find a file
Manuel Samuel Alfaro Sierra 59a1c0ef82 feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks
- Migrate package manager from npm to pnpm (pnpm-lock.yaml, packageManager field)
- Add FastAPI mock server for all API endpoints (oauth/token, profile, orders)
- Add uv for Python dependency management (pyproject.toml, uv.lock)
- Add concurrently to run mock server and Vite together via pnpm dev
- Add husky + lint-staged pre-commit hooks (ESLint on staged files + vitest run)
- Prefill demo user email in LoginForm defaultValues
- Update .env.development to point to local mock server (port 8000)
- Implement PageNavigator component (was empty, TDD tests already existed)
- Fix LoginForm/LoginPage tests to account for prefilled email defaultValues
- Fix unhandled promise rejection in LoginPage handleSubmit (mutateAsync try-catch)
2026-04-08 10:52:21 +02:00
.husky feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
docs/tasks [FEAT] Added catalys Paginator url to task 2025-09-17 16:24:00 +02:00
mock_server feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
public [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
src feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
vendor/ui-kit [FEAT] Moved ui-kit to /vendor. Set vendor folder as eslint ignore 2025-09-09 17:17:32 +02:00
.editorconfig [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
.gitignore feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
eslint.config.js [FEAT] Moved ui-kit to /vendor. Set vendor folder as eslint ignore 2025-09-09 17:17:32 +02:00
index.html [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
package.json feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
pnpm-lock.yaml feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
prettier.config.js [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
pyproject.toml feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
README.md [FEAT] Fix readme 2025-09-08 20:41:10 +02:00
README_URL_Filters.md [FEAT] Added shared/common types and shemas. And added order feature types and schemas. And new readme for filters use a architecture 2025-09-16 17:32:35 +02:00
README_URL_Filters_EN.md [FEAT] Added shared/common types and shemas. And added order feature types and schemas. And new readme for filters use a architecture 2025-09-16 17:32:35 +02:00
tailwind.config.ts [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
tsconfig.app.json [FEAT] Added filters test for virtual url and real url with navigation 2025-09-22 18:06:44 +02:00
tsconfig.json [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
tsconfig.node.json [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00
uv.lock feat: migrate to pnpm, add Python mock server with uv, add husky pre-commit hooks 2026-04-08 10:52:21 +02:00
vite.config.ts [FEAT] Moved ui-kit to /vendor. Set vendor folder as eslint ignore 2025-09-09 17:17:32 +02:00
vitest.config.ts [FEAT] Initial migration prototype from 2022 2025-09-08 20:36:26 +02:00

Logistics Web App Prototype (React)

A modern management UI prototype for logistics built with React + Vite + TypeScript.
It showcases a production-friendly architecture: feature-first folder layout, clean separation of server state vs client/UI state, nested layouts, robust error handling, and scalable i18n.


Goals

  • Fast developer experience (Vite, TS, Tailwind)
  • Clear boundaries: server state (TanStack Query) vs client/UI state (Zustand)
  • Resilient UX with UI error boundaries and router error elements
  • Scalable routing with nested layouts and auth-protected branches
  • i18n designed to grow (namespaces + type-safe keys)
  • Composable, testable components and pages

🧱 Tech Stack

  • Build / Runtime: Vite, React 19, TypeScript
  • Routing: react-router-dom (nested layouts, route guards)
  • Server state: @tanstack/react-query (queries, mutations, cache, retries)
  • Client/UI state: zustand
  • Forms & Validation: react-hook-form + zod (+ @hookform/resolvers)
  • Tables & Virtualization: @tanstack/react-table, @tanstack/react-virtual
  • Styling: Tailwind CSS (+ Headless UI and Heroicons)
  • HTTP client: Axios (shared instance + interceptors)
  • i18n: i18next + react-i18next (namespaces, lazy loading)
  • Error handling: react-error-boundary (UI) + Router errorElement
  • Testing (ready to plug): Vitest, Testing Library, MSW

🗂 Project Structure

src/
  app/
    providers/             # global providers (Query, Router, i18n, etc.)
      AppProviders.tsx
    router/
      index.tsx            # routes, nested layouts, errorElement
    layout/
      MainLayout.tsx       # authenticated shell (sidebar, header)
      AuthLayout.tsx       # public shell for login/register
    i18n/
      index.ts              # i18next init (global namespaces)
      locales/
        es/{common.json,errors.json}
        en/{common.json,errors.json}
      types.d.ts            # type-safe i18n keys (TS augmentation)

  shared/
    api/
      http.ts               # axios instance + interceptors
    auth/
      RequireAuth.tsx       # route guard (uses /auth feature)
    components/
      error/
        AppErrorBoundary.tsx    # UI-level boundary (react-error-boundary)
        RouteErrorElement.tsx   # Router-level error UI
      ...
    hooks/                  # generic hooks (debounce, localStorage...)
    lib/                    # formatters, mappers
    constants/              # app-wide constants
    types/                  # shared types (ApiError, Paginated<T>)

  features/
    auth/
      pages/
        LoginPage.tsx
      components/
        LoginForm.tsx
      api/
        queries.ts          # useMe()
        mutations.ts        # useLogin(), useLogout()
      model/
        schemas.ts          # zod schemas
        types.ts            # zod-inferred types
      store/
        session.ts          # UI flags (e.g., 2FA step)
      i18n/
        es.json
        en.json
      index.ts

    orders/                 # future module (list/detail/create)
      pages/ components/ api/ model/ store/ i18n/ index.ts

Why feature-first? Everything a domain needs (pages, components, API hooks, store, i18n, schemas) lives together → easier maintenance and ownership.


🔀 Routing & Layouts

  • Nested layouts:
    • AuthLayout (no sidebar): /auth/*
    • MainLayout (sidebar/header): all authenticated routes
  • Route guard: RequireAuth wraps private branches (reads the user via useMe() or a session store).
  • Error UI for routes: errorElement: <RouteErrorElement /> for each branch covers 404s and loader/action errors.

Example:

createBrowserRouter([
  {
    path: "/auth",
    element: <AuthLayout />,
    errorElement: <RouteErrorElement />,
    children: [{ path: "login", element: <LoginPage /> }]
  },
  {
    element: <RequireAuth />,
    errorElement: <RouteErrorElement />,
    children: [
      {
        element: <MainLayout />,
        errorElement: <RouteErrorElement />,
        children: [
          { path: "/", element: <HomePage /> },
          // /orders, /clients, ...
        ]
      }
    ]
  }
])

Inside each layout, the content outlet is wrapped with a UI error boundary:

export function MainLayout() {
  return (
    <div className="min-h-screen flex">
      <aside className="w-64 border-r p-4">Sidebar</aside>
      <main className="flex-1 p-6">
        <AppErrorBoundary>
          <Outlet />
        </AppErrorBoundary>
      </main>
    </div>
  )
}

🧭 State Management Strategy

  • Server state (from backend)TanStack Query
    • useQuery({ queryKey, queryFn }) for reads; caching, dedup, background refetch, retries
    • useMutation({ mutationFn, onSuccess: invalidateQueries }) for writes
    • Keep query keys parameterized (e.g., ["orders", page, filters])
  • Client/UI stateZustand
    • Local UI concerns: open modals, table filters, pagination, wizard steps
    • Avoid mixing server data in Zustand

This separation prevents oversized global stores and gives you robust caching + invalidation out of the box.


🌍 Internationalization (i18n)

  • Global namespaces: common, errors
  • Feature namespaces: one per feature (auth, orders, …), co-located under features/<feature>/i18n
  • Lazy loading per feature (load namespace on page/layout entry)
  • Type-safe keys via src/app/i18n/types.d.ts so t("…") autocompletes and fails at compile time on typos

Example in a route error element:

const { t } = useTranslation("errors")
const title = t("unexpected_title")

🧪 Forms & Validation

  • react-hook-form + zod for schema-driven forms
    • Define a single source of truth in zod (schemas.ts)
    • Infer TS types via z.infer<> (types.ts)
    • Use zodResolver to validate form inputs and ensure runtime safety

📊 Tables & Virtualization

  • @tanstack/react-table: headless table engine (sorting, filtering, pagination)
  • @tanstack/react-virtual: virtualized rows for large datasets (10k+)
  • Designed to pair naturally with React Query for server-driven pagination/filtering

🎨 Styling

  • Tailwind CSS for utility-first styling
  • Headless UI for accessible primitives
  • Heroicons for iconography
  • Optional screen/font extensions in tailwind.config.ts

🚨 Error Handling

  • UI errors (rendering): react-error-boundary
    • AppErrorBoundary wraps layout outlets; shows a friendly fallback and resets on route change
  • Route errors (404 / loaders/actions): RouteErrorElement via errorElement
  • Log in onError or forward to your telemetry tool (e.g., Sentry)

🔌 HTTP

  • Centralized Axios instance in shared/api/http.ts
    • baseURL, withCredentials, interceptors (auth/refresh), default headers
  • Feature API hooks call this instance inside Query queryFn/mutationFn

🧭 Aliases

  • Vite + TS paths mapping: @src
  • Configure both vite.config.ts and tsconfig.json (baseUrl + paths)

🧰 Scripts

package.json:

{
  "scripts": {
    "serve": "vite --port 8080 --mode development",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  }
}

▶️ Getting Started

# install
npm install

# dev
npm run serve

# type-check + build
npm run build

# preview production build
npm run preview

Adding a New Feature (example: orders)

  1. Create src/features/orders/{pages,components,api,model,store,i18n}
  2. Define schemas in model/schemas.ts and infer types in model/types.ts
  3. Add Query hooks in api/queries.ts and Mutations in api/mutations.ts
  4. If needed, a small Zustand store for UI filters in store/
  5. Add translations in features/orders/i18n/{es,en}.json and (once) register in app/i18n/types.d.ts
  6. Register routes under MainLayout (/orders, /orders/:id, …)

Conventions

  • Feature-first folders
  • Server vs Client state separation
  • zod-first models (runtime validation + TS inference)
  • Namespaces: common, errors, and one per feature
  • Double quotes & no semicolons (configured via Prettier)
  • Keep shared/ domain-agnostic; only cross-cutting utilities live there

📈 Testing (optional setup)

  • Vitest as test runner
  • Testing Library for React components
  • MSW for API mocking (queries/mutations without a backend)

This repo is a solid starting point for a real-world logistics management UI: fast to iterate, robust on errors, easy to extend by features, and friendly to teams and translators.