source: chapterx-frontend/src/pages/reading-list/CommunityListsPage.tsx

main
Last change on this file was 73b69b2, checked in by kikisrbinoska <srbinoskakristina07@…>, 3 months ago

Fixed reading lists,comments and likes

  • Property mode set to 100644
File size: 5.8 KB
Line 
1import React, { useState, useEffect } from 'react'
2import { useNavigate } from 'react-router-dom'
3import { Globe, BookOpen, User } from 'lucide-react'
4import { useStoryStore } from '../../store/storyStore'
5import { ReadingList } from '../../types'
6import { Modal } from '../../components/ui/Modal'
7import { GenreBadge } from '../../components/ui/Badge'
8import { Avatar } from '../../components/ui/Avatar'
9
10export const CommunityListsPage: React.FC = () => {
11 const navigate = useNavigate()
12 const { readingLists, fetchReadingLists } = useStoryStore()
13 const [selectedList, setSelectedList] = useState<ReadingList | null>(null)
14
15 useEffect(() => { fetchReadingLists() }, [])
16
17 const publicLists = readingLists.filter(l => l.is_public)
18
19 return (
20 <div className="max-w-6xl mx-auto px-4 py-8">
21 {/* Header */}
22 <div className="mb-8">
23 <div className="flex items-center gap-2 mb-2">
24 <Globe size={20} className="text-indigo-400" />
25 <h1 className="font-serif text-3xl font-bold text-white">Community Reading Lists</h1>
26 </div>
27 <p className="text-slate-400">Discover curated lists from the ChapterX community</p>
28 </div>
29
30 {publicLists.length === 0 ? (
31 <div className="flex flex-col items-center py-20 text-slate-500">
32 <Globe size={48} className="mb-4 opacity-40" />
33 <p className="text-lg font-medium">No public lists yet</p>
34 <p className="text-sm mt-1">Be the first to share your reading list!</p>
35 </div>
36 ) : (
37 <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
38 {publicLists.map(list => (
39 <div
40 key={list.list_id}
41 className="bg-slate-800 border border-slate-700 rounded-2xl overflow-hidden hover:border-indigo-500/30 transition-all cursor-pointer group"
42 onClick={() => setSelectedList(list)}
43 >
44 {/* Cover preview */}
45 <div className="h-24 bg-gradient-to-br from-indigo-900/50 via-violet-900/30 to-slate-900 p-4 flex items-end">
46 <div className="flex gap-1">
47 {Array.from({ length: Math.min(3, list.stories.length) }).map((_, i) => (
48 <div key={i} className={`w-10 h-14 rounded bg-slate-700 border border-slate-600 -ml-${i > 0 ? '2' : '0'}`} style={{ transform: `rotate(${(i - 1) * 5}deg)` }} />
49 ))}
50 </div>
51 </div>
52
53 <div className="p-5">
54 <div className="flex items-start justify-between gap-2 mb-3">
55 <h3 className="text-white font-semibold group-hover:text-indigo-300 transition-colors">
56 {list.name}
57 </h3>
58 <span className="flex items-center gap-1 text-xs text-emerald-400 flex-shrink-0">
59 <Globe size={11} /> Public
60 </span>
61 </div>
62
63 <div className="flex items-center gap-2 mb-3">
64 <Avatar name={list.username} size="sm" />
65 <span className="text-slate-400 text-sm">@{list.username}</span>
66 </div>
67
68 {list.description && (
69 <p className="text-slate-500 text-sm mb-3 line-clamp-2">{list.description}</p>
70 )}
71
72 <div className="flex items-center justify-between text-xs text-slate-500">
73 <span className="flex items-center gap-1">
74 <BookOpen size={12} />
75 {list.stories.length} stories
76 </span>
77 <button
78 className="text-indigo-400 hover:text-indigo-300 transition-colors"
79 onClick={e => { e.stopPropagation(); setSelectedList(list) }}
80 >
81 View list →
82 </button>
83 </div>
84 </div>
85 </div>
86 ))}
87 </div>
88 )}
89
90 {/* List detail modal */}
91 {selectedList && (
92 <Modal
93 isOpen={!!selectedList}
94 onClose={() => setSelectedList(null)}
95 title={selectedList.name}
96 size="lg"
97 >
98 <div>
99 <div className="flex items-center gap-2 mb-4">
100 <Avatar name={selectedList.username} size="sm" />
101 <div>
102 <p className="text-white text-sm font-medium">@{selectedList.username}</p>
103 <p className="text-slate-500 text-xs">{selectedList.stories.length} stories</p>
104 </div>
105 </div>
106 {selectedList.description && (
107 <p className="text-slate-400 text-sm mb-4">{selectedList.description}</p>
108 )}
109
110 {selectedList.stories.length === 0 ? (
111 <p className="text-slate-500 text-sm text-center py-8">This list is empty.</p>
112 ) : (
113 <div className="space-y-3">
114 {selectedList.stories.map(item => (
115 <div
116 key={item.item_id}
117 className="flex items-center gap-3 p-3 bg-slate-800 rounded-xl border border-slate-700 hover:border-indigo-500/40 cursor-pointer transition-colors"
118 onClick={() => { navigate(`/story/${item.story_id}`); setSelectedList(null) }}
119 >
120 <div className="flex-1 min-w-0">
121 <p className="text-white font-medium text-sm">{item.story_title}</p>
122 <p className="text-slate-500 text-xs">by {item.author_username}</p>
123 </div>
124 <div className="flex flex-wrap gap-1">
125 {item.genres.slice(0, 2).map(g => <GenreBadge key={g} genre={g} />)}
126 </div>
127 </div>
128 ))}
129 </div>
130 )}
131 </div>
132 </Modal>
133 )}
134 </div>
135 )
136}
Note: See TracBrowser for help on using the repository browser.