84 lines
3.9 KiB
TypeScript
84 lines
3.9 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
export default function AddPage() {
|
|
const router = useRouter();
|
|
const [firmName, setFirmName] = useState('');
|
|
const [username, setUsername] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [error, setError] = useState('');
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
const inputCls = 'w-full border border-slate-200 rounded-lg px-3 py-2 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-blue-400';
|
|
const labelCls = 'block text-xs font-semibold uppercase tracking-wider text-slate-500 mb-1';
|
|
|
|
const handleSave = async () => {
|
|
if (!firmName.trim() || !username.trim() || !password.trim()) return;
|
|
setSaving(true);
|
|
setError('');
|
|
try {
|
|
const res = await fetch('/api/firms', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ name: firmName.trim(), username: username.trim(), password: password.trim() }),
|
|
});
|
|
if (!res.ok) {
|
|
const data = await res.json() as { error?: string };
|
|
setError(data.error ?? 'Failed to save firm');
|
|
return;
|
|
}
|
|
router.push('/');
|
|
} catch {
|
|
setError('Could not connect to server');
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-50 p-8">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<button onClick={() => router.push('/')} className="text-slate-400 hover:text-slate-600 text-sm transition-colors">
|
|
← Back
|
|
</button>
|
|
<h1 className="text-2xl font-bold text-slate-900">Add New Firm</h1>
|
|
</div>
|
|
<div className="bg-white border border-slate-200 rounded-xl p-6 shadow-sm max-w-md space-y-4">
|
|
{error && (
|
|
<div className="text-sm text-red-600 bg-red-50 border border-red-100 rounded-lg px-3 py-2">
|
|
{error}
|
|
</div>
|
|
)}
|
|
<div>
|
|
<label className={labelCls}>Firm Name</label>
|
|
<input value={firmName} onChange={(e) => setFirmName(e.target.value)} className={inputCls} placeholder="e.g. MyFirm" />
|
|
</div>
|
|
<div>
|
|
<label className={labelCls}>Username</label>
|
|
<input value={username} onChange={(e) => setUsername(e.target.value)} className={inputCls} placeholder="Username" />
|
|
</div>
|
|
<div>
|
|
<label className={labelCls}>Password</label>
|
|
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} className={inputCls} placeholder="Password" />
|
|
</div>
|
|
<div className="flex justify-end gap-2 pt-2">
|
|
<button onClick={() => router.push('/')} className="px-4 py-2 text-sm text-slate-600 hover:text-slate-800 transition-colors">
|
|
Cancel
|
|
</button>
|
|
<button
|
|
onClick={handleSave}
|
|
disabled={saving || !firmName.trim() || !username.trim() || !password.trim()}
|
|
className="px-4 py-2 bg-green-100 hover:bg-green-200 disabled:opacity-40 disabled:cursor-not-allowed text-green-700 text-sm font-semibold rounded-lg transition-colors"
|
|
>
|
|
{saving ? 'Saving...' : 'Add Firm'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|