diff --git a/src/App.jsx b/src/App.jsx
index b2bf2e8..7164935 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,121 +1,12 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from './assets/vite.svg'
-import heroImg from './assets/hero.png'
-import './App.css'
+import React from 'react';
+import HomePage from './pages/HomePage';
function App() {
- const [count, setCount] = useState(0)
-
return (
- <>
-
-
-
-
Get started
-
- Edit src/App.jsx and save to test HMR
-
-
-
-
-
-
-
-
-
-
-
Documentation
-
Your questions, answered
-
-
-
-
-
Connect with us
-
Join the Vite community
-
-
-
-
-
-
- >
- )
+
+
+
+ );
}
-export default App
+export default App;
diff --git a/src/components/CardRow/CardRow.jsx b/src/components/CardRow/CardRow.jsx
new file mode 100644
index 0000000..005304d
--- /dev/null
+++ b/src/components/CardRow/CardRow.jsx
@@ -0,0 +1,36 @@
+import React, { useContext } from 'react';
+import { CardContext } from '../../store/CardContext';
+import PrintingRow from '../PrintingRow/PrintingRow';
+
+function CardRow({ card }) {
+ const { expandedCardId, setExpandedCardId } = useContext(CardContext);
+ const isExpanded = expandedCardId === card.id;
+
+ const toggleExpand = () => setExpandedCardId(isExpanded ? null : card.id);
+
+ return (
+
+
+ {card.name}
+ {card.type}
+
+
+ {isExpanded && card.printings?.length > 0 && (
+
+ {card.printings.map(printing => (
+
+ ))}
+
+ )}
+
+ );
+}
+
+export default CardRow;
diff --git a/src/components/PrintingRow/PrintingRow.jsx b/src/components/PrintingRow/PrintingRow.jsx
new file mode 100644
index 0000000..48d44d0
--- /dev/null
+++ b/src/components/PrintingRow/PrintingRow.jsx
@@ -0,0 +1,63 @@
+import React, { useContext, useState } from 'react';
+import { CardContext } from '../../store/CardContext';
+
+function PrintingRow({ card_id, printing }) {
+ const { ownedAmounts, updateAmount } = useContext(CardContext);
+ const [loading, setLoading] = useState(false);
+
+ // Current amount from context, fallback to DB value
+ const currentAmount = ownedAmounts[card_id]?.[printing.set_id] ?? printing.amount_owned ?? 0;
+
+ const updateBackend = async (newAmount) => {
+ const { set_id, rarity_id } = printing;
+
+ if (card_id == null || set_id == null || rarity_id == null) return;
+
+ setLoading(true);
+ try {
+ const response = await fetch('http://localhost:3000/collection/amount', {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ card_id,
+ set_id,
+ rarity_id,
+ amount_owned: newAmount
+ })
+ });
+
+ if (response.ok) {
+ updateAmount(card_id, set_id, newAmount);
+ }
+ } catch (err) {
+ // silently fail or handle elsewhere
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const increment = () => updateBackend(currentAmount + 1);
+ const decrement = () => {
+ if (currentAmount > 0) updateBackend(currentAmount - 1);
+ };
+
+ return (
+
+
{printing.set_name} {printing.rarity_name}
+
+
+ {currentAmount}
+
+
+
+ );
+}
+
+export default PrintingRow;
diff --git a/src/main.jsx b/src/main.jsx
index b9a1a6d..214265f 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -2,9 +2,12 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
+import { CardProvider } from './store/CardContext' // <-- import your context provider
createRoot(document.getElementById('root')).render(
-
+
+
+
,
)
diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx
index e69de29..a33a15e 100644
--- a/src/pages/HomePage.jsx
+++ b/src/pages/HomePage.jsx
@@ -0,0 +1,67 @@
+import React, { useEffect, useState, useContext } from 'react';
+import CardRow from '../components/CardRow/CardRow';
+import { fetchCards } from '../services/api';
+import { CardContext } from '../store/CardContext';
+
+function HomePage() {
+ const [cards, setCards] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const { expandedCardId, cardImages, setCardImage } = useContext(CardContext);
+
+ useEffect(() => {
+ fetchCards()
+ .then(data => setCards(data))
+ .catch(err => setError(err.message))
+ .finally(() => setLoading(false));
+ }, []);
+
+ // Load image for the currently expanded card
+ useEffect(() => {
+ if (!expandedCardId || cardImages[expandedCardId]) return;
+
+ fetch(`http://localhost:3000/cardImage/${expandedCardId}`)
+ .then(res => res.json())
+ .then(data => {
+ if (data.image) setCardImage(expandedCardId, data.image);
+ })
+ .catch(err => console.error('Failed to load card image', err));
+ }, [expandedCardId, cardImages, setCardImage]);
+
+ if (loading) return Loading cards...
;
+ if (error) return Error: {error}
;
+
+ const expandedCard = cards.find(c => c.id === expandedCardId);
+
+ return (
+
+ {/* Left panel: card list */}
+
+
Card List
+ {cards.map(card => (
+
+ ))}
+
+
+ {/* Right panel: card image */}
+
+
Card Image / Details
+ {expandedCardId && expandedCard ? (
+ cardImages[expandedCardId] ? (
+

+ ) : (
+
Loading image...
+ )
+ ) : (
+
Click a card to see its image
+ )}
+
+
+ );
+}
+
+export default HomePage;
diff --git a/src/services/api.jsx b/src/services/api.jsx
index e69de29..de25629 100644
--- a/src/services/api.jsx
+++ b/src/services/api.jsx
@@ -0,0 +1,7 @@
+const API_BASE = 'http://localhost:3000'; // Backend URL
+
+export async function fetchCards() {
+ const response = await fetch(`${API_BASE}/exportCards`);
+ if (!response.ok) throw new Error('Failed to fetch cards');
+ return await response.json();
+}
diff --git a/src/store/CardContent.js b/src/store/CardContent.js
deleted file mode 100644
index e69de29..0000000
diff --git a/src/store/CardContext.jsx b/src/store/CardContext.jsx
new file mode 100644
index 0000000..8309615
--- /dev/null
+++ b/src/store/CardContext.jsx
@@ -0,0 +1,36 @@
+import React, { createContext, useState } from 'react';
+
+export const CardContext = createContext();
+
+export function CardProvider({ children }) {
+ const [expandedCardId, setExpandedCardId] = useState(null);
+ const [ownedAmounts, setOwnedAmounts] = useState({});
+ const [cardImages, setCardImages] = useState({}); // cache loaded images
+
+ // Use set_id as the key to match backend
+ const updateAmount = (cardId, setId, value) => {
+ setOwnedAmounts(prev => ({
+ ...prev,
+ [cardId]: { ...(prev[cardId] || {}), [setId]: value }
+ }));
+ };
+
+ const setCardImage = (cardId, imageData) => {
+ setCardImages(prev => ({ ...prev, [cardId]: imageData }));
+ };
+
+ return (
+
+ {children}
+
+ );
+}
Connect with us
-Join the Vite community
---
-
-
- GitHub
-
-
- -
-
-
- Discord
-
-
- -
-
-
- X.com
-
-
- -
-
-
- Bluesky
-
-
-
-