diff --git a/pages/api/collections.js b/pages/api/collections.js index bf17d96..2cb1603 100644 --- a/pages/api/collections.js +++ b/pages/api/collections.js @@ -61,7 +61,7 @@ export default async function handler(req, res) { } } else if (req.method === 'POST') { try { - const { name, description, tcg = 'MTG', visibility = 'private', tags = [] } = req.body; + const { name, description, tcg = 'MTG', visibility = 'private', image = '', tags = [] } = req.body; if (!name || !description) { return res.status(400).json({ error: 'Name and description are required' }); @@ -75,8 +75,8 @@ export default async function handler(req, res) { const userId = 1; const result = await sql` - INSERT INTO collections (name, description, tcg, visibility, tags, user_id) - VALUES (${name}, ${description}, ${tcg}, ${visibility}, ${tags.join(',')}, ${userId}) + INSERT INTO collections (name, description, tcg, visibility, image, tags, user_id) + VALUES (${name}, ${description}, ${tcg}, ${visibility}, ${image}, ${tags.join(',')}, ${userId}) RETURNING * `; diff --git a/pages/collection/[id].js b/pages/collection/[id].js index 9865055..27550d8 100644 --- a/pages/collection/[id].js +++ b/pages/collection/[id].js @@ -114,15 +114,33 @@ export default function CollectionView() { useEffect(() => { if (id) { - // Simulate API call - setTimeout(() => { - setCollection(mockCollection); - setCards(mockCards); - setLoading(false); - }, 500); + fetchCollectionData(); } }, [id]); + const fetchCollectionData = async () => { + try { + const response = await fetch(`/api/collections/${id}`); + if (response.ok) { + const data = await response.json(); + setCollection(data.collection); + setCards(data.cards || []); + } else { + console.error('Failed to fetch collection'); + // Fallback to mock data for now + setCollection(mockCollection); + setCards(mockCards); + } + } catch (error) { + console.error('Error fetching collection:', error); + // Fallback to mock data for now + setCollection(mockCollection); + setCards(mockCards); + } finally { + setLoading(false); + } + }; + const handleCopyLink = async () => { try { await navigator.clipboard.writeText(window.location.href); @@ -514,17 +532,86 @@ export default function CollectionView() { )} - {sortedCards.length === 0 && ( + {cards.length === 0 ? ( + // Empty collection state +
+
šŸƒ
+

+ Start Building Your Collection +

+

+ This collection is empty. Add your first cards to get started! +

+
+ +
+ Or search for specific cards to add to your collection +
+
+ + {/* Quick add section */} +
+

+ Quick Add +

+
+ + +
+
+
+ ) : sortedCards.length === 0 ? ( + // No results for current filters
šŸ”

- No cards found + No cards match your filters

Try adjusting your search or filter criteria

+
- )} + ) : null} {/* Share Modal */} diff --git a/pages/collections.js b/pages/collections.js index 4d0fdb2..133be40 100644 --- a/pages/collections.js +++ b/pages/collections.js @@ -86,14 +86,33 @@ export default function Collections() { const [newCollection, setNewCollection] = useState({ name: '', description: '', - tcg: 'MTG', - isPublic: false, + visibility: 'private', + image: '', tags: [] }); + const [showSuccessModal, setShowSuccessModal] = useState(false); + const [createdCollection, setCreatedCollection] = useState(null); + + const fetchCollections = async () => { + try { + const response = await fetch('/api/collections'); + if (response.ok) { + const data = await response.json(); + setCollections(data); + } else { + console.error('Failed to fetch collections'); + setCollections(sampleCollections); // Fallback to sample data + } + } catch (error) { + console.error('Error fetching collections:', error); + setCollections(sampleCollections); // Fallback to sample data + } finally { + setLoading(false); + } + }; useEffect(() => { - setCollections(sampleCollections); - setLoading(false); + fetchCollections(); }, []); const tcgOptions = [ @@ -119,19 +138,47 @@ export default function Collections() { return acc; }, {}); - const handleCreateCollection = () => { - const newId = Math.max(...collections.map(c => c.id)) + 1; - const collection = { - ...newCollection, - id: newId, - cardCount: 0, - value: 0, - lastViewed: new Date().toISOString().split('T')[0], - createdAt: new Date().toISOString().split('T')[0] - }; - setCollections([collection, ...collections]); - setNewCollection({ name: '', description: '', tcg: 'MTG', isPublic: false, tags: [] }); - setShowCreateModal(false); + const handleCreateCollection = async () => { + try { + const response = await fetch('/api/collections', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: newCollection.name, + description: newCollection.description, + visibility: newCollection.visibility, + image: newCollection.image, + tags: newCollection.tags + }) + }); + + if (response.ok) { + const createdCollection = await response.json(); + setCreatedCollection(createdCollection); + setShowCreateModal(false); + setShowSuccessModal(true); + + // Reset form + setNewCollection({ + name: '', + description: '', + visibility: 'private', + image: '', + tags: [] + }); + + // Refresh collections list + fetchCollections(); + } else { + const error = await response.json(); + alert(error.error || 'Failed to create collection'); + } + } catch (error) { + console.error('Error creating collection:', error); + alert('Network error. Please try again.'); + } }; const handleUpdateCollection = () => { @@ -400,32 +447,33 @@ export default function Collections() {
+ setNewCollection({...newCollection, image: e.target.value})} + placeholder="Enter image URL" + /> +

+ Add a hero image for your collection +

+
+
+
-
- setNewCollection({...newCollection, isPublic: e.target.checked})} - className="mr-2" - /> - -
+ +
+ + + )} + {/* Edit Collection Modal */} {editingCollection && (
diff --git a/scripts/add-image-column.js b/scripts/add-image-column.js new file mode 100755 index 0000000..a76c774 --- /dev/null +++ b/scripts/add-image-column.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +import { config } from 'dotenv'; +import { sql } from '@vercel/postgres'; + +// Load environment variables +config({ path: '.env.local' }); + +async function addImageColumn() { + try { + console.log('šŸ–¼ļø Adding image column to collections table...\n'); + + // Add image column to collections table + await sql` + ALTER TABLE collections + ADD COLUMN IF NOT EXISTS image TEXT + `; + console.log('āœ… Added image column to collections table'); + + console.log('\nšŸŽ‰ Image column added successfully!'); + console.log('\nšŸ“‹ Collections can now have hero images!'); + + } catch (error) { + console.error('āŒ Migration failed:', error.message); + process.exit(1); + } +} + +addImageColumn();