bigtech-sucks/packages/web/src/hooks/useGameState.ts

91 lines
2.3 KiB
TypeScript
Raw Normal View History

import { useCallback, useMemo, useState } from 'react';
import {
advanceCapture,
buildSovereigntyReport,
computeOffRamp,
createInitialState,
persistToVault,
selectOutlaws,
setPhase,
transitionAfterShowdown,
type LoginMethod,
type PlayerJourneyState,
} from '@bigtech-sucks/core';
export function useGameState() {
const [state, setState] = useState<PlayerJourneyState>(() => createInitialState());
const report = useMemo(
() => buildSovereigntyReport(state.selectedOutlaws, state.loginMethod),
[state.selectedOutlaws, state.loginMethod],
);
const offRamp = useMemo(
() => (state.selectedOutlaws.length ? computeOffRamp(state.selectedOutlaws) : null),
[state.selectedOutlaws],
);
const vaultExport = useMemo(() => persistToVault(state), [state]);
const login = useCallback((method: LoginMethod) => {
setState((s) => ({ ...s, loginMethod: method }));
}, []);
const goToPhase = useCallback((phase: PlayerJourneyState['phase']) => {
setState((s) => setPhase(s, phase));
}, []);
const drawLine = useCallback((ids: string[]) => {
setState((s) => selectOutlaws(s, ids));
}, []);
const startShowdown = useCallback((outlawId: string) => {
setState((s) => setPhase({ ...s, activeOutlawId: outlawId }, 'showdown'));
}, []);
const showdownStep = useCallback(
(step: 'round_up' | 'validate' | 'cut') => {
setState((s) => {
if (!s.activeOutlawId) return s;
const advanced = advanceCapture(s, s.activeOutlawId, step);
if (step === 'cut') {
return transitionAfterShowdown(advanced);
}
return advanced;
});
},
[],
);
const submitWaitlist = useCallback(async (email: string, channel: string) => {
const payload = {
email,
channel,
settlerSince: state.settlerSince,
};
const res = await fetch('/api/waitlist', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!res.ok) throw new Error('Waitlist submission failed');
setState((s) => ({ ...s, waitlistEmail: email, waitlistChannel: channel }));
return payload;
}, [state.settlerSince]);
return {
state,
report,
offRamp,
vaultExport,
login,
goToPhase,
drawLine,
startShowdown,
showdownStep,
submitWaitlist,
};
}