1import { useState, useEffect, useCallback } from "react";
2import { Folder, Plus } from "lucide-react";
3import { getCollections } from "../api/client";
4import { useAuth } from "../context/AuthContext";
5import CollectionModal from "../components/CollectionModal";
6import CollectionRow from "../components/CollectionRow";
7
8export default function Collections() {
9 const { user } = useAuth();
10 const [collections, setCollections] = useState([]);
11 const [loading, setLoading] = useState(true);
12 const [error, setError] = useState(null);
13 const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
14 const [editingCollection, setEditingCollection] = useState(null);
15
16 const fetchCollections = useCallback(async () => {
17 try {
18 setLoading(true);
19 const data = await getCollections(user.did);
20 setCollections(data.items || []);
21 } catch (err) {
22 console.error(err);
23 setError("Failed to load collections");
24 } finally {
25 setLoading(false);
26 }
27 }, [user]);
28
29 useEffect(() => {
30 if (user) {
31 fetchCollections();
32 }
33 }, [user, fetchCollections]);
34
35 const handleCreateSuccess = () => {
36 fetchCollections();
37 setIsCreateModalOpen(false);
38 setEditingCollection(null);
39 };
40
41 if (loading) {
42 return (
43 <div className="feed-page">
44 <div
45 style={{
46 display: "flex",
47 justifyContent: "center",
48 padding: "60px 0",
49 }}
50 >
51 <div className="spinner"></div>
52 </div>
53 </div>
54 );
55 }
56
57 return (
58 <div className="feed-page">
59 <div
60 className="page-header"
61 style={{
62 display: "flex",
63 justifyContent: "space-between",
64 alignItems: "flex-start",
65 }}
66 >
67 <div>
68 <h1 className="page-title">Collections</h1>
69 <p className="page-description">
70 Organize your annotations, highlights, and bookmarks
71 </p>
72 </div>
73 <button
74 onClick={() => setIsCreateModalOpen(true)}
75 className="btn btn-primary"
76 >
77 <Plus size={20} />
78 New Collection
79 </button>
80 </div>
81
82 {error ? (
83 <div className="empty-state card">
84 <div className="empty-state-icon">⚠️</div>
85 <h3 className="empty-state-title">Something went wrong</h3>
86 <p className="empty-state-text">{error}</p>
87 </div>
88 ) : collections.length === 0 ? (
89 <div className="empty-state card">
90 <div className="empty-state-icon">
91 <Folder size={32} />
92 </div>
93 <h3 className="empty-state-title">No collections yet</h3>
94 <p className="empty-state-text mb-6">
95 Create your first collection to start organizing your web
96 annotations.
97 </p>
98 <button
99 onClick={() => setIsCreateModalOpen(true)}
100 className="btn btn-secondary"
101 >
102 Create Collection
103 </button>
104 </div>
105 ) : (
106 <div className="collections-list">
107 {collections.map((collection) => (
108 <CollectionRow
109 key={collection.uri}
110 collection={collection}
111 onEdit={() => setEditingCollection(collection)}
112 />
113 ))}
114 </div>
115 )}
116
117 <CollectionModal
118 isOpen={isCreateModalOpen || !!editingCollection}
119 onClose={() => {
120 setIsCreateModalOpen(false);
121 setEditingCollection(null);
122 }}
123 onSuccess={handleCreateSuccess}
124 collectionToEdit={editingCollection}
125 />
126 </div>
127 );
128}