incr/resources/js/components/Onboarding/OnboardingFlow.tsx

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"
>
&gt; 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>
);
}