mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 10:09:35 +01:00
Neue TUI-Features:
- Inventar: Lageorte auflisten, anlegen, bearbeiten, (de-)aktivieren
- Produktion: Rezepte auflisten, anlegen, Detail-Ansicht
- Navigation erweitert (Hauptmenü, Routing)
API-Client auf generierte OpenAPI-Typen umgestellt:
- 6 neue Alias-Dateien in @effigenix/types (supplier, category, article,
customer, inventory, production)
- api-client Re-Exports direkt von @effigenix/types statt via Resources
- Backend: @Schema(requiredProperties) auf 16 Response-Records
- Backend: OpenApiCustomizer für application-layer DTOs (UserDTO, RoleDTO)
Hinweis: Backend-Endpoints für GET /api/recipes und
GET /api/inventory/storage-locations/{id} fehlen noch (separate Issues).
106 lines
2.7 KiB
TypeScript
106 lines
2.7 KiB
TypeScript
import React, { createContext, useContext, useReducer } from 'react';
|
|
|
|
export type Screen =
|
|
| 'login'
|
|
| 'main-menu'
|
|
| 'user-list'
|
|
| 'user-create'
|
|
| 'user-detail'
|
|
| 'change-password'
|
|
| 'role-list'
|
|
| 'role-detail'
|
|
// Stammdaten
|
|
| 'masterdata-menu'
|
|
| 'category-list'
|
|
| 'category-detail'
|
|
| 'category-create'
|
|
| 'supplier-list'
|
|
| 'supplier-detail'
|
|
| 'supplier-create'
|
|
| 'supplier-rate'
|
|
| 'supplier-add-certificate'
|
|
| 'article-list'
|
|
| 'article-detail'
|
|
| 'article-create'
|
|
| 'article-add-sales-unit'
|
|
| 'customer-list'
|
|
| 'customer-detail'
|
|
| 'customer-create'
|
|
| 'customer-add-delivery-address'
|
|
| 'customer-set-preferences'
|
|
// Lagerverwaltung
|
|
| 'inventory-menu'
|
|
| 'storage-location-list'
|
|
| 'storage-location-create'
|
|
| 'storage-location-detail'
|
|
// Produktion
|
|
| 'production-menu'
|
|
| 'recipe-list'
|
|
| 'recipe-create'
|
|
| 'recipe-detail';
|
|
|
|
interface NavigationState {
|
|
current: Screen;
|
|
history: Screen[];
|
|
params: Record<string, string>;
|
|
}
|
|
|
|
type NavigationAction =
|
|
| { type: 'NAVIGATE'; screen: Screen; params?: Record<string, string> }
|
|
| { type: 'BACK' };
|
|
|
|
function navigationReducer(state: NavigationState, action: NavigationAction): NavigationState {
|
|
switch (action.type) {
|
|
case 'NAVIGATE':
|
|
return {
|
|
current: action.screen,
|
|
history: [...state.history, state.current],
|
|
params: action.params ?? {},
|
|
};
|
|
case 'BACK': {
|
|
const history = [...state.history];
|
|
const previous = history.pop();
|
|
if (!previous) return state;
|
|
return { current: previous, history, params: {} };
|
|
}
|
|
}
|
|
}
|
|
|
|
interface NavigationContextValue {
|
|
current: Screen;
|
|
params: Record<string, string>;
|
|
canGoBack: boolean;
|
|
navigate: (screen: Screen, params?: Record<string, string>) => void;
|
|
back: () => void;
|
|
}
|
|
|
|
const NavigationContext = createContext<NavigationContextValue | null>(null);
|
|
|
|
interface NavigationProviderProps {
|
|
children: React.ReactNode;
|
|
initialScreen?: Screen;
|
|
}
|
|
|
|
export function NavigationProvider({ children, initialScreen = 'login' }: NavigationProviderProps) {
|
|
const [state, dispatch] = useReducer(navigationReducer, {
|
|
current: initialScreen,
|
|
history: [],
|
|
params: {},
|
|
});
|
|
|
|
const value: NavigationContextValue = {
|
|
current: state.current,
|
|
params: state.params,
|
|
canGoBack: state.history.length > 0,
|
|
navigate: (screen, params) => dispatch({ type: 'NAVIGATE', screen, params: params ?? {} }),
|
|
back: () => dispatch({ type: 'BACK' }),
|
|
};
|
|
|
|
return <NavigationContext.Provider value={value}>{children}</NavigationContext.Provider>;
|
|
}
|
|
|
|
export function useNavigation(): NavigationContextValue {
|
|
const ctx = useContext(NavigationContext);
|
|
if (!ctx) throw new Error('useNavigation must be used within NavigationProvider');
|
|
return ctx;
|
|
}
|