import React, { useState } from 'react';
import { Check, ChevronRight, Clock, HelpCircle, Shield, Wrench, X } from 'lucide-react';
import { CreateItemDTO, Group, LifecycleType } from '../services/types';
interface GuidedCreateModalProps {
isOpen: boolean;
onClose: () => void;
groups: Group[];
onSubmit: (data: CreateItemDTO) => Promise<void>;
preselectedType?: LifecycleType;
}
export const GuidedCreateModal: React.FC<GuidedCreateModalProps> = ({
isOpen,
onClose,
groups,
onSubmit,
preselectedType,
}) => {
const [step, setStep] = useState<1 | 2>(preselectedType ? 2 : 1);
const [selectedType, setSelectedType] = useState<LifecycleType>(preselectedType || 'renewal');
const [name, setName] = useState('');
const [dueDate, setDueDate] = useState('');
const [hasDueDate, setHasDueDate] = useState(true);
const [groupId, setGroupId] = useState<string>('');
const [status, setStatus] = useState<'active' | 'completed'>('active');
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
if (!isOpen) return null;
const handleTypeSelect = (type: LifecycleType) => {
setSelectedType(type);
setStep(2);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!name.trim()) {
setError('Item name is required');
return;
}
try {
setSubmitting(true);
setError(null);
await onSubmit({
name: name.trim(),
lifecycleType: selectedType,
dueDate: hasDueDate && dueDate ? dueDate : undefined,
groupId: groupId ? groupId : null,
status,
});
// reset state
setName('');
setDueDate('');
setGroupId('');
setStatus('active');
setStep(1);
onClose();
} catch (err: unknown) {
setError(err instanceof Error ? err.message : 'Failed to create item');
} finally {
setSubmitting(false);
}
};
const typeConfig: Record<
LifecycleType,
{ title: string; desc: string; icon: React.ReactNode; example: string }
> = {
renewal: {
title: 'Renewal',
desc: 'Legal, financial, or membership expiration milestones',
example: 'e.g. Passport, Auto Insurance, Driver License, Gym Membership',
icon: <Clock className="w-5 h-5 text-indigo-600" />,
},
maintenance: {
title: 'Maintenance',
desc: 'Periodic physical equipment, home, or vehicle care',
example: 'e.g. HVAC Filter Change, Oil & Brake Service, Water Purifier',
icon: <Wrench className="w-5 h-5 text-amber-600" />,
},
warranty: {
title: 'Warranty',
desc: 'Coverage duration for electronics, appliances, and assets',
example: 'e.g. Laptop AppleCare, TV Limited Warranty, Refrigerator 5-Yr',
icon: <Shield className="w-5 h-5 text-emerald-600" />,
},
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/40 backdrop-blur-xs">
<div className="bg-white rounded-xl shadow-xl border border-slate-200 max-w-lg w-full overflow-hidden transition-all">
{/* Header */}
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-100">
<div>
<h2 className="text-base font-semibold text-slate-900">
{step === 1 ? 'Step 1: Choose Lifecycle Type' : `Step 2: Track New ${typeConfig[selectedType].title}`}
</h2>
<p className="text-xs text-slate-500 mt-0.5">
{step === 1
? 'Select which category fits your lifecycle record'
: 'Enter the common fields to begin tracking'}
</p>
</div>
<button
onClick={onClose}
className="p-1.5 text-slate-400 hover:text-slate-700 hover:bg-slate-100 rounded-lg transition-colors"
aria-label="Close dialog"
>
<X className="w-5 h-5" />
</button>
</div>
{/* Step 1: Type Selection */}
{step === 1 && (
<div className="p-6 space-y-3">
{(['renewal', 'maintenance', 'warranty'] as LifecycleType[]).map((type) => {
const item = typeConfig[type];
return (
<button
key={type}
type="button"
onClick={() => handleTypeSelect(type)}
className="w-full text-left p-4 rounded-lg border border-slate-200 hover:border-slate-900 hover:bg-slate-50 transition-all flex items-start gap-4 group"
>
<div className="p-2.5 bg-slate-100 group-hover:bg-white rounded-lg transition-colors shrink-0">
{item.icon}
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between">
<h3 className="text-sm font-semibold text-slate-900">{item.title}</h3>
<ChevronRight className="w-4 h-4 text-slate-400 group-hover:text-slate-900 transition-colors" />
</div>
<p className="text-xs text-slate-600 mt-0.5">{item.desc}</p>
<p className="text-xs text-slate-400 italic mt-1">{item.example}</p>
</div>
</button>
);
})}
</div>
)}
{/* Step 2: Common Fields Form */}
{step === 2 && (
<form onSubmit={handleSubmit} className="p-6 space-y-4">
{error && (
<div className="p-3 bg-red-50 border border-red-200 rounded-lg text-xs text-red-700">
{error}
</div>
)}
{/* Selected type pill / back button */}
<div className="flex items-center justify-between p-2.5 bg-slate-50 border border-slate-200 rounded-lg">
<div className="flex items-center gap-2 text-xs">
{typeConfig[selectedType].icon}
<span className="font-semibold text-slate-900">{typeConfig[selectedType].title}</span>
<span className="text-slate-400">· Guided Mode</span>
</div>
<button
type="button"
onClick={() => setStep(1)}
className="text-xs text-slate-600 hover:text-slate-900 font-medium underline"
>
Change type
</button>
</div>
{/* Common Field: Name */}
<div>
<label htmlFor="item-name" className="block text-xs font-semibold text-slate-800 mb-1">
Name <span className="text-red-600">*</span>
</label>
<input
id="item-name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={typeConfig[selectedType].example.replace('e.g. ', '').split(',')[0]}
className="w-full px-3 py-2 text-sm border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-slate-900 focus:border-transparent"
required
autoFocus
/>
</div>
{/* Common Field: Due Date (optional manual entry) */}
<div>
<div className="flex items-center justify-between mb-1">
<label htmlFor="item-due-date" className="block text-xs font-semibold text-slate-800">
Due Date
</label>
<div className="flex items-center gap-2">
<label className="text-xs text-slate-500 flex items-center gap-1.5 cursor-pointer">
<input
type="checkbox"
checked={hasDueDate}
onChange={(e) => setHasDueDate(e.target.checked)}
className="rounded border-slate-300 text-slate-900 focus:ring-slate-900"
/>
<span>Has specific due date</span>
</label>
</div>
</div>
{hasDueDate ? (
<input
id="item-due-date"
type="date"
value={dueDate}
onChange={(e) => setDueDate(e.target.value)}
className="w-full px-3 py-2 text-sm border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-slate-900"
/>
) : (
<div className="text-xs text-slate-500 bg-slate-50 px-3 py-2 border border-dashed border-slate-200 rounded-lg flex items-center gap-2">
<HelpCircle className="w-3.5 h-3.5 text-slate-400" />
<span>No due date specified (allowed per MVP Decision 29).</span>
</div>
)}
</div>
{/* Destination: Personal vs Group */}
<div>
<label htmlFor="item-group" className="block text-xs font-semibold text-slate-800 mb-1">
Access & Scope
</label>
<select
id="item-group"
value={groupId}
onChange={(e) => setGroupId(e.target.value)}
className="w-full px-3 py-2 text-sm border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-slate-900 bg-white"
>
<option value="">Personal (Only you)</option>
{groups.map((group) => (
<option key={group.id} value={group.id}>
Group: {group.name}
</option>
))}
</select>
<p className="text-[11px] text-slate-500 mt-1">
Group items are shared with all members of that group.
</p>
</div>
{/* Status (Active / Completed) */}
<div>
<label className="block text-xs font-semibold text-slate-800 mb-1">Initial Status</label>
<div className="flex items-center gap-4">
<label className="flex items-center gap-2 text-xs text-slate-700 cursor-pointer">
<input
type="radio"
name="status"
value="active"
checked={status === 'active'}
onChange={() => setStatus('active')}
className="text-slate-900 focus:ring-slate-900"
/>
<span>Active</span>
</label>
<label className="flex items-center gap-2 text-xs text-slate-700 cursor-pointer">
<input
type="radio"
name="status"
value="completed"
checked={status === 'completed'}
onChange={() => setStatus('completed')}
className="text-slate-900 focus:ring-slate-900"
/>
<span>Completed</span>
</label>
</div>
</div>
{/* Form Footer */}
<div className="flex items-center justify-end gap-3 pt-4 border-t border-slate-100">
<button
type="button"
onClick={() => setStep(1)}
className="px-4 py-2 text-xs font-medium text-slate-700 hover:text-slate-900 transition-colors"
>
Back
</button>
<button
type="submit"
disabled={submitting}
className="px-4 py-2 text-xs font-medium text-white bg-slate-900 hover:bg-slate-800 rounded-lg transition-colors flex items-center gap-2 disabled:opacity-50"
>
{submitting ? 'Saving...' : 'Track Item'}
<Check className="w-3.5 h-3.5" />
</button>
</div>
</form>
)}
</div>
</div>
);
};