carnet panel contact

This commit is contained in:
alma 2025-04-20 19:38:17 +02:00
parent a654994b1f
commit ef842a15d6
2 changed files with 76 additions and 77 deletions

View File

@ -31,8 +31,8 @@ interface Note {
interface Contact { interface Contact {
id: string; id: string;
fullName: string; fullName?: string;
email: string; email?: string;
phone?: string; phone?: string;
organization?: string; organization?: string;
address?: string; address?: string;
@ -132,6 +132,14 @@ export default function CarnetPage() {
}, [isSmallScreen, isMediumScreen]); }, [isSmallScreen, isMediumScreen]);
useEffect(() => { useEffect(() => {
if (selectedFolder === 'Contacts') {
// When "Contacts" is selected, show all contacts
fetchContacts('Contacts');
} else if (selectedFolder.endsWith('.vcf')) {
// When a specific VCF file is selected, show its contacts
fetchContacts(selectedFolder);
} else {
// For other folders (Notes, etc.), fetch notes
const fetchNotes = async () => { const fetchNotes = async () => {
try { try {
setIsLoadingNotes(true); setIsLoadingNotes(true);
@ -140,43 +148,17 @@ export default function CarnetPage() {
throw new Error('Failed to fetch notes'); throw new Error('Failed to fetch notes');
} }
const data = await response.json(); const data = await response.json();
if (selectedFolder === 'Contacts') {
// For contacts, parse the VCF files
const parsedContacts = await Promise.all(
data.map(async (file: any) => {
try {
// Use the full filename for fetching content
const contentResponse = await fetch(`/api/nextcloud/files/content?path=${encodeURIComponent(file.filename)}`);
if (contentResponse.ok) {
const content = await contentResponse.text();
return parseVCard(content);
}
console.error('Failed to fetch VCF content:', contentResponse.status);
return null;
} catch (error) {
console.error('Error fetching VCF content:', error);
return null;
}
})
);
setContacts(parsedContacts.filter(Boolean));
} else {
setNotes(data); setNotes(data);
}
} catch (error) { } catch (error) {
console.error('Error fetching data:', error); console.error('Error fetching notes:', error);
if (selectedFolder === 'Contacts') {
setContacts([]);
} else {
setNotes([]); setNotes([]);
}
} finally { } finally {
setIsLoadingNotes(false); setIsLoadingNotes(false);
} }
}; };
fetchNotes(); fetchNotes();
}, [selectedFolder]); }
}, [selectedFolder, session?.user?.id]);
const parseVCard = (content: string): Contact[] => { const parseVCard = (content: string): Contact[] => {
try { try {
@ -277,6 +259,19 @@ export default function CarnetPage() {
const fetchContacts = async (folder: string) => { const fetchContacts = async (folder: string) => {
try { try {
setIsLoadingContacts(true); setIsLoadingContacts(true);
// First, check if we're looking at a specific VCF file
if (folder.endsWith('.vcf')) {
const response = await fetch(`/api/nextcloud/files/content?path=${encodeURIComponent(`/files/cube-${session?.user?.id}/Private/Contacts/${folder}`)}`);
if (response.ok) {
const { content } = await response.json();
const contacts = parseVCard(content);
setContacts(contacts.map(contact => ({
...contact,
group: folder.replace('.vcf', '')
})));
}
} else {
// If not a VCF file, list all VCF files in the folder
const response = await fetch(`/api/nextcloud/files?folder=${folder}`); const response = await fetch(`/api/nextcloud/files?folder=${folder}`);
if (response.ok) { if (response.ok) {
const files = await response.json(); const files = await response.json();
@ -286,15 +281,13 @@ export default function CarnetPage() {
const parsedContacts = await Promise.all( const parsedContacts = await Promise.all(
vcfFiles.map(async (file: any) => { vcfFiles.map(async (file: any) => {
try { try {
// Construct the full WebDAV path const contentResponse = await fetch(`/api/nextcloud/files/content?path=${encodeURIComponent(file.filename)}`);
const webdavPath = `/files/${file.filename}`;
const contentResponse = await fetch(`/api/nextcloud/files/content?path=${encodeURIComponent(webdavPath)}`);
if (contentResponse.ok) { if (contentResponse.ok) {
const content = await contentResponse.text(); const { content } = await contentResponse.json();
const contacts = parseVCard(content); const contacts = parseVCard(content);
return contacts.map(contact => ({ return contacts.map(contact => ({
...contact, ...contact,
group: folder group: file.basename.replace('.vcf', '')
})); }));
} }
return []; return [];
@ -308,8 +301,10 @@ export default function CarnetPage() {
// Flatten the array of contact arrays // Flatten the array of contact arrays
setContacts(parsedContacts.flat().filter(Boolean)); setContacts(parsedContacts.flat().filter(Boolean));
} }
}
} catch (error) { } catch (error) {
console.error('Error fetching contacts:', error); console.error('Error fetching contacts:', error);
setContacts([]);
} finally { } finally {
setIsLoadingContacts(false); setIsLoadingContacts(false);
} }

View File

@ -5,8 +5,8 @@ import { Search, User, Mail, Phone, Building, MapPin, ChevronRight } from 'lucid
interface Contact { interface Contact {
id: string; id: string;
fullName: string; fullName?: string;
email: string; email?: string;
phone?: string; phone?: string;
organization?: string; organization?: string;
address?: string; address?: string;
@ -76,8 +76,12 @@ export const ContactsView: React.FC<ContactsViewProps> = ({
<User className="h-5 w-5 text-primary" /> <User className="h-5 w-5 text-primary" />
</div> </div>
<div> <div>
<div className="font-medium text-carnet-text-primary">{contact.fullName}</div> <div className="font-medium text-carnet-text-primary">
{contact.fullName || contact.email || 'Sans nom'}
</div>
{contact.email && (
<div className="text-sm text-carnet-text-muted">{contact.email}</div> <div className="text-sm text-carnet-text-muted">{contact.email}</div>
)}
</div> </div>
</div> </div>
<ChevronRight className="h-4 w-4 text-carnet-text-muted" /> <ChevronRight className="h-4 w-4 text-carnet-text-muted" />