Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ pnpm-debug.log*
*storybook.log

# Storybook build output
storybook-static/
storybook-static/

# 3rd party
vendors/
19 changes: 15 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install

# Copy workspace configuration and root package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./

# Install pnpm
RUN npm install -g pnpm

# Copy all package.json files to enable proper dependency resolution
COPY packages/ui-kit/package.json ./packages/ui-kit/
WORKDIR /app/packages/ui-kit
COPY packages/showcase/package.json ./packages/showcase/

# Install all dependencies for the workspace
RUN pnpm install
WORKDIR /app

# Copy all source code
COPY . .

# Build all packages
RUN pnpm build

# Production stage
Expand Down
2 changes: 1 addition & 1 deletion docs/project_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ A pragmatic breakdown into **four one‑week sprints** plus a preparatory **Spri
| --- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------ |
| 3.1 | Wrap **TanStack Table** into `DataTable` with pagination, resize. | Story with 50 rows paginates; Playwright test clicks next page. | βœ“ |
| 3.2 | Build **MainLayout** with TopBar + LeftNav + Breadcrumb. | Storybook viewport test at 1280 & 1024 px shows responsive collapse. | βœ“ |
| 3.3 | Implement Toast system (`useToast`) + StatusBadge. | Vitest renders Toast, axe-core passes. | PR |
| 3.3 | Implement Toast system (`useToast`) + StatusBadge. | Vitest renders Toast, axe-core passes. | βœ“ |
| 3.4 | Sample showcase: login page + dashboard + customers table route. | E2E Playwright run (login β†’ dashboard) green in CI. | |
| 3.5 | Add i18n infrastructure (`react-i18next`) with `en`, `de` locales. | Storybook toolbar allows locale switch; renders German labels. | |
| 3.6 | **SQLite seed script** – generate 100 customers & 2 users; hook `pnpm run seed` in showcase. | Script executes without error; Playwright test logs in with `admin` credentials, verifies 100 customers paginated. | |
Expand Down
169 changes: 169 additions & 0 deletions docs/task-planning/task-3.4-sample-showcase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Task 3.4: Sample Showcase - Login Page + Dashboard + Customers Table Route

## Task Description

Implement a sample showcase application that demonstrates the UI-Kit components in action. This includes creating actual application routes with login functionality, a dashboard, and a customers table view using the existing UI components.

## Task Planning

| Task Description | Definition of Done (DoD) | Status |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------- |
| Set up showcase application structure | - Showcase app directory structure exists<br>- React Router v7 configured<br>- Basic routing setup complete | Complete |
| Create login page using AuthShell | - Login page renders with AuthShell layout<br>- Login form uses UI-Kit form components<br>- Basic authentication logic implemented | Checking |
| Implement dashboard page using MainLayout | - Dashboard page renders with MainLayout<br>- Displays summary cards and navigation<br>- Uses existing UI-Kit components | Open |
| Create customers table route with DataTable | - Customers page displays using DataTable component<br>- Shows paginated customer data<br>- Navigation from dashboard works | Open |
| Add routing and navigation | - React Router navigation between pages<br>- Protected routes for authenticated content<br>- Breadcrumb navigation works | Open |
| Implement basic authentication state | - Login/logout functionality<br>- Session persistence<br>- Route protection based on auth state | Open |
| Add sample data and mock API | - Customer data generation<br>- Mock authentication endpoints<br>- API integration with DataTable | Open |
| Create E2E tests | - Playwright tests for login flow<br>- Navigation test (login β†’ dashboard β†’ customers)<br>- Tests pass in CI | Open |
| Integrate showcase with UI-Kit build | - Showcase app builds successfully<br>- Uses published UI-Kit components<br>- No circular dependencies | Open |

## Implementation Details

### 1. Application Structure

Create a sample showcase application that demonstrates the UI-Kit in a realistic scenario:

```
showcase/
src/
pages/
LoginPage.tsx # Using AuthShell + form components
DashboardPage.tsx # Using MainLayout + stats components
CustomersPage.tsx # Using MainLayout + DataTable
components/
ProtectedRoute.tsx # Route protection wrapper
Navigation.tsx # App navigation using UI-Kit components
hooks/
useAuth.tsx # Authentication state management
services/
api.ts # Mock API for data
auth.ts # Authentication logic
types/
Customer.ts # Customer data types
Auth.ts # Authentication types
```

### 2. Pages Implementation

**Login Page:**

- Use `AuthShell` layout from UI-Kit
- Login form with `TextInput` and `Button` components
- Form validation using React Hook Form + Zod
- Error handling with `Toast` notifications
- Responsive design following UI-Kit patterns

**Dashboard Page:**

- Use `MainLayout` with navigation and breadcrumbs
- Summary cards showing customer statistics
- Quick action buttons using UI-Kit buttons
- Navigation to customers page
- Use `StatusBadge` for status indicators

**Customers Page:**

- Use `MainLayout` for consistent navigation
- `DataTable` component showing customer list
- Pagination, sorting, and filtering
- Customer actions (view, edit buttons)
- Breadcrumb navigation

### 3. Technical Requirements

**Routing:**

- React Router v7 with data loaders
- Protected routes requiring authentication
- Proper error boundaries and 404 handling
- Clean URL structure

**State Management:**

- Authentication state using Zustand (from UI-Kit)
- Customer data fetching and caching
- Form state management with React Hook Form

**Data Layer:**

- Mock customer data (50+ records)
- Simulated API responses with realistic delays
- Pagination and filtering logic
- Authentication simulation

### 4. Testing Strategy

**E2E Tests (Playwright):**

- Login flow: invalid credentials β†’ error, valid credentials β†’ dashboard
- Navigation: login β†’ dashboard β†’ customers β†’ back to dashboard
- DataTable interactions: pagination, sorting
- Logout functionality
- Responsive behavior testing

**Integration:**

- Component integration with real data
- Form submission and validation flows
- Navigation state persistence
- Error handling scenarios

## Definition of Done

**Original DoD:** "E2E Playwright run (login β†’ dashboard) green in CI."

**Expanded DoD:**

- βœ… Showcase application builds and runs without errors
- βœ… Login page functional with form validation
- βœ… Dashboard page displays with navigation
- βœ… Customers page shows DataTable with pagination
- βœ… E2E Playwright tests pass: login β†’ dashboard β†’ customers flow
- βœ… All UI-Kit components integrated properly
- βœ… Responsive design works on different screen sizes
- βœ… Authentication flow works end-to-end
- βœ… CI pipeline runs tests successfully

## Technical Dependencies

### Required UI-Kit Components:

- `AuthShell` (login page layout)
- `AppShell` (dashboard and customers layout)
- `DataTable` (customers table)
- `TextInput`, `Button` (forms)
- `Toast` (notifications)
- `StatusBadge` (status indicators)

### External Dependencies:

- React Router v7 (routing)
- React Hook Form + Zod (forms)
- Playwright (E2E testing)
- Mock data generation utilities

### Infrastructure:

- Vite setup for showcase app
- Build integration with UI-Kit
- CI/CD pipeline updates
- Development server configuration

## Success Metrics

1. **Functionality:** All user flows work end-to-end
2. **Performance:** Pages load within 2 seconds
3. **Accessibility:** axe-core tests pass on all pages
4. **Testing:** 100% E2E test coverage for critical paths
5. **Integration:** UI-Kit components work seamlessly
6. **Maintainability:** Clean, documented code structure

## Next Steps After Completion

This showcase will serve as:

- Reference implementation for UI-Kit usage
- Testing ground for new components
- Demo for stakeholders and users
- Foundation for future showcase extensions (task 3.5: i18n, task 3.6: SQLite integration)
2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import uiKitRules from './packages/eslint-plugin-ui-kit-rules/index.js';
export default [
// global ignores – applied before other configs
{
ignores: ['packages/ui-kit/dist/**', '**/node_modules/**', '**/storybook-static/**']
ignores: ['packages/ui-kit/dist/**', '**/node_modules/**', '**/storybook-static/**', 'vendors/**', 'packages/showcase/dist/**', '**/dist/**']
},
js.configs.recommended,
...tseslint.configs.recommended,
Expand Down
42 changes: 42 additions & 0 deletions packages/showcase/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';

export default [
// global ignores – applied before other configs
{
ignores: ['dist/**', 'node_modules/**', '../../vendors/**']
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['src/**/*.{js,jsx,ts,tsx}', 'tailwind.config.js', 'vite.config.ts', 'postcss.config.js'],
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
globals: {
module: 'readonly',
require: 'readonly',
process: 'readonly',
console: 'readonly',
window: 'readonly',
document: 'readonly',
navigator: 'readonly'
}
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh
},
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true }
],
'@typescript-eslint/no-require-imports': 'off'
}
}
];
16 changes: 16 additions & 0 deletions packages/showcase/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>UI-Kit Showcase</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>
48 changes: 48 additions & 0 deletions packages/showcase/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@org/showcase",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint .",
"preview": "vite preview",
"test": "vitest run",
"test:e2e": "playwright test"
},
"dependencies": {
"@hookform/resolvers": "^3.6.1",
"@org/ui-kit": "workspace:*",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-hook-form": "^7.56.4",
"react-router": "^7.0.0",
"react-router-dom": "^7.0.0",
"zod": "^3.25.7",
"zustand": "^5.0.4"
},
"devDependencies": {
"@eslint/js": "^9.27.0",
"@playwright/test": "^1.52.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@types/react": "^19.1.4",
"@types/react-dom": "^19.1.5",
"@vitejs/plugin-react": "^4.4.1",
"autoprefixer": "^10.4.21",
"daisyui": "^5.0.35",
"eslint": "^9.27.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"jsdom": "^26.1.0",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1",
"vite": "^5.4.19",
"vitest": "^1.6.1"
}
}
9 changes: 9 additions & 0 deletions packages/showcase/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import tailwindcss from 'tailwindcss';
import autoprefixer from 'autoprefixer';

export default {
plugins: [
tailwindcss,
autoprefixer,
],
};
20 changes: 20 additions & 0 deletions packages/showcase/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { BrowserRouter } from 'react-router';
import { ToastProvider } from '@org/ui-kit';
import { LoginPage } from './pages/LoginPage';

describe('Showcase App', () => {
it('renders LoginPage without crashing', () => {
render(
<BrowserRouter>
<ToastProvider>
<LoginPage />
</ToastProvider>
</BrowserRouter>
);

// Check that the component renders
expect(document.body).toBeTruthy();
});
});
16 changes: 16 additions & 0 deletions packages/showcase/src/components/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Navigate } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';

interface ProtectedRouteProps {
children: React.ReactNode;
}

export function ProtectedRoute({ children }: ProtectedRouteProps) {
const { isAuthenticated } = useAuth();

if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}

return <>{children}</>;
}
Loading