Stop_smoking_website_ver2/src/components/SavingsSetupDialog.tsx

243 lines
7.7 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { SavingsConfig } from '@/lib/storage';
import { DollarSign, Target } from 'lucide-react';
interface SavingsSetupDialogProps {
open: boolean;
onClose: () => void;
onSave: (config: SavingsConfig) => void;
existingConfig: SavingsConfig | null;
}
const CURRENCIES = [
{ code: 'USD', symbol: '$', name: 'US Dollar' },
{ code: 'EUR', symbol: '€', name: 'Euro' },
{ code: 'GBP', symbol: '£', name: 'British Pound' },
{ code: 'CAD', symbol: 'C$', name: 'Canadian Dollar' },
{ code: 'AUD', symbol: 'A$', name: 'Australian Dollar' },
];
export function SavingsSetupDialog({
open,
onClose,
onSave,
existingConfig,
}: SavingsSetupDialogProps) {
const [costPerUnit, setCostPerUnit] = useState('');
const [unitsPerDay, setUnitsPerDay] = useState('');
const [currency, setCurrency] = useState('');
const [substance, setSubstance] = useState<'nicotine' | 'weed' | ''>('');
const [savingsGoal, setSavingsGoal] = useState('');
const [goalName, setGoalName] = useState('');
useEffect(() => {
if (existingConfig) {
setCostPerUnit(existingConfig.costPerUnit.toString());
setUnitsPerDay(existingConfig.unitsPerDay.toString());
setCurrency(existingConfig.currency);
setSubstance(existingConfig.substance);
setSavingsGoal(existingConfig.savingsGoal?.toString() || '');
setGoalName(existingConfig.goalName || '');
} else {
setCostPerUnit('');
setUnitsPerDay('');
setCurrency('');
setSubstance('');
setSavingsGoal('');
setGoalName('');
}
}, [existingConfig, open]);
const handleSave = () => {
const cost = parseFloat(costPerUnit);
const units = parseFloat(unitsPerDay);
if (isNaN(cost) || isNaN(units) || cost <= 0 || units <= 0) {
return;
}
const config: SavingsConfig = {
costPerUnit: cost,
unitsPerDay: units,
currency,
substance: substance as 'nicotine' | 'weed',
savingsGoal: savingsGoal ? parseFloat(savingsGoal) : null,
goalName: goalName.trim() || null,
};
onSave(config);
};
const isValid =
costPerUnit &&
unitsPerDay &&
currency &&
substance &&
parseFloat(costPerUnit) > 0 &&
parseFloat(unitsPerDay) > 0;
return (
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onClose()}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<DollarSign className="h-5 w-5 text-emerald-500" />
{existingConfig ? 'Edit Savings Tracker' : 'Set Up Savings Tracker'}
</DialogTitle>
<DialogDescription>
Enter your usage costs to track how much you&apos;re saving
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
{/* Substance Selection */}
<div className="space-y-2">
<Label>What are you tracking?</Label>
<Select value={substance} onValueChange={(v) => setSubstance(v as 'nicotine' | 'weed')}>
<SelectTrigger>
<SelectValue placeholder="Select substance" />
</SelectTrigger>
<SelectContent>
<SelectItem value="nicotine">Nicotine (Vape/Cigarettes)</SelectItem>
<SelectItem value="weed">Marijuana</SelectItem>
</SelectContent>
</Select>
</div>
{/* Currency Selection */}
<div className="space-y-2">
<Label>Currency</Label>
<Select value={currency} onValueChange={setCurrency}>
<SelectTrigger>
<SelectValue placeholder="Select currency" />
</SelectTrigger>
<SelectContent>
{CURRENCIES.map((curr) => (
<SelectItem key={curr.code} value={curr.code}>
{curr.symbol} {curr.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Cost Per Unit */}
<div className="space-y-2">
<Label htmlFor="costPerUnit">
Cost per pack/cartridge/unit
</Label>
<div className="relative">
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">
{CURRENCIES.find((c) => c.code === currency)?.symbol || '$'}
</span>
<Input
id="costPerUnit"
type="number"
min="0"
step="0.01"
value={costPerUnit}
onChange={(e) => setCostPerUnit(e.target.value)}
className="pl-8"
placeholder="10.00"
/>
</div>
<p className="text-xs text-muted-foreground">
How much does one pack or cartridge cost?
</p>
</div>
{/* Units Per Week */}
<div className="space-y-2">
<Label htmlFor="unitsPerDay">
Packs/vapes per week (before quitting)
</Label>
<Input
id="unitsPerDay"
type="number"
min="0"
step="0.1"
value={unitsPerDay}
onChange={(e) => setUnitsPerDay(e.target.value)}
placeholder="1"
/>
<p className="text-xs text-muted-foreground">
How many packs/vapes did you typically use per week?
</p>
</div>
{/* Optional: Savings Goal */}
<div className="pt-4 border-t space-y-4">
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Target className="h-4 w-4" />
<span>See your real time savings:</span>
</div>
<div className="space-y-2">
<Label htmlFor="savingsGoal">Target amount</Label>
<div className="relative">
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">
{CURRENCIES.find((c) => c.code === currency)?.symbol || '$'}
</span>
<Input
id="savingsGoal"
type="number"
min="0"
step="1"
value={savingsGoal}
onChange={(e) => setSavingsGoal(e.target.value)}
className="pl-8"
placeholder="500"
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="goalName">What are you saving for?</Label>
<Input
id="goalName"
type="text"
value={goalName}
onChange={(e) => setGoalName(e.target.value)}
placeholder="e.g., New Phone, Vacation"
/>
</div>
</div>
{/* Actions */}
<div className="flex gap-2 pt-4">
<Button onClick={onClose} variant="outline" className="flex-1">
Cancel
</Button>
<Button
onClick={handleSave}
disabled={!isValid}
className="flex-1"
>
{existingConfig ? 'Update' : 'Save'}
</Button>
</div>
</div>
</DialogContent>
</Dialog>
);
}