Files
ToBePlayed-Frontend/src/hooks/useSaveBacklogField.js
T
lobo 45f5087227 feat(library): set status and rating in one step (#56)
Library rows: the status badge is a menu that saves at once.
Game page: status and rating in the top card, saved on click.
Status changes and hiding a game show an Undo toast.
Other game actions moved into a "..." menu; split and unlink ask first.
New sorts: name, last played, time to beat; "last synced" is gone.
Page numbers and 44 px touch targets on phones.
2026-10-21 11:09:44 +02:00

46 lines
1.8 KiB
JavaScript

import {useRef, useState} from 'react';
import {useTranslation} from 'react-i18next';
import {toast} from 'sonner';
import {saveBacklogEntry, toBacklogRequest} from '../utils/backlog.js';
/**
* Returns `{save, pending, busy}`. `save(field, value)` sends that one field (PATCH .../backlog; 0 or NONE clear it),
* shows the saved or error toast and calls `onSaved(entry)` with the whole saved entry. One request at a time: a call
* while one runs does nothing. Resolves to true when saved.
*
* `pending` is `{field, value}` while saving, else null. Show `pending.value` for that field meanwhile: a failed save
* then falls back to the saved value by itself.
*/
export default function useSaveBacklogField(appid, {onSaved} = {}) {
const {t} = useTranslation();
const [pending, setPending] = useState(null);
const running = useRef(false);
const save = async (field, value) => {
if (running.current) return false;
running.current = true;
setPending({field, value});
try {
const response = await saveBacklogEntry(appid, {[field]: toBacklogRequest({[field]: value})[field]});
if (response.status === 401) return false;
if (!response.ok) {
toast.error(t('BACKLOG.SAVE_FAILED'));
return false;
}
const entry = await response.json();
onSaved?.(entry);
toast.success(t('BACKLOG.SAVED'));
return true;
} catch (err) {
console.error('backlog save error:', err);
toast.error(t('INFO.ERROR.NETWORK_FAILURE'));
return false;
} finally {
running.current = false;
setPending(null);
}
};
return {save, pending, busy: pending !== null};
}