///
/**
* Shared type definitions for the contacts pattern family.
*
* Extracted to break circular dependencies between contacts.tsx,
* person.tsx, and family-member.tsx.
*/
import { type Default, NAME, UI, type VNode } from "commontools";
// ============================================================================
// PersonLike - Schelling point for person data (structural type)
// ============================================================================
/**
* Minimal interface for person-like items.
* Defined locally in patterns, not in core API - works via duck typing.
* Any object with { firstName, lastName } satisfies PersonLike.
*/
export interface PersonLike {
firstName: string;
lastName: string;
/** Optional link to same entity in another context (e.g., work vs personal) */
sameAs?: PersonLike;
}
// ============================================================================
// Address & SocialProfile - Structured sub-types
// ============================================================================
export interface Address {
label: Default; // "Home", "Work", etc.
street: Default;
city: Default;
state: Default;
zip: Default;
country: Default;
}
export interface SocialProfile {
platform: Default; // "LinkedIn", "Twitter", etc.
url: Default;
}
// ============================================================================
// Birthday - Structured date with optional year
// ============================================================================
export interface Birthday {
month: Default; // 1-12, 0 = unset
day: Default; // 1-31, 0 = unset
year: Default; // 4-digit year, 0 = unknown
}
// ============================================================================
// Person Type - Extends PersonLike with optional contact fields
// ============================================================================
export interface Person extends PersonLike {
firstName: string;
lastName: string;
// Name extensions
middleName: Default;
nickname: Default; // preferred name / what they go by
prefix: Default; // Dr., Mr., Prof.
suffix: Default; // Jr., III, Ph.D.
// Identity metadata
pronouns: Default; // freeform: "he/him", "they/them"
birthday: Default;
photo: Default; // URL or data reference
// Contact fields
email: Default;
phone: Default;
notes: Default;
tags: Default;
addresses: Default;
socialProfiles: Default;
}
// ============================================================================
// FamilyMember Type - Extends PersonLike with family-specific fields
// ============================================================================
export interface FamilyMember extends PersonLike {
firstName: string;
lastName: string;
relationship: Default;
birthday: Default; // ISO date string (YYYY-MM-DD)
dietaryRestrictions: Default;
notes: Default;
tags: Default;
allergies: Default;
giftIdeas: Default;
}
// ============================================================================
// ContactPiece - What the container stores in its contacts array
// ============================================================================
/**
* A contact piece has [NAME], [UI], and either person or member data.
*/
export interface ContactPiece {
[NAME]: string;
[UI]: VNode;
person?: Person;
member?: FamilyMember;
}
// ============================================================================
// ContactGroup - Manual grouping of contacts
// ============================================================================
export interface ContactGroup {
name: string;
contactIndices: Default; // indices into contacts[]
}
// Default export required by ct check infrastructure
export default undefined;