This commit is contained in:
Lars Behrends
2026-04-09 12:46:32 +02:00
parent dda118a2f7
commit d6a0aac5f7
29 changed files with 1182 additions and 4005 deletions

View File

@@ -12,7 +12,7 @@ import CastView from './components/CastView';
import CastDetailView from './components/CastDetailView';
import { MOCK_MEDIA, DETAIL_MEDIA } from './data';
import { Media, Staff, MediaCategory } from './types';
import { fetchMediaFromLocalJson, fetchMediaById } from './api';
import { fetchAllMedia, fetchMediaById } from './api';
export default function App() {
const [currentView, setCurrentView] = useState<'browse' | 'detail' | 'cast' | 'castDetail'>('browse');
@@ -24,19 +24,19 @@ export default function App() {
const [customMedia, setCustomMedia] = useState<Media[]>([]);
const [adultMedia, setAdultMedia] = useState<Media[]>([]);
// Load adult media on component mount
// Load media from API on component mount
const [apiMedia, setApiMedia] = useState<Media[]>([]);
useEffect(() => {
const loadAdultMedia = async () => {
const loadMediaFromApi = async () => {
try {
const media = await fetchMediaFromLocalJson();
// Add category to adult media
const categorizedMedia = media.map(m => ({ ...m, category: 'Adult' as MediaCategory }));
setAdultMedia(categorizedMedia);
const media = await fetchAllMedia();
setApiMedia(media);
} catch (error) {
console.error('Failed to load adult media:', error);
console.error('Failed to load media from API:', error);
}
};
loadAdultMedia();
loadMediaFromApi();
}, []);
const toggleCategory = (category: MediaCategory) => {
@@ -62,23 +62,52 @@ export default function App() {
};
const allMedia = useMemo(() => {
// Merge mock media, adult media, detail media and custom media
const list = [...MOCK_MEDIA, ...adultMedia, ...customMedia];
// Use API data if available, otherwise fall back to mock data
let list: Media[] = [];
if (apiMedia.length > 0) {
// API has data, use it
list = [...apiMedia];
} else {
// API is empty, use mock data as fallback
list = [...MOCK_MEDIA];
}
// Add custom media and detail media
list = [...list, ...customMedia];
if (!list.find(m => m.id === DETAIL_MEDIA.id)) {
list.push(DETAIL_MEDIA);
}
// Filter by active category AND ensure it's enabled
return list.filter(m => m.category === activeCategory && enabledCategories.includes(m.category));
}, [activeCategory, enabledCategories, customMedia, adultMedia]);
}, [activeCategory, enabledCategories, customMedia, apiMedia]);
const handleAddMedia = (newMedia: Media) => {
setCustomMedia(prev => [...prev, newMedia]);
const handleAddMedia = async (newMedia: Media) => {
// Reload all media from API to get the newly added item
try {
const media = await fetchAllMedia();
setApiMedia(media);
} catch (error) {
console.error('Failed to reload media from API:', error);
}
};
const allStaff = useMemo(() => {
const staff: Staff[] = [];
// Use all available media (mock + adult + custom + detail) but filter by enabled categories
const baseList = [...MOCK_MEDIA, ...adultMedia, ...customMedia];
// Use API data if available, otherwise fall back to mock data
let baseList: Media[] = [];
if (apiMedia.length > 0) {
// API has data, use it
baseList = [...apiMedia];
} else {
// API is empty, use mock data as fallback
baseList = [...MOCK_MEDIA];
}
// Add custom media and detail media
baseList = [...baseList, ...customMedia];
if (!baseList.find(m => m.id === DETAIL_MEDIA.id)) {
baseList.push(DETAIL_MEDIA);
}
@@ -95,7 +124,7 @@ export default function App() {
});
});
return staff;
}, [enabledCategories, customMedia, adultMedia]);
}, [enabledCategories, customMedia, apiMedia]);
const filteredMedia = useMemo(() => {
if (!searchQuery.trim()) return allMedia;