fix: kolo štěstí točí až od dvou možností
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 25s
CI / Build server (push) Successful in 28s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m50s
CI / Build and push Docker image (push) Successful in 46s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 25s
CI / Build server (push) Successful in 28s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m50s
CI / Build and push Docker image (push) Successful in 46s
CI / Notify (push) Successful in 2s
This commit is contained in:
@@ -45,6 +45,8 @@ const WHEEL_SIZE = 360;
|
||||
const RADIUS = WHEEL_SIZE / 2 - 6;
|
||||
const SEGMENT_COLORS = 6;
|
||||
const MAX_LABELED_SEGMENTS = 40;
|
||||
/** Točit má smysl až od dvou možností — jediná zbylá se vybere rovnou. */
|
||||
const MIN_SPIN_ITEMS = 2;
|
||||
|
||||
/** Kryptograficky náhodný index v rozsahu 0..n-1 (bez modulo zkreslení to u malých n nevadí). */
|
||||
function randomIndex(n: number): number {
|
||||
@@ -198,9 +200,17 @@ export default function SpinWheelModal({ isOpen, onClose, menus, onPick }: Reado
|
||||
setRotation(r => r % 360);
|
||||
};
|
||||
|
||||
// Zbyla jediná možnost — není co losovat, vybere se rovnou (lze pokračovat dál / převzít)
|
||||
const onlyOne = wheelItems.length === 1;
|
||||
useEffect(() => {
|
||||
if (spinning || !onlyOne) return;
|
||||
if (phase === 'place' && place?.id !== places[0].id) setPlace(places[0]);
|
||||
else if (phase === 'dish' && dish?.name !== dishes[0].name) setDish(dishes[0]);
|
||||
}, [onlyOne, phase, places, dishes, spinning, place?.id, dish?.name]);
|
||||
|
||||
const spin = () => {
|
||||
const n = wheelItems.length;
|
||||
if (n === 0 || spinning) return;
|
||||
if (n < MIN_SPIN_ITEMS || spinning) return;
|
||||
const index = randomIndex(n);
|
||||
const angle = 360 / n;
|
||||
const jitter = (Math.random() - 0.5) * angle * 0.6;
|
||||
@@ -337,17 +347,21 @@ export default function SpinWheelModal({ isOpen, onClose, menus, onPick }: Reado
|
||||
)}
|
||||
<div className={`spin-result${result ? ' visible' : ''}`} aria-live="polite">
|
||||
{result && (phase === 'place'
|
||||
? <>Padlo: <strong>{place!.label}</strong> <small>({place!.kind === 'menu' ? 'dnešní menu' : 'rozvoz'})</small></>
|
||||
: <>Padlo: <strong>{dish!.name}</strong>{dish!.price && <small> ({dish!.price})</small>}</>)}
|
||||
? <>{onlyOne ? 'Zbývá jediná možnost' : 'Padlo'}: <strong>{place!.label}</strong> <small>({place!.kind === 'menu' ? 'dnešní menu' : 'rozvoz'})</small></>
|
||||
: <>{onlyOne ? 'Zbývá jediné jídlo' : 'Padlo'}: <strong>{dish!.name}</strong>{dish!.price && <small> ({dish!.price})</small>}</>)}
|
||||
</div>
|
||||
<div className="spin-actions">
|
||||
<Button onClick={spin} disabled={spinning || wheelItems.length === 0} className="spin-button">
|
||||
{spinning ? 'Točí se…' : result ? 'Točit znovu' : 'Roztočit!'}
|
||||
<Button onClick={spin} disabled={spinning || wheelItems.length < MIN_SPIN_ITEMS} className="spin-button"
|
||||
title={wheelItems.length < MIN_SPIN_ITEMS ? 'Na kole musí být aspoň 2 možnosti' : undefined}>
|
||||
{spinning ? 'Točí se…' : result && !onlyOne ? 'Točit znovu' : 'Roztočit!'}
|
||||
</Button>
|
||||
{result && !spinning && wheelItems.length > 1 && (
|
||||
<Button variant="outline-primary" onClick={removeResultAndRespin}>Vyřadit a točit znovu</Button>
|
||||
)}
|
||||
</div>
|
||||
{onlyOne && (
|
||||
<small className="text-muted">Na kole musí být aspoň 2 možnosti — vrať nějaké vyřazené, nebo pokračuj s touto.</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="spin-options">
|
||||
<div className="spin-options-header">
|
||||
|
||||
Reference in New Issue
Block a user