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

161 lines
7.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 { useForm } from '@inertiajs/react';
import { LoaderCircle } from 'lucide-react';
import { FormEventHandler, useState } from 'react';
import ComponentTitle from '@/components/ui/ComponentTitle';
interface TrackerFormData {
label: string;
unit: string;
price_tracking_enabled: string;
symbol: string;
full_name: string;
[key: string]: string;
}
interface CreateTrackerStepProps {
onSuccess: (priceTrackingEnabled: boolean) => void;
}
export default function CreateTrackerStep({ onSuccess }: CreateTrackerStepProps) {
const [priceTracking, setPriceTracking] = useState(false);
const { data, setData, post, processing, errors } = useForm<TrackerFormData>({
label: '',
unit: '',
price_tracking_enabled: '0',
symbol: '',
full_name: '',
});
const togglePriceTracking = (enabled: boolean) => {
setPriceTracking(enabled);
setData({
...data,
price_tracking_enabled: enabled ? '1' : '0',
symbol: enabled ? data.symbol : '',
full_name: enabled ? data.full_name : '',
});
};
const submit: FormEventHandler = (e) => {
e.preventDefault();
post(route('tracker.store'), {
onSuccess: () => {
onSuccess(priceTracking);
},
});
};
return (
<div className="w-full">
<div className="space-y-4">
<ComponentTitle>SET UP YOUR TRACKER</ComponentTitle>
<p className="text-sm text-red-400/60 font-mono">
[SYSTEM] What are you tracking?
</p>
<form onSubmit={submit} className="space-y-4">
<div>
<Label htmlFor="label" className="text-red-400 font-mono text-xs uppercase tracking-wider">
&gt; Tracker Name
</Label>
<Input
id="label"
type="text"
placeholder="My Portfolio"
value={data.label}
onChange={(e) => setData('label', 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 focus:shadow-[0_0_10px_rgba(239,68,68,0.5)] placeholder:text-red-400/40 transition-all"
/>
<p className="text-xs text-red-400/60 mt-1 font-mono">
[REQUIRED] e.g. "My Portfolio", "Books Read", "KM Run"
</p>
<InputError message={errors.label} />
</div>
<div>
<Label htmlFor="unit" className="text-red-400 font-mono text-xs uppercase tracking-wider">
&gt; Unit
</Label>
<Input
id="unit"
type="text"
placeholder="shares"
value={data.unit}
onChange={(e) => setData('unit', 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 focus:shadow-[0_0_10px_rgba(239,68,68,0.5)] placeholder:text-red-400/40 transition-all"
/>
<p className="text-xs text-red-400/60 mt-1 font-mono">
[REQUIRED] e.g. "shares", "books", "km"
</p>
<InputError message={errors.unit} />
</div>
<div className="border border-red-500/30 p-4 space-y-3">
<label className="flex items-center gap-3 cursor-pointer group">
<input
type="checkbox"
checked={priceTracking}
onChange={(e) => togglePriceTracking(e.target.checked)}
className="w-4 h-4 accent-red-500"
/>
<span className="text-red-400 font-mono text-sm uppercase tracking-wider group-hover:text-red-300">
Enable price tracking
</span>
</label>
<p className="text-red-400/60 font-mono text-xs">
Track market price, portfolio value, and P&amp;L. Requires an asset symbol.
</p>
{priceTracking && (
<div className="space-y-3 pt-2">
<div>
<Label htmlFor="symbol" className="text-red-400 font-mono text-xs uppercase tracking-wider">
&gt; Asset Symbol
</Label>
<Input
id="symbol"
type="text"
placeholder="VWCE"
value={data.symbol}
onChange={(e) => setData('symbol', e.target.value.toUpperCase())}
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 focus:shadow-[0_0_10px_rgba(239,68,68,0.5)] placeholder:text-red-400/40 transition-all"
/>
<InputError message={errors.symbol} />
</div>
<div>
<Label htmlFor="full_name" className="text-red-400 font-mono text-xs uppercase tracking-wider">
&gt; Full Name (Optional)
</Label>
<Input
id="full_name"
type="text"
placeholder="Vanguard FTSE All-World UCITS ETF"
value={data.full_name}
onChange={(e) => setData('full_name', 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 focus:shadow-[0_0_10px_rgba(239,68,68,0.5)] placeholder:text-red-400/40 transition-all"
/>
<InputError message={errors.full_name} />
</div>
</div>
)}
</div>
<Button
type="submit"
disabled={processing || !data.label || !data.unit || (priceTracking && !data.symbol)}
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>
);
}