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
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user