Use Zustand store; modularize API & routes

Introduce a centralized Zustand store and refactor app state out of App.tsx into src/store/appStore.ts. Modularize API surface by moving media/cast/settings/converters/types into src/lib/api/* and re-exporting from src/api.ts for backward compatibility. Replace inline route helpers with dedicated route components (MediaDetailRoute, CastDetailRoute, CategoryBrowseRoute) and wire CATEGORY_PATHS/PATH_TO_CATEGORY constants. Update AddMediaView UI (icons, layout) and adjust settings/category handling to use DEFAULT_SETTINGS and the store. Add zustand to package.json/package-lock.json and include a new React SKILL.md. Overall changes improve state management, API organization, and route/component separation for better maintainability and code-splitting.
This commit is contained in:
Lars Behrends
2026-04-16 14:53:46 +02:00
parent a407b57006
commit 432416cfc5
22 changed files with 1843 additions and 1342 deletions
@@ -0,0 +1,49 @@
import { useParams } from 'react-router-dom';
import { Media, Staff, MediaCategory } from '../../types';
import BrowseView from '../BrowseView';
interface CategoryBrowseRouteProps {
mediaList: Media[];
onMediaClick: (media: Media) => void;
itemsPerPage?: number;
gridItemSize?: number;
onGridItemSizeChange: (size: number) => void;
loading: boolean;
}
export default function CategoryBrowseRoute({
mediaList,
onMediaClick,
itemsPerPage,
gridItemSize,
onGridItemSizeChange,
loading
}: CategoryBrowseRouteProps) {
const { category } = useParams<{ category: string }>();
// Map URL path to category
const categoryMap: Record<string, MediaCategory> = {
'anime': 'Anime',
'movies': 'Movies',
'tv-series': 'TV Series',
'music': 'Music',
'books': 'Books',
'games': 'Games',
'consoles': 'Consoles',
'adult': 'Adult'
};
const activeCategory = category ? categoryMap[category] : 'Anime';
return (
<BrowseView
mediaList={mediaList}
onMediaClick={onMediaClick}
activeCategory={activeCategory}
itemsPerPage={itemsPerPage}
gridItemSize={gridItemSize}
onGridItemSizeChange={onGridItemSizeChange}
loading={loading}
/>
);
}