From fda3e3ecbf7cbb3f88ab6ddae0253dc753637906 Mon Sep 17 00:00:00 2001 From: Syco21 Date: Sat, 14 Mar 2026 23:54:37 +0100 Subject: [PATCH] change amount + pictures --- src/App.jsx | 123 ++------------------- src/components/CardRow/CardRow.jsx | 36 ++++++ src/components/PrintingRow/PrintingRow.jsx | 63 +++++++++++ src/main.jsx | 5 +- src/pages/HomePage.jsx | 67 +++++++++++ src/services/api.jsx | 7 ++ src/store/CardContent.js | 0 src/store/CardContext.jsx | 36 ++++++ 8 files changed, 220 insertions(+), 117 deletions(-) create mode 100644 src/components/CardRow/CardRow.jsx create mode 100644 src/components/PrintingRow/PrintingRow.jsx delete mode 100644 src/store/CardContent.js create mode 100644 src/store/CardContext.jsx 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 ( - <> -
-
- - React logo - Vite logo -
-
-

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] ? ( + {expandedCard.name} + ) : ( +

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} + + ); +}