Changeset 73b69b2 for chapterx-frontend/src/store/storyStore.ts
- Timestamp:
- 03/24/26 22:13:36 (3 months ago)
- Branches:
- main
- Children:
- 7fbb91c
- Parents:
- acf690c
- File:
-
- 1 edited
-
chapterx-frontend/src/store/storyStore.ts (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
chapterx-frontend/src/store/storyStore.ts
racf690c r73b69b2 25 25 const API = 'https://localhost:7125/api' 26 26 27 function mapReadingList(l: any): ReadingList { 28 return { 29 list_id: l.id, 30 user_id: l.userId, 31 username: l.username ?? '', 32 name: l.name, 33 description: l.content ?? '', 34 is_public: l.isPublic, 35 created_at: l.createdAt, 36 stories: (l.readingListItems ?? []).map((i: any) => ({ 37 item_id: i.listId ?? 0, 38 list_id: l.id, 39 story_id: i.storyId, 40 story_title: i.storyTitle ?? `Story #${i.storyId}`, 41 author_username: i.authorUsername ?? '', 42 added_at: i.addedAt ?? new Date().toISOString(), 43 genres: i.genres ?? [], 44 })), 45 } 46 } 47 27 48 function getAuthHeaders() { 28 49 try { … … 53 74 fetchChapters: () => Promise<void> 54 75 fetchReadingLists: () => Promise<void> 76 fetchUserReadingLists: (userId: number) => Promise<void> 77 fetchGenres: () => Promise<void> 55 78 56 79 // Story actions … … 86 109 87 110 // Genre actions 88 addGenre: ( genre: Genre) => void89 deleteGenre: (id: number) => void111 addGenre: (name: string) => Promise<void> 112 deleteGenre: (id: number) => Promise<void> 90 113 91 114 // Reading list actions … … 103 126 aiSuggestions: [...mockAISuggestions], 104 127 genres: [...mockGenres], 105 readingLists: [ ...mockReadingLists],128 readingLists: [], 106 129 likedStories: [], 107 130 … … 118 141 mature_content: s.matureContent, 119 142 status: 'published' as StoryStatus, 120 author_username: '',143 author_username: s.writer?.user?.username ?? '', 121 144 created_at: s.createdAt, 122 145 updated_at: s.updatedAt, … … 125 148 total_chapters: 0, 126 149 total_views: 0, 127 genres: [],150 genres: (s.hasGenres ?? []).map((hg: any) => hg.genre?.name ?? hg.name).filter(Boolean), 128 151 })) 129 152 if (stories.length > 0) set({ stories }) … … 159 182 const res = await axios.post(`${API}/stories`, { 160 183 matureContent: story.mature_content, 161 shortDescription: story. title || story.short_description,184 shortDescription: story.short_description || story.title, 162 185 image: null, 163 186 content: story.content, 164 187 userId: story.user_id, 188 genres: story.genres ?? [], 165 189 }, { headers: getAuthHeaders() }) 166 190 const backendId = res.data?.id ?? res.data … … 443 467 }, 444 468 445 addGenre: (genre) => 446 set(state => ({ genres: [...state.genres, genre] })), 447 448 deleteGenre: (id) => 449 set(state => ({ genres: state.genres.filter(g => g.genre_id !== id) })), 469 fetchGenres: async () => { 470 try { 471 const res = await axios.get(`${API}/genres`) 472 const data: any[] = res.data?.genres ?? res.data ?? [] 473 const genres: Genre[] = data.map((g: any) => ({ genre_id: g.id, name: g.name })) 474 if (genres.length > 0) set({ genres }) 475 } catch { 476 // keep mock data on failure 477 } 478 }, 479 480 addGenre: async (name) => { 481 const res = await axios.post(`${API}/genres`, { name }, { headers: getAuthHeaders() }) 482 const id = res.data?.id ?? res.data 483 set(state => ({ genres: [...state.genres, { genre_id: id, name }] })) 484 }, 485 486 deleteGenre: async (id) => { 487 set(state => ({ genres: state.genres.filter(g => g.genre_id !== id) })) 488 try { 489 await axios.delete(`${API}/genres/${id}`, { headers: getAuthHeaders() }) 490 } catch { 491 // optimistic delete already applied 492 } 493 }, 450 494 451 495 fetchReadingLists: async () => { 452 496 try { 453 const [listsRes, storiesRes] = await Promise.all([ 454 axios.get(`${API}/readinglists`), 455 axios.get(`${API}/stories`), 456 ]) 457 const data: any[] = listsRes.data?.readingLists ?? listsRes.data ?? [] 458 const storiesData: any[] = storiesRes.data?.stories ?? storiesRes.data ?? [] 459 const lists: ReadingList[] = data.map((l: any) => ({ 460 list_id: l.id, 461 user_id: l.userId, 462 username: '', 463 name: l.name, 464 description: l.content ?? '', 465 is_public: l.isPublic, 466 created_at: l.createdAt, 467 stories: (l.readingListItems ?? []).map((i: any) => { 468 const story = storiesData.find((s: any) => s.id === i.storyId) 469 return { 470 item_id: i.id ?? 0, 471 list_id: l.id, 472 story_id: i.storyId, 473 story_title: story?.title ?? story?.shortDescription ?? `Story #${i.storyId}`, 474 author_username: story?.authorUsername ?? '', 475 added_at: i.addedAt ?? new Date().toISOString(), 476 genres: story?.genres ?? [], 477 } 478 }), 479 })) 480 if (lists.length > 0) set({ readingLists: lists }) 481 } catch { 482 // keep mock data on failure 497 const res = await axios.get(`${API}/readinglists`) 498 const data: any[] = res.data ?? [] 499 const lists: ReadingList[] = data.map(mapReadingList) 500 set({ readingLists: lists }) 501 } catch { 502 // keep existing data on failure 503 } 504 }, 505 506 fetchUserReadingLists: async (userId) => { 507 try { 508 const res = await axios.get(`${API}/readinglists/user/${userId}`, { headers: getAuthHeaders() }) 509 const data: any[] = res.data ?? [] 510 const lists: ReadingList[] = data.map(mapReadingList) 511 set(state => ({ 512 readingLists: [ 513 ...state.readingLists.filter(l => l.user_id !== userId), 514 ...lists, 515 ] 516 })) 517 } catch (err) { 518 console.error('fetchUserReadingLists failed:', err) 483 519 } 484 520 }, … … 525 561 })) 526 562 try { 527 // find the item id from backend list items to delete 528 const res = await axios.get(`${API}/readinglistitems`) 529 const items: any[] = res.data?.readingListItems ?? res.data ?? [] 530 const item = items.find((i: any) => i.readingListId === listId && i.storyId === storyId) 531 if (item) await axios.delete(`${API}/readinglistitems/${item.id}`, { headers: getAuthHeaders() }) 563 await axios.delete(`${API}/readinglistitems/${listId}/story/${storyId}`, { headers: getAuthHeaders() }) 532 564 } catch { 533 565 // optimistic update already applied
Note:
See TracChangeset
for help on using the changeset viewer.
