feat(contacts): integrate contacts into Todo and Calendar apps

- Add ContactSelector, ContactBadge, ContactAvatar to shared-ui
- Add ContactsClient API service to shared-auth
- Add ContactReference, ContactSummary types to shared-types
- Todo: Add assignee and involvedContacts to tasks with UI in TaskEditModal
- Todo: Display contacts in TaskItem and KanbanTaskCard
- Calendar: Add AttendeeSelector with RSVP status support
- Calendar: Integrate attendees in EventForm
- Calendar: Add task drag-drop to calendar views (Day/Week/MultiDay)
- Contacts: Add ContactTasks component to show related tasks
- Backend: Add findByContact endpoint to Todo task service
- UI polish: glassmorphism styling, keyboard navigation, auto-focus

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Till-JS 2025-12-11 16:00:08 +01:00 committed by Wuesteon
parent 307f1ae22e
commit 0ecbf69ebc
50 changed files with 5791 additions and 53 deletions

View file

@ -0,0 +1,80 @@
/**
* Contact-related types for cross-app integration
*
* These types are used when referencing contacts from the Contacts app
* in other apps like Todo and Calendar.
*/
/**
* Reference to a contact with cached display data.
* Used for offline display when Contacts API is unavailable.
*/
export interface ContactReference {
/** Contact ID from Contacts app */
contactId: string;
/** Cached display name */
displayName: string;
/** Cached email */
email?: string;
/** Cached photo URL */
photoUrl?: string;
/** Cached company name */
company?: string;
/** ISO timestamp when data was fetched (for cache invalidation) */
fetchedAt: string;
}
/**
* Summary of a contact from the Contacts API.
* Contains essential fields for display in selectors and lists.
*/
export interface ContactSummary {
id: string;
displayName: string;
firstName?: string;
lastName?: string;
email?: string;
phone?: string;
company?: string;
photoUrl?: string;
}
/**
* Manual contact entry (when contact doesn't exist in Contacts app).
* Used for calendar attendees who aren't in the user's contacts.
*/
export interface ManualContactEntry {
/** Email address (required for manual entries) */
email: string;
/** Display name (optional) */
name?: string;
/** Indicates this is a manual entry, not from Contacts app */
isManual: true;
}
/**
* Union type for contact references that can be either
* a real contact or a manual entry.
*/
export type ContactOrManual = ContactReference | ManualContactEntry;
/**
* Helper to check if a contact entry is manual
*/
export function isManualContact(contact: ContactOrManual): contact is ManualContactEntry {
return 'isManual' in contact && contact.isManual === true;
}
/**
* Helper to create a ContactReference from a ContactSummary
*/
export function createContactReference(contact: ContactSummary): ContactReference {
return {
contactId: contact.id,
displayName: contact.displayName,
email: contact.email,
photoUrl: contact.photoUrl,
company: contact.company,
fetchedAt: new Date().toISOString(),
};
}

View file

@ -16,6 +16,9 @@ export * from './ui';
// Common utility types
export * from './common';
// Contact types for cross-app integration
export * from './contact';
// API types
export interface User {
id: string;