Files
rentman-clone/frontend/src/pages/ContactsEdit.tsx
T
Agent Zero 7f7da15965 Initial commit: Rentman Clone - Phase 0-6 (T001-T023)
Completed:
- Phase 0: Project Setup (T001-T003) - Docker Compose, FastAPI skeleton, React SPA
- Phase 1: Auth System (T004-T008) - DB models, JWT auth, RBAC middleware, user management
- Phase 2: Contacts & Tags (T009-T011) - CRUD API + UI
- Phase 3: Equipment Catalog (T012-T014) - Models, API, UI with barcode/QR
- Phase 4: Crew Management (T015-T017) - Models, availability, UI
- Phase 5: Vehicle Fleet (T018-T020) - Models, assignments, UI
- Phase 6: Projects (T021-T023) - Project hierarchy models, CRUD API, list/detail UI
2026-05-31 20:36:42 +00:00

72 lines
2.6 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import ContactForm, { ContactFormData, emptyFormData } from '../components/ContactForm.tsx';
import api from '../services/api.ts';
export default function ContactsEdit() {
const { contactId } = useParams<{ contactId: string }>();
const navigate = useNavigate();
const [initialData, setInitialData] = useState<ContactFormData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
loadContact();
}, [contactId]);
const loadContact = async () => {
try {
setLoading(true);
const response = await api.get(`/contacts/${contactId}`);
const c = response.data;
setInitialData({
type: c.type,
company_name: c.company_name || '',
first_name: c.first_name || '',
last_name: c.last_name || '',
email: c.email || '',
phone: c.phone || '',
mobile: c.mobile || '',
website: c.website || '',
billing_street: c.billing_street || '',
billing_number: c.billing_number || '',
billing_postalcode: c.billing_postalcode || '',
billing_city: c.billing_city || '',
billing_country: c.billing_country || '',
shipping_street: c.shipping_street || '',
shipping_number: c.shipping_number || '',
shipping_postalcode: c.shipping_postalcode || '',
shipping_city: c.shipping_city || '',
shipping_country: c.shipping_country || '',
tax_number: c.tax_number || '',
note: c.note || '',
tag_ids: c.tags?.map((t: any) => t.id) || [],
});
} catch (err: any) {
setError(err.response?.data?.detail || 'Failed to load contact');
} finally {
setLoading(false);
}
};
const handleUpdate = async (formData: ContactFormData) => {
await api.put(`/contacts/${contactId}`, formData);
navigate(`/contacts/${contactId}`);
};
if (loading) return <div className="p-6"><p className="text-text-secondary">Loading contact...</p></div>;
if (error) return <div className="p-6"><p className="text-red-500">{error}</p></div>;
if (!initialData) return <div className="p-6"><p className="text-text-secondary">Contact not found.</p></div>;
return (
<div className="p-6 max-w-3xl mx-auto">
<h1 className="text-2xl font-bold text-text-primary mb-6">Edit Contact</h1>
<ContactForm
initialData={initialData}
onSubmit={handleUpdate}
submitLabel="Save Changes"
/>
</div>
);
}