Optimistic updates for +/- buttons, UI responds instantly
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -1,24 +1,21 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { CardContext } from '../../context/CardContext';
|
||||
import { updateCardAmount } from '../../services/api';
|
||||
|
||||
function PrintingRow({ card_id, printing, cols, zebra }) {
|
||||
const { ownedAmounts, updateAmount } = useContext(CardContext);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const key = `${printing.set_id}-${printing.rarity_id}`;
|
||||
const current = ownedAmounts[card_id]?.[key] ?? printing.amount_owned ?? 0;
|
||||
|
||||
const save = async (next) => {
|
||||
if (card_id == null || printing.set_id == null || printing.rarity_id == null) return;
|
||||
setLoading(true);
|
||||
updateAmount(card_id, key, next);
|
||||
try {
|
||||
await updateCardAmount(card_id, printing.set_id, printing.rarity_id, next);
|
||||
updateAmount(card_id, key, next);
|
||||
} catch (err) {
|
||||
console.error('Failed to update amount', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
updateAmount(card_id, key, current);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,7 +23,7 @@ function PrintingRow({ card_id, printing, cols, zebra }) {
|
||||
<div style={{
|
||||
display: 'grid', gridTemplateColumns: cols,
|
||||
gap: '8px', padding: '7px 16px 7px 32px',
|
||||
alignItems: 'center', opacity: loading ? 0.5 : 1,
|
||||
alignItems: 'center',
|
||||
background: zebra ? '#1e1e1e' : '#161616',
|
||||
}}>
|
||||
<span style={{ fontFamily: 'monospace', fontSize: '11px', color: '#555' }}>
|
||||
@@ -35,19 +32,11 @@ function PrintingRow({ card_id, printing, cols, zebra }) {
|
||||
<span style={{ fontSize: '12px', color: '#888' }}>{printing.set_name}</span>
|
||||
<span style={{ fontSize: '12px', color: '#aaa' }}>{printing.rarity_name}</span>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
|
||||
<button
|
||||
className="icon-btn"
|
||||
onClick={() => current > 0 && save(current - 1)}
|
||||
disabled={loading || current === 0}
|
||||
>−</button>
|
||||
<button className="icon-btn" onClick={() => current > 0 && save(current - 1)} disabled={current === 0}>−</button>
|
||||
<span style={{ minWidth: '20px', textAlign: 'center', color: '#e0e0e0', fontSize: '13px' }}>
|
||||
{current}
|
||||
</span>
|
||||
<button
|
||||
className="icon-btn"
|
||||
onClick={() => save(current + 1)}
|
||||
disabled={loading}
|
||||
>+</button>
|
||||
<button className="icon-btn" onClick={() => save(current + 1)}>+</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user