carnet panel contact
This commit is contained in:
parent
add7e45af9
commit
6beb394a84
@ -11,7 +11,7 @@ import { useMediaQuery } from "@/hooks/use-media-query";
|
||||
import { ContactsView } from '@/components/carnet/contacts-view';
|
||||
import { X, Menu } from "lucide-react";
|
||||
import { ContactDetails } from '@/components/carnet/contact-details';
|
||||
import { VCard } from 'vcard-js';
|
||||
import { parse as parseVCard, format as formatVCard } from 'vcard-parser';
|
||||
|
||||
// Layout modes
|
||||
export enum PaneLayout {
|
||||
@ -162,24 +162,23 @@ export default function CarnetPage() {
|
||||
}
|
||||
}, [selectedFolder, session?.user?.id]);
|
||||
|
||||
const parseVCard = (content: string): Contact[] => {
|
||||
const parseVCardContent = (content: string): Contact[] => {
|
||||
try {
|
||||
// Split the content into individual vCards
|
||||
const vcards = content.split('BEGIN:VCARD').filter(section => section.trim());
|
||||
|
||||
return vcards.map(section => {
|
||||
const vcard = new VCard();
|
||||
vcard.parse('BEGIN:VCARD' + section);
|
||||
const vcard = parseVCard('BEGIN:VCARD' + section);
|
||||
|
||||
// Extract contact properties with proper type handling
|
||||
const uid = vcard.getProperty('UID')?.value;
|
||||
const fullName = vcard.getProperty('FN')?.value;
|
||||
const email = vcard.getProperty('EMAIL')?.value;
|
||||
const phone = vcard.getProperty('TEL')?.value;
|
||||
const organization = vcard.getProperty('ORG')?.value;
|
||||
const address = vcard.getProperty('ADR')?.value;
|
||||
const notes = vcard.getProperty('NOTE')?.value;
|
||||
const group = vcard.getProperty('CATEGORIES')?.value;
|
||||
const uid = vcard.uid?.[0]?.value;
|
||||
const fullName = vcard.fn?.[0]?.value;
|
||||
const email = vcard.email?.[0]?.value;
|
||||
const phone = vcard.tel?.[0]?.value;
|
||||
const organization = vcard.org?.[0]?.value;
|
||||
const address = vcard.adr?.[0]?.value;
|
||||
const notes = vcard.note?.[0]?.value;
|
||||
const group = vcard.categories?.[0]?.value;
|
||||
|
||||
// Create a clean contact object
|
||||
const contact: Contact = {
|
||||
@ -210,7 +209,7 @@ export default function CarnetPage() {
|
||||
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);
|
||||
const contacts = parseVCardContent(content);
|
||||
setContacts(contacts.map(contact => ({
|
||||
...contact,
|
||||
group: folder.replace('.vcf', '')
|
||||
@ -230,7 +229,7 @@ export default function CarnetPage() {
|
||||
const contentResponse = await fetch(`/api/nextcloud/files/content?path=${encodeURIComponent(file.filename)}`);
|
||||
if (contentResponse.ok) {
|
||||
const { content } = await contentResponse.json();
|
||||
const contacts = parseVCard(content);
|
||||
const contacts = parseVCardContent(content);
|
||||
return contacts.map(contact => ({
|
||||
...contact,
|
||||
group: file.basename.replace('.vcf', '')
|
||||
@ -394,7 +393,7 @@ export default function CarnetPage() {
|
||||
}
|
||||
|
||||
const { content } = await response.json();
|
||||
const contacts = parseVCard(content);
|
||||
const contacts = parseVCardContent(content);
|
||||
|
||||
// Update or add the contact
|
||||
const existingIndex = contacts.findIndex(c => c.id === contact.id);
|
||||
@ -405,7 +404,7 @@ export default function CarnetPage() {
|
||||
}
|
||||
|
||||
// Generate new VCF content
|
||||
const vcfContent = contacts.map(c => generateVCard(c)).join('\n');
|
||||
const vcfContent = contacts.map(c => generateVCardContent(c)).join('\n');
|
||||
|
||||
// Save the updated VCF file
|
||||
const saveResponse = await fetch('/api/nextcloud/files', {
|
||||
@ -455,13 +454,13 @@ export default function CarnetPage() {
|
||||
}
|
||||
|
||||
const { content } = await response.json();
|
||||
const contacts = parseVCard(content);
|
||||
const contacts = parseVCardContent(content);
|
||||
|
||||
// Remove the contact
|
||||
const updatedContacts = contacts.filter(c => c.id !== contact.id);
|
||||
|
||||
// Generate new VCF content
|
||||
const vcfContent = updatedContacts.map(c => generateVCard(c)).join('\n');
|
||||
const vcfContent = updatedContacts.map(c => generateVCardContent(c)).join('\n');
|
||||
|
||||
// Save the updated VCF file
|
||||
const saveResponse = await fetch('/api/nextcloud/files', {
|
||||
@ -492,22 +491,20 @@ export default function CarnetPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const generateVCard = (contact: Contact): string => {
|
||||
const vcard = new VCard();
|
||||
|
||||
// Ensure required fields are not undefined
|
||||
vcard.setProperty('UID', contact.id || Math.random().toString(36).substr(2, 9));
|
||||
vcard.setProperty('FN', contact.fullName || 'Unknown Contact');
|
||||
|
||||
// Add optional fields only if they have values
|
||||
if (contact.email) vcard.setProperty('EMAIL', contact.email);
|
||||
if (contact.phone) vcard.setProperty('TEL', contact.phone);
|
||||
if (contact.organization) vcard.setProperty('ORG', contact.organization);
|
||||
if (contact.address) vcard.setProperty('ADR', contact.address);
|
||||
if (contact.notes) vcard.setProperty('NOTE', contact.notes);
|
||||
if (contact.group) vcard.setProperty('CATEGORIES', contact.group);
|
||||
|
||||
return vcard.toString();
|
||||
const generateVCardContent = (contact: Contact): string => {
|
||||
const vcard = {
|
||||
version: '3.0',
|
||||
uid: contact.id,
|
||||
fn: contact.fullName,
|
||||
email: contact.email ? [{ value: contact.email }] : undefined,
|
||||
tel: contact.phone ? [{ value: contact.phone }] : undefined,
|
||||
org: contact.organization ? [{ value: contact.organization }] : undefined,
|
||||
adr: contact.address ? [{ value: contact.address }] : undefined,
|
||||
note: contact.notes ? [{ value: contact.notes }] : undefined,
|
||||
categories: contact.group ? [{ value: contact.group }] : undefined
|
||||
};
|
||||
|
||||
return formatVCard(vcard);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user