Changeset 7fbb91c for chapterx-frontend/src/pages
- Timestamp:
- 03/24/26 23:03:39 (3 months ago)
- Branches:
- main
- Children:
- a7550ca
- Parents:
- 73b69b2
- Location:
- chapterx-frontend/src/pages
- Files:
-
- 2 edited
-
story/StoryDetailPage.tsx (modified) (3 diffs)
-
writer/WriterDashboard.tsx (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
chapterx-frontend/src/pages/story/StoryDetailPage.tsx
r73b69b2 r7fbb91c 102 102 103 103 const isOwner = currentUser?.user_id === story.user_id 104 const isCollaborator = currentUser ? storyCollabs.some(c => c.user_id === currentUser.user_id) : false 104 105 105 106 return ( … … 162 163 </Button> 163 164 )} 164 { isOwner&& (165 {(isOwner || isCollaborator) && ( 165 166 <Button variant="ghost" size="sm" onClick={() => navigate(`/writer/edit-story/${story.story_id}`)}> 166 167 Edit Story … … 173 174 <div className="flex items-center justify-between mb-4"> 174 175 <h2 className="font-serif text-xl font-bold text-white">Chapters</h2> 175 { isOwner&& (176 {(isOwner || isCollaborator) && ( 176 177 <Button size="sm" onClick={() => navigate(`/writer/create-chapter/${story.story_id}`)}> 177 178 <Plus size={14} /> -
chapterx-frontend/src/pages/writer/WriterDashboard.tsx
r73b69b2 r7fbb91c 22 22 const navigate = useNavigate() 23 23 const { currentUser } = useAuthStore() 24 const { stories } = useStoryStore()24 const { stories, collaborations } = useStoryStore() 25 25 const { notifications } = useNotificationStore() 26 26 27 27 if (!currentUser) return null 28 28 29 const myStories = stories.filter(s => s.user_id === currentUser.user_id) 29 const ownedStories = stories.filter(s => s.user_id === currentUser.user_id) 30 const collabStoryIds = new Set(collaborations.filter(c => c.user_id === currentUser.user_id).map(c => c.story_id)) 31 const collabStories = stories.filter(s => collabStoryIds.has(s.story_id)) 32 const myStories = ownedStories 33 const allDashboardStories = [...ownedStories, ...collabStories] 30 34 const published = myStories.filter(s => s.status === 'published') 31 35 const drafts = myStories.filter(s => s.status === 'draft') … … 76 80 <h2 className="font-serif text-xl font-bold text-white">My Stories</h2> 77 81 </div> 78 { myStories.length === 0 ? (82 {allDashboardStories.length === 0 ? ( 79 83 <div className="bg-slate-800 border border-slate-700 rounded-2xl p-12 text-center"> 80 84 <BookOpen size={40} className="mx-auto mb-4 text-slate-600" /> … … 88 92 ) : ( 89 93 <div className="space-y-3"> 90 {myStories.map(story => ( 91 <div key={story.story_id} className="flex items-center gap-4 p-4 bg-slate-800 border border-slate-700 rounded-xl hover:border-indigo-500/40 transition-colors"> 92 <div className="flex-1 min-w-0"> 93 <div className="flex items-center gap-2 mb-1"> 94 <h3 className="text-white font-medium text-sm truncate">{story.title}</h3> 95 <StatusBadge status={story.status} /> 94 {allDashboardStories.map(story => { 95 const isCollab = collabStoryIds.has(story.story_id) 96 return ( 97 <div key={story.story_id} className="flex items-center gap-4 p-4 bg-slate-800 border border-slate-700 rounded-xl hover:border-indigo-500/40 transition-colors"> 98 <div className="flex-1 min-w-0"> 99 <div className="flex items-center gap-2 mb-1"> 100 <h3 className="text-white font-medium text-sm truncate">{story.title}</h3> 101 <StatusBadge status={story.status} /> 102 {isCollab && ( 103 <span className="px-2 py-0.5 text-xs font-medium rounded-full bg-violet-500/20 text-violet-400 border border-violet-500/30"> 104 Collaborator 105 </span> 106 )} 107 </div> 108 <div className="flex items-center gap-3 text-slate-500 text-xs"> 109 {isCollab && <span className="text-slate-500">by {story.author_username}</span>} 110 <span className="flex items-center gap-1"><Eye size={11} /> {story.total_views.toLocaleString()}</span> 111 <span className="flex items-center gap-1"><Heart size={11} /> {story.total_likes}</span> 112 <span className="flex items-center gap-1"><MessageCircle size={11} /> {story.total_comments}</span> 113 <span>{story.total_chapters} chapters</span> 114 </div> 96 115 </div> 97 <div className="flex items-center gap-3 text-slate-500 text-xs"> 98 <span className="flex items-center gap-1"><Eye size={11} /> {story.total_views.toLocaleString()}</span> 99 <span className="flex items-center gap-1"><Heart size={11} /> {story.total_likes}</span> 100 <span className="flex items-center gap-1"><MessageCircle size={11} /> {story.total_comments}</span> 101 <span>{story.total_chapters} chapters</span> 116 <div className="flex gap-2 flex-shrink-0"> 117 <Button size="sm" variant="ghost" onClick={() => navigate(`/story/${story.story_id}`)}>View</Button> 118 <Button size="sm" variant="secondary" onClick={() => navigate(`/writer/edit-story/${story.story_id}`)}>Edit</Button> 102 119 </div> 103 120 </div> 104 <div className="flex gap-2 flex-shrink-0"> 105 <Button size="sm" variant="ghost" onClick={() => navigate(`/story/${story.story_id}`)}>View</Button> 106 <Button size="sm" variant="secondary" onClick={() => navigate(`/writer/edit-story/${story.story_id}`)}>Edit</Button> 107 </div> 108 </div> 109 ))} 121 ) 122 })} 110 123 </div> 111 124 )}
Note:
See TracChangeset
for help on using the changeset viewer.
