100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import InputError from '@/components/InputError';
|
|
import { csrfToken } from '@/lib/utils';
|
|
import { LoaderCircle } from 'lucide-react';
|
|
import { FormEventHandler, useState } from 'react';
|
|
|
|
interface OnboardingFlowProps {
|
|
onComplete?: () => void;
|
|
}
|
|
|
|
export default function OnboardingFlow({ onComplete }: OnboardingFlowProps) {
|
|
const [startingValue, setStartingValue] = useState('0');
|
|
const [processing, setProcessing] = useState(false);
|
|
const [error, setError] = useState<string | undefined>();
|
|
|
|
const submit: FormEventHandler = async (e) => {
|
|
e.preventDefault();
|
|
setProcessing(true);
|
|
setError(undefined);
|
|
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': csrfToken(),
|
|
Accept: 'application/json',
|
|
};
|
|
|
|
try {
|
|
const trackerResponse = await fetch(route('tracker.store'), {
|
|
method: 'POST',
|
|
headers,
|
|
body: JSON.stringify({}),
|
|
});
|
|
|
|
if (!trackerResponse.ok && trackerResponse.status !== 409) {
|
|
setError('Could not create the counter. Please try again.');
|
|
return;
|
|
}
|
|
|
|
const count = Number(startingValue);
|
|
|
|
if (count > 0) {
|
|
const countResponse = await fetch('/count', {
|
|
method: 'PATCH',
|
|
headers,
|
|
body: JSON.stringify({ count }),
|
|
});
|
|
|
|
if (!countResponse.ok) {
|
|
setError('Could not save the starting value. Please try again.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
onComplete?.();
|
|
} catch {
|
|
setError('Something went wrong. Please try again.');
|
|
} finally {
|
|
setProcessing(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-black flex items-center justify-center p-4">
|
|
<div className="w-full max-w-md">
|
|
<div className="border-2 border-red-500 bg-black shadow-[0_0_20px_rgba(239,68,68,0.3)] p-8">
|
|
<form onSubmit={submit} className="space-y-4">
|
|
<Label
|
|
htmlFor="starting-value"
|
|
className="text-red-400 font-mono text-xs uppercase tracking-wider"
|
|
>
|
|
> Starting Value
|
|
</Label>
|
|
<Input
|
|
id="starting-value"
|
|
type="number"
|
|
min="0"
|
|
step="1"
|
|
autoFocus
|
|
value={startingValue}
|
|
onChange={(e) => setStartingValue(e.target.value)}
|
|
className="bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red"
|
|
/>
|
|
<InputError message={error} />
|
|
|
|
<Button
|
|
type="submit"
|
|
disabled={processing || startingValue === ''}
|
|
className="w-full bg-red-500 hover:bg-red-500 text-black font-mono text-sm font-bold border-red-500 rounded-none border-2 uppercase tracking-wider transition-all glow-red"
|
|
>
|
|
{processing && <LoaderCircle className="mr-2 h-4 w-4 animate-spin" />}
|
|
[INITIALIZE]
|
|
</Button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|