Skip to main content

Contacts Feature - Integration Status

This document tracks what is integrated between frontend and backend for the contacts feature.

Last updated: 2026-03-23


1. Multi-Value Email & Phone Numbers

Status:Fully integrated

Frontend sends and receives additionalEmails and additionalPhones arrays on all contact CRUD operations.

Implementation Details

Type:

type AdditionalEntry {
value: String!
label: String!
}

Label Options:

  • Phone labels: ["Mobile", "Work", "Home", "Other"]
  • Email labels: ["Work", "Personal", "Other"]

Frontend Behavior:

  • Entries are loaded from backend on page load
  • Creating a contact sends additionalEmails / additionalPhones in createContact mutation
  • Updating a contact sends the complete arrays (backend replaces, not merges)
  • Removing an entry auto-saves immediately
  • Pressing Enter on an entry auto-saves
  • Pressing Escape dismisses editing without saving
  • Delete icon is always visible (not hidden behind hover)

GraphQL Queries that include these fields:

  • GET_CONTACTS_BY_COMPANY (list view)
  • GET_CONTACT_BY_ID (detail view)
  • CREATE_CONTACT (return fields)
  • UPDATE_CONTACT (return fields)

Files:

  • graphql/operations/contacts/queries.ts
  • graphql/operations/contacts/mutations.ts
  • app/company/connections/contacts/_components/CreateContactCard.tsx
  • app/company/connections/contacts/[id]/view/page.tsx

2. Company Name (Free Text)

Status:Fully integrated

The company field on contacts is a user-editable free text field, not auto-populated from the user's company.

Implementation Details

  • Create: companyName sent in createContact mutation input
  • Update: companyName sent in updateContact mutation input
  • Display: Loaded from display.companyName on the contact record
  • UI: Click-to-edit text input in both the hero section and the Organization panel
  • Company is NOT resolved from user.companies or userCompanyRole — it's whatever the contact creator typed

Backend requirement: The CreateContactInput and UpdateContactInput must accept a companyName: String field. This value should be stored in the contact's display JSON or as a dedicated column.


3. ContactNote.Author

Status:Integrated with fallback

The Author field is now queried directly on ContactNote in GET_CONTACT_BY_ID:

ContactNote {
id
contactId
authorId
title
content
createdAt
updatedAt
Author {
id
firstName
lastName
profileImageUrl
}
}

Frontend uses Author from the query when available, with a client-side fallback to userIdToName map via authorId if Author is null.


4. Contact Types System

Status: ✅ Fully integrated and working


5. Contact Notes System

Status: ✅ Fully integrated

  • CRUD operations work via createContactNote, updateContactNote, removeContactNote
  • Author info now comes from GraphQL Author field with client-side fallback
  • GET_CONTACT_NOTES standalone query includes Author { id firstName lastName profileImageUrl }

6. External Sharing System

Status: ✅ Fully integrated and working


7. Merge Contacts System

Status: ✅ Fully integrated and working


8. CSV Bulk Import System

Status: ✅ Fully integrated


9. Collaboration & Partnership Status Fields

Status: ✅ Fully integrated and working


10. UX Behaviors

Auto-save on Enter

  • Pressing Enter while editing any inline field dismisses the editor and auto-saves the contact
  • Pressing Escape dismisses the editor without saving
  • Removing an additional email/phone entry auto-saves immediately

Keyboard Support

  • All inline edit fields (name, title, company, phone, location, types, responsible, additional entries) support Enter/Escape
  • EditableInfoItem component has onDismiss (Enter → save) and onCancel (Escape → dismiss) callbacks
  • AdditionalEntryRow component has onSave and onCancel callbacks
  • Back button is an icon-only arrow on the left side next to "CONTACT PROFILE" label
  • Prev/Next navigation with arrow keys (when not editing a field)

Remaining Backend Issues (Low Priority)

These have frontend workarounds in place:

  1. Import errors: nullimportContacts returns null instead of [] for empty errors array. Frontend normalizes with ?? [].

  2. Company Name SortingCOMPANY_NAME sort uses a different field than what the frontend displays. Frontend applies client-side sort as workaround.

  3. Mutation Argument Naming — Some mutations use createContactInput / updateContactInput instead of input. Frontend maps to the correct names.


File Reference

FilePurpose
graphql/operations/contacts/queries.tsAll contact GraphQL queries
graphql/operations/contacts/mutations.tsAll contact GraphQL mutations
app/company/connections/contacts/page.tsxContacts list page
app/company/connections/contacts/_components/CreateContactCard.tsxCreate contact form
app/company/connections/contacts/[id]/view/page.tsxView/edit contact detail page
app/company/connections/contacts/_components/ShareContactDialog.tsxExternal sharing dialog
app/company/connections/contacts/_components/MergeContactsDialog.tsxMerge contacts dialog
app/company/connections/contacts/_components/ImportContactsDialog.tsxCSV import dialog
components/reusable/ProfileViewPrimitives.tsxEditableInfoItem component (shared)