detail fixes

This commit is contained in:
Ken Yasue
2025-03-25 07:02:21 +01:00
parent 1866d84a86
commit d713939730
3 changed files with 71 additions and 22 deletions

View File

@ -1,6 +1,6 @@
'use client'; 'use client';
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import Link from 'next/link'; import Link from 'next/link';
@ -14,14 +14,55 @@ interface ContactRecord {
} }
interface ContactRecordListProps { interface ContactRecordListProps {
contactRecords: ContactRecord[]; customerId: string;
} }
export default function ContactRecordList({ contactRecords }: ContactRecordListProps) { export default function ContactRecordList({ customerId }: ContactRecordListProps) {
const router = useRouter(); const router = useRouter();
const [contactRecords, setContactRecords] = useState<ContactRecord[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [isDeleting, setIsDeleting] = useState<string | null>(null); const [isDeleting, setIsDeleting] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// Function to fetch contact records
const fetchContactRecords = async () => {
setIsLoading(true);
try {
const response = await fetch(`/api/contact-records?customerId=${customerId}`);
if (!response.ok) {
throw new Error('Failed to fetch contact records');
}
const data = await response.json();
setContactRecords(data);
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred while fetching contact records');
} finally {
setIsLoading(false);
}
};
// Fetch records on initial load and when customerId changes
useEffect(() => {
fetchContactRecords();
}, [customerId]);
// Refresh data when router.refresh() is called
useEffect(() => {
// Create a callback function that will be called when the component is re-rendered
const refreshData = () => {
fetchContactRecords();
};
// Add an event listener for a custom event that will be dispatched when router.refresh() is called
window.addEventListener('contact-records-refresh', refreshData);
return () => {
window.removeEventListener('contact-records-refresh', refreshData);
};
}, []);
const handleDelete = async (id: string) => { const handleDelete = async (id: string) => {
if (!confirm('Are you sure you want to delete this contact record?')) { if (!confirm('Are you sure you want to delete this contact record?')) {
return; return;
@ -40,7 +81,10 @@ export default function ContactRecordList({ contactRecords }: ContactRecordListP
throw new Error(data.error || 'Failed to delete contact record'); throw new Error(data.error || 'Failed to delete contact record');
} }
// Refresh the page to show updated contact record list // Refresh the contact records list
fetchContactRecords();
// Refresh the page
router.refresh(); router.refresh();
} catch (err) { } catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred'); setError(err instanceof Error ? err.message : 'An error occurred');
@ -49,6 +93,14 @@ export default function ContactRecordList({ contactRecords }: ContactRecordListP
} }
}; };
if (isLoading) {
return (
<div className="text-center py-8 text-gray-500">
Loading contact records...
</div>
);
}
if (contactRecords.length === 0) { if (contactRecords.length === 0) {
return ( return (
<div className="text-center py-8 text-gray-500"> <div className="text-center py-8 text-gray-500">

View File

@ -61,6 +61,9 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
}); });
setSuccess(true); setSuccess(true);
// Dispatch a custom event to notify the ContactRecordList component to refresh
window.dispatchEvent(new Event('contact-records-refresh'));
// Refresh the page to show the new contact record // Refresh the page to show the new contact record
router.refresh(); router.refresh();
} catch (err) { } catch (err) {
@ -73,30 +76,30 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
return ( return (
<div> <div>
{error && ( {error && (
<div className="bg-red-50 border-l-4 border-red-400 p-4 mb-4"> <div className="bg-red-50 border-l-4 border-red-400 p-4 mb-4 dark:bg-red-900/20 dark:border-red-500">
<div className="flex"> <div className="flex">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<svg className="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor"> <svg className="h-5 w-5 text-red-400 dark:text-red-300" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" /> <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
</svg> </svg>
</div> </div>
<div className="ml-3"> <div className="ml-3">
<p className="text-sm text-red-700">{error}</p> <p className="text-sm text-red-700 dark:text-red-300">{error}</p>
</div> </div>
</div> </div>
</div> </div>
)} )}
{success && ( {success && (
<div className="bg-green-50 border-l-4 border-green-400 p-4 mb-4"> <div className="bg-green-50 border-l-4 border-green-400 p-4 mb-4 dark:bg-green-900/20 dark:border-green-500">
<div className="flex"> <div className="flex">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<svg className="h-5 w-5 text-green-400" viewBox="0 0 20 20" fill="currentColor"> <svg className="h-5 w-5 text-green-400 dark:text-green-300" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" /> <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg> </svg>
</div> </div>
<div className="ml-3"> <div className="ml-3">
<p className="text-sm text-green-700">Contact record created successfully!</p> <p className="text-sm text-green-700 dark:text-green-300">Contact record created successfully!</p>
</div> </div>
</div> </div>
</div> </div>
@ -104,7 +107,7 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
<form onSubmit={handleSubmit} className="space-y-4"> <form onSubmit={handleSubmit} className="space-y-4">
<div> <div>
<label htmlFor="contactType" className="block text-sm font-medium text-gray-700"> <label htmlFor="contactType" className="block text-sm font-medium text-gray-700 dark:text-gray-300">
Contact Type Contact Type
</label> </label>
<select <select
@ -112,7 +115,7 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
name="contactType" name="contactType"
value={formData.contactType} value={formData.contactType}
onChange={handleChange} onChange={handleChange}
className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md" className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md dark:bg-gray-800 dark:border-gray-700 dark:text-gray-200"
required required
> >
<option value="">Select a contact type</option> <option value="">Select a contact type</option>
@ -124,7 +127,7 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
</div> </div>
<div> <div>
<label htmlFor="notes" className="block text-sm font-medium text-gray-700"> <label htmlFor="notes" className="block text-sm font-medium text-gray-700 dark:text-gray-300">
Notes Notes
</label> </label>
<textarea <textarea
@ -133,7 +136,7 @@ export default function NewContactRecordForm({ customerId }: NewContactRecordFor
rows={4} rows={4}
value={formData.notes} value={formData.notes}
onChange={handleChange} onChange={handleChange}
className="mt-1 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" className="mt-1 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md dark:bg-gray-800 dark:border-gray-700 dark:text-gray-200"
placeholder="Enter notes about the contact" placeholder="Enter notes about the contact"
></textarea> ></textarea>
</div> </div>

View File

@ -1,5 +1,5 @@
import Link from 'next/link'; import Link from 'next/link';
import { getDataSource, Customer, ContactRecord } from '@/lib/database'; import { getDataSource, Customer } from '@/lib/database';
import ContactRecordList from '../../components/ContactRecordList'; import ContactRecordList from '../../components/ContactRecordList';
import NewContactRecordForm from '../../components/NewContactRecordForm'; import NewContactRecordForm from '../../components/NewContactRecordForm';
@ -9,7 +9,6 @@ export default async function CustomerDetail({ params }: { params: { id: string
// Fetch customer data // Fetch customer data
const dataSource = await getDataSource(); const dataSource = await getDataSource();
const customerRepository = dataSource.getRepository(Customer); const customerRepository = dataSource.getRepository(Customer);
const contactRecordRepository = dataSource.getRepository(ContactRecord);
const customer = await customerRepository.findOne({ const customer = await customerRepository.findOne({
where: { id } where: { id }
@ -30,11 +29,6 @@ export default async function CustomerDetail({ params }: { params: { id: string
); );
} }
// Fetch contact records for this customer
const contactRecords = await contactRecordRepository.find({
where: { customerId: id },
order: { createdAt: 'DESC' }
});
return ( return (
<div> <div>
@ -130,7 +124,7 @@ export default async function CustomerDetail({ params }: { params: { id: string
{/* Contact Records List */} {/* Contact Records List */}
<div className="border-t border-gray-200"> <div className="border-t border-gray-200">
<ContactRecordList contactRecords={contactRecords} /> <ContactRecordList customerId={id} />
</div> </div>
</div> </div>
</div> </div>