@fluid-app/portal-sdk 0.1.253 → 0.1.255

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/dist/{AddressAutocompleteInput-Dy5sL54V.mjs → AddressAutocompleteInput-Dg-75n-K.mjs} +9 -12
  2. package/dist/AddressAutocompleteInput-Dg-75n-K.mjs.map +1 -0
  3. package/dist/{AddressAutocompleteInput-eO2ZMNvX.cjs → AddressAutocompleteInput-W2jWPYoJ.cjs} +26 -11
  4. package/dist/AddressAutocompleteInput-W2jWPYoJ.cjs.map +1 -0
  5. package/dist/{ContactsScreen-9gyQNZY-.cjs → ContactsScreen-BC5P7RD1.cjs} +2 -2
  6. package/dist/{ContactsScreen-B9I61v6-.cjs → ContactsScreen-BTBszjeo.cjs} +22 -22
  7. package/dist/{ContactsScreen-B9I61v6-.cjs.map → ContactsScreen-BTBszjeo.cjs.map} +1 -1
  8. package/dist/{ContactsScreen-gMBovFil.mjs → ContactsScreen-CYl6fWtE.mjs} +22 -22
  9. package/dist/{ContactsScreen-gMBovFil.mjs.map → ContactsScreen-CYl6fWtE.mjs.map} +1 -1
  10. package/dist/{FluidProvider-Can6hW1d.mjs → FluidProvider-B58aBJhk.mjs} +4 -5
  11. package/dist/{FluidProvider-Can6hW1d.mjs.map → FluidProvider-B58aBJhk.mjs.map} +1 -1
  12. package/dist/{FluidProvider-BLri8EGR.cjs → FluidProvider-IFbNov8P.cjs} +3 -10
  13. package/dist/{FluidProvider-BLri8EGR.cjs.map → FluidProvider-IFbNov8P.cjs.map} +1 -1
  14. package/dist/{MessagingScreen-CTjDMhpI.mjs → MessagingScreen-BU7xPuff.mjs} +2 -2
  15. package/dist/{MessagingScreen-CLnVhFC5.cjs → MessagingScreen-BohdQMST.cjs} +2 -2
  16. package/dist/{MessagingScreen-BqmMhGDq.mjs → MessagingScreen-CKE4KsvW.mjs} +2 -2
  17. package/dist/{MessagingScreen-BqmMhGDq.mjs.map → MessagingScreen-CKE4KsvW.mjs.map} +1 -1
  18. package/dist/{MessagingScreen-CLcsshRX.cjs → MessagingScreen-CrTcbztO.cjs} +2 -2
  19. package/dist/{MessagingScreen-CLcsshRX.cjs.map → MessagingScreen-CrTcbztO.cjs.map} +1 -1
  20. package/dist/{ProfileScreen-6nDSJ8F0.mjs → ProfileScreen-D42NNNqT.mjs} +3 -3
  21. package/dist/{ProfileScreen-DvWpS_uG.mjs → ProfileScreen-Dvq3SfmI.mjs} +3 -3
  22. package/dist/{ProfileScreen-DvWpS_uG.mjs.map → ProfileScreen-Dvq3SfmI.mjs.map} +1 -1
  23. package/dist/{ProfileScreen-Ckh4xGkq.cjs → ProfileScreen-LL3z9-cx.cjs} +3 -3
  24. package/dist/{ProfileScreen-Ckh4xGkq.cjs.map → ProfileScreen-LL3z9-cx.cjs.map} +1 -1
  25. package/dist/{ProfileScreen-0fVNXPBY.cjs → ProfileScreen-dU8ZM8eY.cjs} +3 -3
  26. package/dist/{ShopScreen-Cdxvxph7.cjs → ShopScreen-C4z4aB8f.cjs} +3 -3
  27. package/dist/{ShopScreen-Cdxvxph7.cjs.map → ShopScreen-C4z4aB8f.cjs.map} +1 -1
  28. package/dist/{ShopScreen-C5IVlT_r.cjs → ShopScreen-CrRI83Xk.cjs} +3 -3
  29. package/dist/{ShopScreen-CvefnY1H.mjs → ShopScreen-DXzBm27P.mjs} +3 -3
  30. package/dist/{ShopScreen-CvefnY1H.mjs.map → ShopScreen-DXzBm27P.mjs.map} +1 -1
  31. package/dist/{ShopScreen-Dyy0Yi2Q.mjs → ShopScreen-kuA8cWVc.mjs} +3 -3
  32. package/dist/{SubscriptionsScreen-ByoOMsky.cjs → SubscriptionsScreen-Bm8Ncl1e.cjs} +624 -166
  33. package/dist/SubscriptionsScreen-Bm8Ncl1e.cjs.map +1 -0
  34. package/dist/{SubscriptionsScreen-Y4UgpC1Y.mjs → SubscriptionsScreen-CsNE6gik.mjs} +627 -169
  35. package/dist/SubscriptionsScreen-CsNE6gik.mjs.map +1 -0
  36. package/dist/{SubscriptionsScreen-GCZYPM8-.cjs → SubscriptionsScreen-ztgglvXe.cjs} +2 -2
  37. package/dist/de-C_Zyp0-8.mjs +55 -0
  38. package/dist/de-C_Zyp0-8.mjs.map +1 -0
  39. package/dist/de-DeRNmEET.cjs +61 -0
  40. package/dist/de-DeRNmEET.cjs.map +1 -0
  41. package/dist/el-BD_oG0S8.cjs +61 -0
  42. package/dist/el-BD_oG0S8.cjs.map +1 -0
  43. package/dist/el-DR5yE3hc.mjs +55 -0
  44. package/dist/el-DR5yE3hc.mjs.map +1 -0
  45. package/dist/es-BBPaROwb.mjs +55 -0
  46. package/dist/es-BBPaROwb.mjs.map +1 -0
  47. package/dist/es-Bb_shBOb.cjs +61 -0
  48. package/dist/es-Bb_shBOb.cjs.map +1 -0
  49. package/dist/fr-BetvW17a.mjs +55 -0
  50. package/dist/fr-BetvW17a.mjs.map +1 -0
  51. package/dist/fr-Cah7_RPB.cjs +61 -0
  52. package/dist/fr-Cah7_RPB.cjs.map +1 -0
  53. package/dist/he-D3kODvf8.mjs +55 -0
  54. package/dist/he-D3kODvf8.mjs.map +1 -0
  55. package/dist/he-gYOd_7Xx.cjs +61 -0
  56. package/dist/he-gYOd_7Xx.cjs.map +1 -0
  57. package/dist/hu-C68EBfmm.mjs +55 -0
  58. package/dist/hu-C68EBfmm.mjs.map +1 -0
  59. package/dist/hu-Cn5739bo.cjs +61 -0
  60. package/dist/hu-Cn5739bo.cjs.map +1 -0
  61. package/dist/id-BH2K_Gbr.cjs +61 -0
  62. package/dist/id-BH2K_Gbr.cjs.map +1 -0
  63. package/dist/id-Bt8m325E.mjs +55 -0
  64. package/dist/id-Bt8m325E.mjs.map +1 -0
  65. package/dist/index.cjs +22 -58
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.mjs +23 -59
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/it-BqtPjHii.cjs +61 -0
  70. package/dist/it-BqtPjHii.cjs.map +1 -0
  71. package/dist/it-WF3n2-Dh.mjs +55 -0
  72. package/dist/it-WF3n2-Dh.mjs.map +1 -0
  73. package/dist/ja-D6Gu5dFq.cjs +61 -0
  74. package/dist/ja-D6Gu5dFq.cjs.map +1 -0
  75. package/dist/ja-DwJ0vZjy.mjs +55 -0
  76. package/dist/ja-DwJ0vZjy.mjs.map +1 -0
  77. package/dist/ko-BdbrLr2D.mjs +55 -0
  78. package/dist/ko-BdbrLr2D.mjs.map +1 -0
  79. package/dist/ko-Dl2fBpWC.cjs +61 -0
  80. package/dist/ko-Dl2fBpWC.cjs.map +1 -0
  81. package/dist/nl-CA5o2t0S.cjs +61 -0
  82. package/dist/nl-CA5o2t0S.cjs.map +1 -0
  83. package/dist/nl-CUiqH5zZ.mjs +55 -0
  84. package/dist/nl-CUiqH5zZ.mjs.map +1 -0
  85. package/dist/pl-IbyEkNiD.mjs +55 -0
  86. package/dist/pl-IbyEkNiD.mjs.map +1 -0
  87. package/dist/pl-WlQv3-yq.cjs +61 -0
  88. package/dist/pl-WlQv3-yq.cjs.map +1 -0
  89. package/dist/pt-BhhvO4Qw.mjs +55 -0
  90. package/dist/pt-BhhvO4Qw.mjs.map +1 -0
  91. package/dist/pt-Cuoe77sP.cjs +61 -0
  92. package/dist/pt-Cuoe77sP.cjs.map +1 -0
  93. package/dist/ro-DIrwj2Mc.cjs +61 -0
  94. package/dist/ro-DIrwj2Mc.cjs.map +1 -0
  95. package/dist/ro-GgbW8Cux.mjs +55 -0
  96. package/dist/ro-GgbW8Cux.mjs.map +1 -0
  97. package/dist/ru-BC9x5NIp.mjs +55 -0
  98. package/dist/ru-BC9x5NIp.mjs.map +1 -0
  99. package/dist/ru-DCHj3W_N.cjs +61 -0
  100. package/dist/ru-DCHj3W_N.cjs.map +1 -0
  101. package/dist/{static-dict-adapter-Bxrw9FK5.cjs → static-dict-adapter-BLfRl80i.cjs} +1 -2
  102. package/dist/static-dict-adapter-BLfRl80i.cjs.map +1 -0
  103. package/dist/{static-dict-adapter-Bc5RtEkZ.mjs → static-dict-adapter-CdbsRyE-.mjs} +1 -2
  104. package/dist/static-dict-adapter-CdbsRyE-.mjs.map +1 -0
  105. package/dist/th-C2DeNJoD.mjs +55 -0
  106. package/dist/th-C2DeNJoD.mjs.map +1 -0
  107. package/dist/th-CebgyxgZ.cjs +61 -0
  108. package/dist/th-CebgyxgZ.cjs.map +1 -0
  109. package/dist/tl-CxY_bq4K.mjs +55 -0
  110. package/dist/tl-CxY_bq4K.mjs.map +1 -0
  111. package/dist/tl-DlFV8z30.cjs +61 -0
  112. package/dist/tl-DlFV8z30.cjs.map +1 -0
  113. package/dist/tr-Dj-KyRbz.cjs +61 -0
  114. package/dist/tr-Dj-KyRbz.cjs.map +1 -0
  115. package/dist/tr-DjrNAJD7.mjs +55 -0
  116. package/dist/tr-DjrNAJD7.mjs.map +1 -0
  117. package/dist/zh_CN-BE-GTtuO.mjs +55 -0
  118. package/dist/zh_CN-BE-GTtuO.mjs.map +1 -0
  119. package/dist/zh_CN-s2Jm_Dbu.cjs +61 -0
  120. package/dist/zh_CN-s2Jm_Dbu.cjs.map +1 -0
  121. package/dist/zh_TW-CR1xJCr6.mjs +55 -0
  122. package/dist/zh_TW-CR1xJCr6.mjs.map +1 -0
  123. package/dist/zh_TW-t10xPnCU.cjs +61 -0
  124. package/dist/zh_TW-t10xPnCU.cjs.map +1 -0
  125. package/package.json +14 -14
  126. package/dist/AddressAutocompleteInput-Dy5sL54V.mjs.map +0 -1
  127. package/dist/AddressAutocompleteInput-eO2ZMNvX.cjs.map +0 -1
  128. package/dist/SubscriptionsScreen-ByoOMsky.cjs.map +0 -1
  129. package/dist/SubscriptionsScreen-Y4UgpC1Y.mjs.map +0 -1
  130. package/dist/de-69v-QMl3.mjs +0 -6
  131. package/dist/de-69v-QMl3.mjs.map +0 -1
  132. package/dist/de-CvBkoR8P.cjs +0 -12
  133. package/dist/de-CvBkoR8P.cjs.map +0 -1
  134. package/dist/el-CP3qYmjt.cjs +0 -12
  135. package/dist/el-CP3qYmjt.cjs.map +0 -1
  136. package/dist/el-moRf_431.mjs +0 -6
  137. package/dist/el-moRf_431.mjs.map +0 -1
  138. package/dist/es-BAjIJqb8.mjs +0 -6
  139. package/dist/es-BAjIJqb8.mjs.map +0 -1
  140. package/dist/es-DdHDXWW1.cjs +0 -12
  141. package/dist/es-DdHDXWW1.cjs.map +0 -1
  142. package/dist/fr-B6rL2HtM.mjs +0 -6
  143. package/dist/fr-B6rL2HtM.mjs.map +0 -1
  144. package/dist/fr-wZG7Wsps.cjs +0 -12
  145. package/dist/fr-wZG7Wsps.cjs.map +0 -1
  146. package/dist/he-B5y3gSwp.mjs +0 -6
  147. package/dist/he-B5y3gSwp.mjs.map +0 -1
  148. package/dist/he-C_xAhEyE.cjs +0 -12
  149. package/dist/he-C_xAhEyE.cjs.map +0 -1
  150. package/dist/hu-BYzcu3lh.mjs +0 -6
  151. package/dist/hu-BYzcu3lh.mjs.map +0 -1
  152. package/dist/hu-CttQPNpi.cjs +0 -12
  153. package/dist/hu-CttQPNpi.cjs.map +0 -1
  154. package/dist/id-D_R-JS-K.mjs +0 -6
  155. package/dist/id-D_R-JS-K.mjs.map +0 -1
  156. package/dist/id-iykEHp5z.cjs +0 -12
  157. package/dist/id-iykEHp5z.cjs.map +0 -1
  158. package/dist/it-BM8H-5lK.mjs +0 -6
  159. package/dist/it-BM8H-5lK.mjs.map +0 -1
  160. package/dist/it-aOan3LJA.cjs +0 -12
  161. package/dist/it-aOan3LJA.cjs.map +0 -1
  162. package/dist/ja-DJwh8O25.cjs +0 -12
  163. package/dist/ja-DJwh8O25.cjs.map +0 -1
  164. package/dist/ja-uq5fuZ2n.mjs +0 -6
  165. package/dist/ja-uq5fuZ2n.mjs.map +0 -1
  166. package/dist/ko-BrOveybS.cjs +0 -12
  167. package/dist/ko-BrOveybS.cjs.map +0 -1
  168. package/dist/ko-DCZTj-Cn.mjs +0 -6
  169. package/dist/ko-DCZTj-Cn.mjs.map +0 -1
  170. package/dist/nl-BOJJj-wO.mjs +0 -6
  171. package/dist/nl-BOJJj-wO.mjs.map +0 -1
  172. package/dist/nl-CwVoaQ7l.cjs +0 -12
  173. package/dist/nl-CwVoaQ7l.cjs.map +0 -1
  174. package/dist/pl-Cjublhfj.mjs +0 -6
  175. package/dist/pl-Cjublhfj.mjs.map +0 -1
  176. package/dist/pl-CxlPZSW0.cjs +0 -12
  177. package/dist/pl-CxlPZSW0.cjs.map +0 -1
  178. package/dist/pt-DIdr0upI.cjs +0 -12
  179. package/dist/pt-DIdr0upI.cjs.map +0 -1
  180. package/dist/pt-Dj1-G3ee.mjs +0 -6
  181. package/dist/pt-Dj1-G3ee.mjs.map +0 -1
  182. package/dist/ro-94vihNFf.mjs +0 -6
  183. package/dist/ro-94vihNFf.mjs.map +0 -1
  184. package/dist/ro-B_Do9sPB.cjs +0 -12
  185. package/dist/ro-B_Do9sPB.cjs.map +0 -1
  186. package/dist/ru-CeRancbh.cjs +0 -12
  187. package/dist/ru-CeRancbh.cjs.map +0 -1
  188. package/dist/ru-DoATiIwu.mjs +0 -6
  189. package/dist/ru-DoATiIwu.mjs.map +0 -1
  190. package/dist/static-dict-adapter-Bc5RtEkZ.mjs.map +0 -1
  191. package/dist/static-dict-adapter-Bxrw9FK5.cjs.map +0 -1
  192. package/dist/th-B43cNBU0.cjs +0 -12
  193. package/dist/th-B43cNBU0.cjs.map +0 -1
  194. package/dist/th-YR02xDFQ.mjs +0 -6
  195. package/dist/th-YR02xDFQ.mjs.map +0 -1
  196. package/dist/tl-CHqst9js.cjs +0 -12
  197. package/dist/tl-CHqst9js.cjs.map +0 -1
  198. package/dist/tl-RXmEp0_X.mjs +0 -6
  199. package/dist/tl-RXmEp0_X.mjs.map +0 -1
  200. package/dist/tr-BuEAVG9I.mjs +0 -6
  201. package/dist/tr-BuEAVG9I.mjs.map +0 -1
  202. package/dist/tr-DYe4JMxj.cjs +0 -12
  203. package/dist/tr-DYe4JMxj.cjs.map +0 -1
  204. package/dist/zh_CN-CUeI99z0.cjs +0 -12
  205. package/dist/zh_CN-CUeI99z0.cjs.map +0 -1
  206. package/dist/zh_CN-NCLMiB-i.mjs +0 -6
  207. package/dist/zh_CN-NCLMiB-i.mjs.map +0 -1
  208. package/dist/zh_TW-CgTn_SV4.cjs +0 -12
  209. package/dist/zh_TW-CgTn_SV4.cjs.map +0 -1
  210. package/dist/zh_TW-CtEmIukX.mjs +0 -6
  211. package/dist/zh_TW-CtEmIukX.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ContactsScreen-B9I61v6-.cjs","names":["createTranslationContext","Button","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","BreadcrumbPage","cn","cn","ChevronRight","Plus","Search","Input","cn","parseApiErrors","parseApiErrors","z","useZodForm","Mail","Phone","MapPin","parseApiErrors","parseApiErrors","parseApiErrors","parseApiErrors","useEditor","StarterKit","Heading","Placeholder","TextAlign","Underline","cn","AlignLeft","AlignCenter","AlignRight","AlignJustify","List","ListOrdered","Calendar","X","EditorContent","Sheet","SheetContent","SheetHeader","SheetTitle","Input","Calendar","X","SheetFooter","Button","formatDueDate","EmptyState","ClipboardList","SquareCheckBig","Plus","parseTaskBody","CircleCheck","cn","DropdownMenu","DropdownMenuTrigger","Button","EllipsisVertical","DropdownMenuContent","DropdownMenuItem","Calendar","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","parseApiErrors","parseApiErrors","parseApiErrors","StickyNote","Pen","Plus","DropdownMenu","DropdownMenuTrigger","EllipsisVertical","DropdownMenuContent","DropdownMenuItem","Calendar","Paperclip","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","cn","FormField","FormItem","FormLabel","FormControl","Input","FormMessage","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","ArrowLeft","Button","Spinner","cn","Plus","Card","CardContent","FormProvider","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","ChevronLeft","Phone","Mail","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","Trash2","cn","Users","cn","parseApiErrors","portalTenantContacts.contacts_show","portalTenantContacts.contacts_list","portalTenantContacts.contacts_create","portalTenantContacts.contacts_update","portalTenantContacts.contacts_destroy","portalTenantContacts.contacts_bulk_destroy","portalTenantContacts.contacts_notes_list","portalTenantContacts.contacts_notes_create","portalTenantContacts.contacts_notes_update","portalTenantContacts.contacts_notes_destroy","portalTenantContacts.contacts_tasks_list","portalTenantContacts.contacts_tasks_create","portalTenantContacts.contacts_tasks_update","portalTenantContacts.contacts_tasks_destroy","portalTenantContacts.contacts_groups_list","portalTenantContacts.contacts_groups_create","portalTenantContacts.contacts_groups_update","portalTenantContacts.contacts_groups_destroy","usePortalTenantClient","createDomainTranslations","createStaticDictAdapter","useActiveLocale","useDomainDict","useCountriesApi","storeKeys","useZodForm","FormProvider"],"sources":["../../../contacts/core/src/translation-api-context.ts","../../../contacts/ui/src/screens/ContactCreateScreen.tsx","../../../contacts/core/src/contacts-api-context.ts","../../../contacts/core/src/query-keys.ts","../../../contacts/core/src/hooks/use-infinite-contacts.ts","../../../contacts/ui/src/portal/hooks/groups/use-groups.ts","../../../contacts/ui/src/shared/components/contacts/statusBadge.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/utils.ts","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsSidebarRow.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsSidebar.tsx","../../../contacts/ui/src/shared/hooks/useContactDetail.ts","../../../contacts/ui/src/shared/hooks/useUpdateContactMutation.ts","../../../contacts/ui/src/shared/hooks/useDeleteContactMutation.ts","../../../contacts/ui/src/shared/schemas/contactFormSchema.ts","../../../contacts/ui/src/shared/hooks/useContactDetailPage.ts","../../../contacts/ui/src/portal/hooks/contacts/use-contact-tasks.ts","../../../contacts/ui/src/portal/hooks/notes/use-contact-notes.ts","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailHero.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactInfoRow.tsx","../../../contacts/ui/src/portal/hooks/contacts/use-toggle-task-completion.ts","../../../contacts/ui/src/portal/hooks/contacts/use-delete-contact-task.ts","../../../contacts/ui/src/portal/hooks/contacts/use-create-contact-task.ts","../../../contacts/ui/src/portal/hooks/contacts/use-update-contact-task.ts","../../../contacts/ui/src/portal/utils/format-date.ts","../../../contacts/ui/src/portal/components/editor/note-task-editor.tsx","../../../contacts/ui/src/portal/components/editor/note-task-modal.tsx","../../../contacts/ui/src/portal/components/tasks/task-list.tsx","../../../contacts/ui/src/portal/hooks/notes/use-delete-contact-note.ts","../../../contacts/ui/src/portal/hooks/notes/use-create-contact-note.ts","../../../contacts/ui/src/portal/hooks/notes/use-update-contact-note.ts","../../../contacts/ui/src/portal/components/notes/notes-list.tsx","../../../contacts/ui/src/shared/components/contacts/contactDetailsForm.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailTabs.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailPane.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsEmptyState.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/RepContactsLayout.tsx","../../../contacts/ui/src/shared/hooks/useCreateContactMutation.ts","../../../api-clients/portal-tenant-contacts/src/namespaces/portal_tenant_contacts.ts","../src/adapters/contacts-api-adapter.ts","../src/contacts/PortalContactsApiProvider.tsx","../../../contacts/core/src/translation-dictionary.ts","../../../contacts/core/src/translation-adapter.ts","../src/providers/ContactsTranslationBridge.tsx","../src/screens/ContactsScreen.tsx"],"sourcesContent":["import { createTranslationContext } from \"@fluid-app/i18n/translation-api-context-factory\";\nimport type { ContactsDict } from \"./translation-dictionary\";\n\nconst { Provider, useTranslation } =\n createTranslationContext<ContactsDict>(\"Contacts\");\n\nexport const ContactsTranslationProvider = Provider;\nexport const useContactsTranslation = useTranslation;\n","\"use client\";\n\nimport { useMemo, type ReactNode } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n Button,\n} from \"@fluid-app/ui-primitives\";\nimport {\n useScreenHeaderActions,\n useScreenHeaderBreadcrumbs,\n} from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport interface ContactCreateScreenProps {\n onNavigateToList: () => void;\n onSubmit: () => void;\n isPending: boolean;\n children: ReactNode;\n}\n\nexport function ContactCreateScreen({\n onNavigateToList,\n onSubmit,\n isPending,\n children,\n}: ContactCreateScreenProps) {\n const { t } = useContactsTranslation();\n\n const headerActions = useMemo(\n () => (\n <>\n <Button\n variant=\"outline\"\n onClick={onNavigateToList}\n disabled={isPending}\n >\n {t(\"cancel\")}\n </Button>\n <Button onClick={onSubmit} disabled={isPending}>\n {isPending ? t(\"adding\") : t(\"add_contact\")}\n </Button>\n </>\n ),\n [onNavigateToList, onSubmit, isPending, t],\n );\n useScreenHeaderActions(headerActions);\n\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n {t(\"breadcrumb\")}\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n {t(\"breadcrumb_new\")}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [onNavigateToList, t],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return <>{children}</>;\n}\n","import { createContext, useContext } from \"react\";\nimport type { ContactsApi } from \"./contacts-api\";\nimport type { NotesApi } from \"./notes-api\";\nimport type { TasksApi } from \"./tasks-api\";\nimport type { GroupsApi } from \"./groups-api\";\n\nexport interface ContactsDomainApi {\n contacts: ContactsApi;\n notes: NotesApi;\n tasks: TasksApi;\n groups?: GroupsApi;\n}\n\nconst ContactsApiContext = createContext<ContactsDomainApi | null>(null);\n\nexport const ContactsApiProvider = ContactsApiContext.Provider;\n\nexport function useContactsDomainApi(): ContactsDomainApi {\n const api = useContext(ContactsApiContext);\n if (!api) {\n throw new Error(\n \"useContactsDomainApi must be used within a ContactsApiProvider\",\n );\n }\n return api;\n}\n\nexport function useContactsCrud(): ContactsApi {\n return useContactsDomainApi().contacts;\n}\n\nexport function useNotesApi(): NotesApi {\n return useContactsDomainApi().notes;\n}\n\nexport function useTasksApi(): TasksApi {\n return useContactsDomainApi().tasks;\n}\n\n/** Returns GroupsApi if the provider supplies one, otherwise null. */\nexport function useGroupsApi(): GroupsApi | null {\n return useContactsDomainApi().groups ?? null;\n}\n","export const CONTACTS_QUERY_KEYS = {\n all: (prefix: string) => [prefix] as const,\n list: (prefix: string) =>\n [...CONTACTS_QUERY_KEYS.all(prefix), \"list\"] as const,\n detail: (prefix: string, id: string) =>\n [...CONTACTS_QUERY_KEYS.all(prefix), \"detail\", id] as const,\n} as const;\n\nexport const contactsKeys = {\n activities: (contactId: string) =>\n [\"portal-contacts\", \"activities\", contactId] as const,\n tasks: (contactId: string) =>\n [\"portal-contacts\", \"tasks\", contactId] as const,\n notes: (contactId: string) =>\n [\"portal-contacts\", \"notes\", contactId] as const,\n orders: (contactId: string) => [\"rep-contacts\", \"orders\", contactId] as const,\n subscriptionOrders: (contactId: string) =>\n [\"rep-contacts\", \"subscription-orders\", contactId] as const,\n groups: () => [\"portal-contacts\", \"groups\"] as const,\n} as const;\n","import { useInfiniteQuery } from \"@tanstack/react-query\";\nimport { useContactsCrud } from \"../contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"../query-keys\";\n\nexport interface UseInfiniteContactsParams {\n search_query?: string;\n status?: string;\n sort_by?: string;\n sort_direction?: string;\n per_page?: number;\n tags?: string[];\n}\n\nexport function useInfiniteContacts(params: UseInfiniteContactsParams) {\n const api = useContactsCrud();\n return useInfiniteQuery({\n queryKey: [...CONTACTS_QUERY_KEYS.list(\"contacts\"), params],\n queryFn: ({ pageParam }) =>\n api.listContacts({\n ...params,\n page: pageParam,\n }),\n getNextPageParam: (lastPage) => {\n const currentPage = lastPage.meta.current_page;\n // Contacts API is page-number based; next_cursor and total_pages\n // are both used as \"has-next-page\" signals.\n if (currentPage == null) return undefined;\n if (lastPage.meta.next_cursor) return currentPage + 1;\n if (\n lastPage.meta.total_pages != null &&\n currentPage < lastPage.meta.total_pages\n ) {\n return currentPage + 1;\n }\n return undefined;\n },\n initialPageParam: 1,\n });\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useGroupsApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useGroups() {\n const api = useGroupsApi();\n\n return useQuery({\n queryKey: contactsKeys.groups(),\n queryFn: () => api!.listGroups(),\n enabled: !!api,\n select: (data) => data.groups,\n });\n}\n","import React from \"react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\n\nconst statusStyles: Record<string, string> = {\n // Contact statuses\n new: \"border-[var(--status-new-border)] bg-[var(--status-new)] text-[var(--status-new-foreground)]\",\n active:\n \"border-[var(--status-active-border)] bg-[var(--status-active)] text-[var(--status-active-foreground)]\",\n inactive: \"border-border bg-muted text-muted-foreground\",\n lead: \"border-[var(--status-lead-border)] bg-[var(--status-lead)] text-[var(--status-lead-foreground)]\",\n customer:\n \"border-[var(--status-customer-border)] bg-[var(--status-customer)] text-[var(--status-customer-foreground)]\",\n // Semantic categories (orders, subscriptions, etc.)\n success:\n \"border-[var(--badge-success-border)] bg-[var(--badge-success)] text-[var(--badge-success-foreground)]\",\n warning:\n \"border-[var(--badge-warning-border)] bg-[var(--badge-warning)] text-[var(--badge-warning-foreground)]\",\n danger:\n \"border-[var(--badge-danger-border)] bg-[var(--badge-danger)] text-[var(--badge-danger-foreground)]\",\n info: \"border-[var(--badge-info-border)] bg-[var(--badge-info)] text-[var(--badge-info-foreground)]\",\n neutral: \"border-border bg-muted text-muted-foreground\",\n notice:\n \"border-[var(--badge-notice-border)] bg-[var(--badge-notice)] text-[var(--badge-notice-foreground)]\",\n accent:\n \"border-[var(--badge-accent-border)] bg-[var(--badge-accent)] text-[var(--badge-accent-foreground)]\",\n};\n\nconst defaultStyle = \"border-border bg-muted text-muted-foreground\";\n\nexport type StatusBadgeVariant = keyof typeof statusStyles;\n\nexport function getStatusStyle(status: string): string {\n return statusStyles[status] ?? defaultStyle;\n}\n\nexport function StatusBadge({\n status,\n label,\n className,\n}: {\n status: string;\n label?: string;\n className?: string;\n}): React.JSX.Element {\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold capitalize\",\n getStatusStyle(status),\n className,\n )}\n >\n {label ?? status}\n </span>\n );\n}\n","import type { Contact } from \"@fluid-app/contacts-core/types\";\n\nexport function getDisplayName(contact: Contact): string {\n if (contact.full_name && contact.full_name.trim().length > 0) {\n return contact.full_name;\n }\n const parts = [contact.first_name, contact.last_name].filter(Boolean);\n if (parts.length > 0) return parts.join(\" \");\n if (contact.email) return contact.email;\n return \"Contact\";\n}\n\nexport function getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n/** Lowercase relative label derived from `contact.updated_at`.\n * Returns null if the timestamp is missing or unparseable. Lowercase on\n * purpose so callers can compose phrases like \"Last updated 3 days ago\"\n * without an awkward \"Last updated Today\". */\nexport function getRelativeUpdated(contact: Contact): string | null {\n const updated =\n typeof contact.updated_at === \"string\" ? contact.updated_at : null;\n if (!updated) return null;\n const date = new Date(updated);\n if (Number.isNaN(date.getTime())) return null;\n\n const diffMs = Date.now() - date.getTime();\n const day = 1000 * 60 * 60 * 24;\n const diffDays = Math.floor(diffMs / day);\n\n if (diffDays <= 0) return \"today\";\n if (diffDays === 1) return \"yesterday\";\n if (diffDays < 7) return `${diffDays} days ago`;\n if (diffDays < 30) {\n const weeks = Math.floor(diffDays / 7);\n return weeks === 1 ? \"1 week ago\" : `${weeks} weeks ago`;\n }\n if (diffDays < 365) {\n const months = Math.floor(diffDays / 30);\n return months === 1 ? \"1 month ago\" : `${months} months ago`;\n }\n const years = Math.floor(diffDays / 365);\n return years === 1 ? \"1 year ago\" : `${years} years ago`;\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { StatusBadge } from \"../../../../shared/components/contacts/statusBadge\";\nimport { getDisplayName, getInitials, getRelativeUpdated } from \"./utils\";\n\nexport interface ContactsSidebarRowProps {\n contact: Contact;\n isSelected: boolean;\n onSelect: (id: string) => void;\n}\n\nexport function ContactsSidebarRow({\n contact,\n isSelected,\n onSelect,\n}: ContactsSidebarRowProps): React.JSX.Element {\n const name = getDisplayName(contact);\n const id = String(contact.id);\n const status = contact.status?.trim() || null;\n const relativeLabel = getRelativeUpdated(contact);\n const secondary = contact.email ?? status ?? null;\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(id)}\n aria-current={isSelected ? \"true\" : undefined}\n className={cn(\n \"group flex w-full items-center gap-3.5 rounded-xl px-3 py-3 text-left transition-colors\",\n isSelected ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n >\n <div className=\"bg-muted text-muted-foreground relative flex size-12 shrink-0 items-center justify-center overflow-hidden rounded-xl text-base font-semibold shadow-sm\">\n {contact.avatar_url ? (\n <img\n alt={name}\n src={contact.avatar_url}\n className=\"size-12 object-cover\"\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(name)}</span>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-foreground truncate text-sm font-bold tracking-tight\">\n {name}\n </span>\n {status && <StatusBadge status={status} className=\"shrink-0\" />}\n </div>\n <div className=\"text-muted-foreground mt-0.5 flex items-center gap-2 text-sm\">\n {secondary && <span className=\"truncate\">{secondary}</span>}\n {secondary && relativeLabel && (\n <span\n className=\"text-muted-foreground/60 shrink-0 text-xs\"\n aria-hidden=\"true\"\n >\n ·\n </span>\n )}\n {relativeLabel && (\n <span className=\"text-muted-foreground/60 shrink-0 text-xs\">\n {relativeLabel}\n </span>\n )}\n </div>\n </div>\n\n <ChevronRight\n className={cn(\n \"size-4 shrink-0 transition-all\",\n isSelected\n ? \"text-foreground\"\n : \"text-muted-foreground/60 group-hover:text-foreground group-hover:translate-x-0.5\",\n )}\n aria-hidden=\"true\"\n />\n </button>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Plus, Search } from \"lucide-react\";\nimport { cn, Input } from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useGroups } from \"../../../hooks/groups/use-groups\";\nimport { ContactsSidebarRow } from \"./ContactsSidebarRow\";\n\nexport interface ContactsSidebarProps {\n selectedContactId: string | null;\n onSelect: (id: string) => void;\n onAdd: () => void;\n}\n\nconst DEBOUNCE_MS = 200;\n\ntype FilterValue =\n | { kind: \"all\" }\n | { kind: \"status\"; status: \"lead\" | \"customer\" }\n | { kind: \"group\"; tag: string };\n\nfunction useBuiltInFilters(): {\n id: string;\n label: string;\n value: FilterValue;\n}[] {\n const { t } = useContactsTranslation();\n return [\n { id: \"all\", label: t(\"filter_all\"), value: { kind: \"all\" } },\n {\n id: \"status:lead\",\n label: t(\"filter_leads\"),\n value: { kind: \"status\", status: \"lead\" },\n },\n {\n id: \"status:customer\",\n label: t(\"filter_customers\"),\n value: { kind: \"status\", status: \"customer\" },\n },\n ];\n}\n\nfunction filterId(value: FilterValue): string {\n if (value.kind === \"all\") return \"all\";\n if (value.kind === \"status\") return `status:${value.status}`;\n return `group:${value.tag}`;\n}\n\nexport function ContactsSidebar({\n selectedContactId,\n onSelect,\n onAdd,\n}: ContactsSidebarProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [filter, setFilter] = useState<FilterValue>({ kind: \"all\" });\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const { data: groups = [] } = useGroups();\n\n const queryParams = useMemo(\n () => ({\n search_query: debouncedSearch || undefined,\n tags: filter.kind === \"group\" ? [filter.tag] : undefined,\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 50,\n }),\n [debouncedSearch, filter],\n );\n\n const {\n data,\n isLoading,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n isError,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n const visibleContacts = useMemo(() => {\n if (filter.kind === \"status\") {\n return contacts.filter((c) => c.status === filter.status);\n }\n return contacts;\n }, [contacts, filter]);\n\n // Server `total_count` ignores the client-side status filter, so when a\n // status pill is active we report the locally-filtered count instead.\n const serverTotalCount = data?.pages[0]?.meta.total_count ?? contacts.length;\n const subtitleCount =\n filter.kind === \"status\" ? visibleContacts.length : serverTotalCount;\n\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // Auto-select the first contact on initial load so the right pane shows\n // detail instead of the empty state. Desktop only — on mobile the layout\n // hides the sidebar when a contact is selected, so auto-selecting would\n // drop the rep straight into a detail view with no list visible. Ref\n // guards re-fires so explicit deselects (back button, post-delete, filter\n // changes) don't get clobbered.\n const hasAutoSelectedRef = useRef(false);\n useEffect(() => {\n if (hasAutoSelectedRef.current) return;\n if (selectedContactId) {\n hasAutoSelectedRef.current = true;\n return;\n }\n if (isLoading || visibleContacts.length === 0) return;\n const isDesktop =\n typeof window === \"undefined\" ||\n window.matchMedia(\"(min-width: 768px)\").matches;\n if (!isDesktop) {\n hasAutoSelectedRef.current = true;\n return;\n }\n const first = visibleContacts[0];\n if (first) {\n hasAutoSelectedRef.current = true;\n onSelect(String(first.id));\n }\n }, [selectedContactId, isLoading, visibleContacts, onSelect]);\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel || !hasNextPage) return;\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (entry?.isIntersecting && !isFetchingNextPage) {\n fetchNextPage();\n }\n });\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n const activeFilterId = filterId(filter);\n\n return (\n <>\n <div className=\"px-7 pt-8 pb-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <h1 className=\"text-foreground text-2xl font-extrabold tracking-tight\">\n {t(\"breadcrumb\")}\n </h1>\n <p className=\"text-muted-foreground mt-1.5 text-sm\">\n {isLoading\n ? t(\"loading\")\n : hasNextPage && filter.kind === \"status\"\n ? t(\"searching\")\n : subtitleCount === 1\n ? t(\"person_count\", { count: subtitleCount })\n : t(\"people_count\", { count: subtitleCount })}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={onAdd}\n className=\"bg-foreground text-background hover:bg-foreground/90 inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-bold transition-colors\"\n >\n <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n {t(\"add\")}\n </button>\n </div>\n </div>\n\n <div className=\"px-6 pb-3\">\n <div className=\"bg-muted focus-within:ring-foreground/20 flex items-center gap-2.5 rounded-xl px-3.5 py-2.5 transition focus-within:ring-2\">\n <Search\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n <Input\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={t(\"search_placeholder\")}\n type=\"search\"\n className=\"placeholder:text-muted-foreground/80 h-auto flex-1 border-0 bg-transparent p-0 text-sm font-medium shadow-none focus-visible:ring-0\"\n aria-label={t(\"search_placeholder\")}\n />\n </div>\n </div>\n\n <FilterPills\n activeId={activeFilterId}\n groups={groups.map((g) => g.name)}\n onChange={setFilter}\n />\n\n <div className=\"flex-1 overflow-y-auto px-3 pb-8\">\n {isError ? (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {t(\"error_loading_list\")}\n </div>\n ) : isLoading ? (\n <SidebarSkeleton />\n ) : visibleContacts.length === 0 ? (\n // Status filters apply client-side, so an empty visible list with\n // more pages still pending means matching contacts may be on later\n // pages. Keep the sentinel mounted so the IntersectionObserver can\n // continue paging until we either find matches or exhaust the data.\n <div className=\"space-y-2\">\n {hasNextPage || isFetchingNextPage ? (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {t(\"searching\")}\n </div>\n ) : (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : filter.kind === \"all\"\n ? t(\"no_contacts_yet\")\n : t(\"no_contacts_filter\")}\n </div>\n )}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n </div>\n ) : (\n <div className=\"space-y-1\">\n {visibleContacts.map((contact) => (\n <ContactsSidebarRow\n key={contact.id}\n contact={contact}\n isSelected={String(contact.id) === selectedContactId}\n onSelect={onSelect}\n />\n ))}\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground py-3 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </div>\n )}\n </div>\n </>\n );\n}\n\ninterface FilterPillsProps {\n activeId: string;\n groups: string[];\n onChange: (filter: FilterValue) => void;\n}\n\nfunction FilterPills({ activeId, groups, onChange }: FilterPillsProps) {\n const builtInFilters = useBuiltInFilters();\n const allFilters = useMemo<\n { id: string; label: string; value: FilterValue }[]\n >(\n () => [\n ...builtInFilters,\n ...groups.map((tag) => ({\n id: `group:${tag}`,\n label: tag,\n value: { kind: \"group\" as const, tag },\n })),\n ],\n [builtInFilters, groups],\n );\n\n return (\n <div className=\"px-6 pb-4\">\n <div className=\"flex gap-1.5 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {allFilters.map(({ id, label, value }) => {\n const isActive = id === activeId;\n return (\n <button\n key={id}\n type=\"button\"\n onClick={() => onChange(value)}\n aria-pressed={isActive}\n className={cn(\n \"shrink-0 rounded-full px-4 py-1.5 text-sm font-semibold capitalize transition-colors\",\n isActive\n ? \"bg-foreground text-background\"\n : \"border-border bg-muted text-foreground hover:bg-muted/70 border\",\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"space-y-1.5 px-1\">\n {[0, 1, 2, 3, 4].map((i) => (\n <div\n key={i}\n className=\"flex items-center gap-3 rounded-xl px-3 py-3\"\n aria-hidden=\"true\"\n >\n <div className=\"bg-muted size-12 shrink-0 animate-pulse rounded-xl\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"bg-muted h-3.5 w-3/5 animate-pulse rounded\" />\n <div className=\"bg-muted h-3 w-4/5 animate-pulse rounded\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useContactDetail(\n contactId: string,\n queryKeyPrefix = \"contacts\",\n) {\n const api = useContactsCrud();\n\n return useQuery({\n queryKey: CONTACTS_QUERY_KEYS.detail(queryKeyPrefix, contactId),\n queryFn: () => api.getContact(contactId),\n enabled: !!contactId,\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\ntype UpdateInput = {\n id: string;\n data: Record<string, unknown>;\n};\n\nexport function useUpdateContactMutation(\n contactId: string,\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: ({ id, data }: UpdateInput) => api.updateContact(id, data),\n onSuccess: () => {\n fluidToast({ title: \"Contact updated successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to save contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n options?.onError?.(error);\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactMutation(\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: (contactId: string) => api.deleteContact(contactId),\n onSuccess: () => {\n fluidToast({ title: \"Contact deleted successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n options?.onError?.(error);\n },\n });\n}\n","import { z } from \"zod\";\n\n/**\n * Form schema for creating a contact.\n * Matches CompanyContactCreate / ContactCreate from the OpenAPI spec.\n *\n * @see CompanyContactCreate in company_contacts.d.ts\n * @see ContactCreate in users_contacts.d.ts\n */\nexport const createContactFormSchema = z.object({\n first_name: z.string().min(1, { message: \"First name is required\" }),\n last_name: z.string().min(1, { message: \"Last name is required\" }),\n status: z.string().nullable().optional(),\n email: z.string().email().or(z.literal(\"\")).nullable().optional(),\n phone: z.string().nullable().optional(),\n address: z.string().nullable().optional(),\n city: z.string().nullable().optional(),\n state: z.string().nullable().optional(),\n postal_code: z.string().nullable().optional(),\n country_code: z.coerce.string().nullable().optional(),\n language_code: z.coerce.string().nullable().optional(),\n affiliate: z.record(z.string(), z.unknown()).nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type CreateContactFormData = z.infer<typeof createContactFormSchema>;\n\n/**\n * Form schema for editing a contact.\n * Same fields as create plus id. Uses .passthrough() so extra fields\n * from the Contact read model (full_name, avatar_url, etc.) don't\n * cause validation failures.\n *\n * @see CompanyContactUpdate in company_contacts.d.ts\n */\nexport const editContactFormSchema = createContactFormSchema.passthrough();\n\nexport type EditContactFormData = z.infer<typeof editContactFormSchema>;\n","\"use client\";\n\nimport { useMemo, useCallback } from \"react\";\nimport { useZodForm, fluidToast } from \"@fluid-app/ui-primitives\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useContactDetail } from \"./useContactDetail\";\nimport { useUpdateContactMutation } from \"./useUpdateContactMutation\";\nimport { useDeleteContactMutation } from \"./useDeleteContactMutation\";\nimport {\n createContactFormSchema,\n editContactFormSchema,\n type EditContactFormData,\n} from \"../schemas/contactFormSchema\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\n\nconst mutableKeys = Object.keys(\n createContactFormSchema.shape,\n) as (keyof EditContactFormData)[];\n\nexport function useContactDetailPage(\n contactId: string,\n options?: {\n queryKeyPrefix?: string;\n getCountries?: () => Promise<{ id: number; name: string; iso?: string }[]>;\n onDeleteSuccess?: () => void;\n },\n): {\n contact: Contact | undefined;\n isLoading: boolean;\n methods: UseFormReturn<EditContactFormData>;\n countryOptions: { name: string; value: string }[];\n isDirty: boolean;\n isSubmitting: boolean;\n isDeleting: boolean;\n onSave: () => void;\n onDelete: () => void;\n} {\n const queryKeyPrefix = options?.queryKeyPrefix ?? \"contacts\";\n\n const { data, isLoading } = useContactDetail(contactId, queryKeyPrefix);\n\n const { data: countries } = useQuery({\n queryKey: [\"countries\"],\n queryFn: options?.getCountries ?? (() => Promise.resolve([])),\n enabled: !!options?.getCountries,\n });\n\n const countryOptions = useMemo(\n () =>\n [\n ...(countries?.map((c) => ({\n name: c.name,\n value: c.iso ?? c.id.toString(),\n })) ?? []),\n ].sort((a, b) => a.name.localeCompare(b.name)),\n [countries],\n );\n\n const contact = data?.contact;\n\n // Map nested country object to the ISO code the form select expects\n const formValues = useMemo(() => {\n if (!contact) return undefined;\n return {\n ...contact,\n country_code:\n contact.country?.iso ?? contact.country_id?.toString() ?? null,\n } as unknown as EditContactFormData;\n }, [contact]);\n\n const methods = useZodForm<EditContactFormData>(editContactFormSchema, {\n values: formValues,\n mode: \"onBlur\",\n });\n\n const updateMutation = useUpdateContactMutation(contactId, queryKeyPrefix, {\n onSuccess: () => {\n methods.reset(methods.getValues());\n },\n });\n\n const deleteMutation = useDeleteContactMutation(queryKeyPrefix, {\n onSuccess: () => {\n options?.onDeleteSuccess?.();\n },\n });\n\n const onSave = useCallback(() => {\n methods.handleSubmit(\n (formData) => {\n const payload: Record<string, unknown> = {};\n for (const key of mutableKeys) {\n if (key in formData) {\n payload[key] = formData[key];\n }\n }\n\n updateMutation.mutate({\n id: contactId,\n data: payload,\n });\n },\n (errors) => {\n const errorMessages = Object.entries(errors)\n .map(([field, err]) => {\n const msg =\n typeof err?.message === \"string\" ? err.message : \"invalid\";\n return `${field.replace(/_/g, \" \")}: ${msg}`;\n })\n .join(\", \");\n fluidToast({\n title: \"Please fix the form errors before saving\",\n description: errorMessages || undefined,\n type: \"error\",\n });\n },\n )();\n }, [methods, updateMutation, contactId]);\n\n const onDelete = useCallback(() => {\n deleteMutation.mutate(contactId);\n }, [deleteMutation, contactId]);\n\n return {\n contact,\n isLoading,\n methods,\n countryOptions,\n isDirty: methods.formState.isDirty,\n isSubmitting: updateMutation.isPending,\n isDeleting: deleteMutation.isPending,\n onSave,\n onDelete,\n };\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { ContactTask } from \"@fluid-app/contacts-core/types\";\n\nexport type { ContactTask };\n\nexport const CONTACT_TASKS_QUERY_KEY = (contactId: string) =>\n contactsKeys.tasks(contactId);\n\nexport function useContactTasks(contactId: string) {\n const api = useTasksApi();\n\n return useQuery({\n queryKey: contactsKeys.tasks(contactId),\n queryFn: () => api.listTasks(contactId),\n enabled: !!contactId,\n select: (data) => data.tasks,\n });\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { ContactNote } from \"@fluid-app/contacts-core/types\";\n\nexport type { ContactNote };\n\nexport const CONTACT_NOTES_QUERY_KEY = (contactId: string) =>\n contactsKeys.notes(contactId);\n\nexport function useContactNotes(contactId: string) {\n const api = useNotesApi();\n\n return useQuery({\n queryKey: contactsKeys.notes(contactId),\n queryFn: () => api.listNotes(contactId),\n enabled: !!contactId,\n select: (data) => data.notes,\n });\n}\n","\"use client\";\n\nimport React from \"react\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { StatusBadge } from \"../../../../shared/components/contacts/statusBadge\";\nimport { getDisplayName, getInitials, getRelativeUpdated } from \"./utils\";\n\nexport interface ContactDetailHeroProps {\n contact: Contact;\n tasksCount: number;\n notesCount: number;\n}\n\nexport function ContactDetailHero({\n contact,\n tasksCount,\n notesCount,\n}: ContactDetailHeroProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const name = getDisplayName(contact);\n const status = contact.status?.trim();\n const lastUpdated = getRelativeUpdated(contact);\n\n return (\n <div className=\"flex flex-col gap-5 md:flex-row md:items-start md:justify-between md:gap-8\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:gap-5\">\n <div className=\"bg-muted text-muted-foreground relative flex size-20 shrink-0 items-center justify-center overflow-hidden rounded-xl text-2xl font-semibold shadow-sm md:size-24 md:text-2xl\">\n {contact.avatar_url ? (\n <img\n alt={name}\n src={contact.avatar_url}\n className=\"size-full object-cover\"\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(name)}</span>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-foreground text-2xl leading-tight font-extrabold tracking-tight\">\n {name}\n </h2>\n <div className=\"mt-3 flex flex-wrap items-center gap-2.5\">\n {status && <StatusBadge status={status} />}\n {lastUpdated && (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"last_updated\", { date: lastUpdated })}\n </span>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"bg-muted flex shrink-0 gap-6 rounded-xl px-5 py-4\">\n <Stat label={t(\"tab_tasks\")} value={tasksCount} />\n <div className=\"bg-border w-px\" aria-hidden=\"true\" />\n <Stat label={t(\"tab_notes\")} value={notesCount} />\n </div>\n </div>\n );\n}\n\nfunction Stat({ label, value }: { label: string; value: number }) {\n return (\n <div>\n <div className=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\">\n {label}\n </div>\n <div className=\"text-foreground mt-1 text-lg font-bold tracking-tight\">\n {value}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { Mail, MapPin, Phone } from \"lucide-react\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport interface ContactInfoRowProps {\n contact: Contact;\n}\n\nfunction buildAddressLine(contact: Contact): string | null {\n const parts = [\n contact.address,\n contact.city,\n contact.state,\n contact.postal_code,\n ].filter((part): part is string => Boolean(part?.trim()));\n if (parts.length === 0) return null;\n return parts.join(\", \");\n}\n\nexport function ContactInfoRow({\n contact,\n}: ContactInfoRowProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const address = buildAddressLine(contact);\n\n return (\n <div className=\"border-border bg-card mt-6 grid grid-cols-1 gap-x-6 gap-y-3 rounded-xl border p-4 md:grid-cols-3 md:p-5\">\n <InfoCell\n icon={<Mail className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_email\")}\n value={contact.email}\n notSetLabel={t(\"not_set\")}\n />\n <InfoCell\n icon={<Phone className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_phone\")}\n value={contact.phone}\n notSetLabel={t(\"not_set\")}\n />\n <InfoCell\n icon={<MapPin className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_address\")}\n value={address}\n notSetLabel={t(\"not_set\")}\n />\n </div>\n );\n}\n\ninterface InfoCellProps {\n icon: React.ReactNode;\n label: string;\n value: string | null | undefined;\n notSetLabel: string;\n}\n\nfunction InfoCell({ icon, label, value, notSetLabel }: InfoCellProps) {\n return (\n <div className=\"min-w-0\">\n <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs font-bold tracking-wider uppercase\">\n <span className=\"text-muted-foreground\">{icon}</span>\n {label}\n </div>\n <div className=\"text-foreground mt-1 truncate text-sm font-medium\">\n {value && value.trim().length > 0 ? (\n value\n ) : (\n <span className=\"text-muted-foreground/60 font-normal italic\">\n {notSetLabel}\n </span>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useToggleTaskCompletion(contactId: string) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: ({\n taskId,\n isCompleted,\n }: {\n taskId: number;\n isCompleted: boolean;\n }) =>\n api.updateTask(taskId, contactId, {\n completed_at: isCompleted ? null : new Date().toISOString(),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: (taskId: number) => api.deleteTask(taskId, contactId),\n onSuccess: () => {\n fluidToast({ title: \"Task deleted\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateTaskInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { CreateTaskInput };\n\nexport function useCreateContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: (input: CreateTaskInput) => api.createTask(contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Task created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to create task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { UpdateTaskInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { UpdateTaskInput };\n\nexport function useUpdateContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: ({\n taskId,\n input,\n }: {\n taskId: number;\n input: UpdateTaskInput;\n }) => api.updateTask(taskId, contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Task updated\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","export function formatDateForDisplay(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { useEditor, EditorContent } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Heading from \"@tiptap/extension-heading\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport Underline from \"@tiptap/extension-underline\";\nimport {\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n List,\n ListOrdered,\n Calendar,\n X,\n} from \"lucide-react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport { formatDateForDisplay } from \"../../utils/format-date\";\n\nexport interface NoteTaskEditorProps {\n titlePlaceholder?: string;\n bodyPlaceholder?: string;\n onChange?: (content: {\n title: string;\n body: string;\n dueDate?: string;\n }) => void;\n className?: string;\n /** Pre-populate the title (for edit mode) */\n initialTitle?: string;\n /** Pre-populate the body (for edit mode) */\n initialBody?: string;\n /** Show due date picker */\n showDueDate?: boolean;\n /** Pre-populate the due date (ISO string, for edit mode) */\n initialDueDate?: string;\n /** When false, the editor is body-only (no H1 title). Default true. */\n showTitle?: boolean;\n /** Override for the editor content area min-height class */\n editorClassName?: string;\n}\n\nfunction extractTitleAndBody(editor: ReturnType<typeof useEditor>): {\n title: string;\n body: string;\n} {\n if (!editor) return { title: \"\", body: \"\" };\n\n const doc = editor.state.doc;\n let title = \"\";\n const bodyParts: string[] = [];\n\n doc.forEach((node) => {\n if (node.type.name === \"heading\" && !title) {\n title = node.textContent.trim();\n } else {\n const text = node.textContent.trim();\n if (text) bodyParts.push(text);\n }\n });\n\n return { title, body: bodyParts.join(\"\\n\") };\n}\n\nfunction extractBodyOnly(editor: ReturnType<typeof useEditor>): string {\n if (!editor) return \"\";\n const parts: string[] = [];\n editor.state.doc.forEach((node) => {\n const text = node.textContent.trim();\n if (text) parts.push(text);\n });\n return parts.join(\"\\n\");\n}\n\nexport function NoteTaskEditor({\n titlePlaceholder = \"New Note\",\n bodyPlaceholder = \"Start writing...\",\n onChange,\n className,\n initialTitle,\n initialBody,\n showDueDate = false,\n initialDueDate,\n showTitle = true,\n editorClassName,\n}: NoteTaskEditorProps): React.JSX.Element {\n const [dueDate, setDueDate] = useState<string | undefined>(initialDueDate);\n const dueDateRef = useRef(initialDueDate);\n const dateInputRef = useRef<HTMLInputElement>(null);\n\n // Keep ref in sync with state so onUpdate always reads the latest value\n useEffect(() => {\n dueDateRef.current = dueDate;\n }, [dueDate]);\n\n const initialContent = showTitle\n ? initialTitle || initialBody\n ? `<h1>${initialTitle ?? \"\"}</h1>${initialBody ?? \"\"}`\n : undefined\n : initialBody || undefined;\n\n const extensions = [\n StarterKit.configure({\n heading: showTitle ? false : { levels: [] as const },\n bulletList: {\n keepMarks: true,\n keepAttributes: false,\n },\n orderedList: {\n keepMarks: true,\n keepAttributes: false,\n },\n }),\n ...(showTitle ? [Heading.configure({ levels: [1] })] : []),\n Placeholder.configure({\n placeholder: ({ node }) => {\n if (node.type.name === \"heading\") {\n return titlePlaceholder;\n }\n return bodyPlaceholder;\n },\n }),\n TextAlign.configure({\n types: showTitle ? [\"heading\", \"paragraph\"] : [\"paragraph\"],\n alignments: [\"left\", \"center\", \"right\", \"justify\"],\n }),\n Underline,\n ];\n\n const defaultContent = showTitle\n ? {\n type: \"doc\" as const,\n content: [{ type: \"heading\" as const, attrs: { level: 1 } }],\n }\n : undefined;\n\n const editor = useEditor({\n extensions,\n content: initialContent ?? defaultContent,\n onUpdate: ({ editor }) => {\n if (showTitle) {\n const { title, body } = extractTitleAndBody(editor);\n onChange?.({ title, body, dueDate: dueDateRef.current });\n } else {\n const body = extractBodyOnly(editor);\n onChange?.({ title: \"\", body, dueDate: dueDateRef.current });\n }\n },\n });\n\n const fireOnChange = () => {\n if (!editor || !onChange) return;\n if (showTitle) {\n const { title, body } = extractTitleAndBody(editor);\n onChange({ title, body, dueDate });\n } else {\n const body = extractBodyOnly(editor);\n onChange({ title: \"\", body, dueDate });\n }\n };\n\n // Fire onChange once on mount so the parent's ref is populated with the\n // initial values before the user makes any edits.\n useEffect(() => {\n fireOnChange();\n // We only want this to run once after the editor is first created.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor]);\n\n // Notify parent when due date changes\n useEffect(() => {\n fireOnChange();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dueDate]);\n\n const buttonBase =\n \"flex h-7 w-7 items-center justify-center rounded text-xs transition-colors\";\n const buttonActive = \"bg-muted text-primary\";\n const buttonInactive = \"text-muted-foreground hover:bg-muted/50\";\n\n const toolbarSeparator = <div className=\"bg-border mx-1 h-5 w-px\" />;\n\n return (\n <div\n className={cn(\n \"border-border flex flex-col overflow-hidden rounded-lg border\",\n className,\n )}\n >\n {/* Toolbar */}\n <div className=\"border-border bg-muted/50 flex items-center gap-0.5 border-b px-2 py-1.5\">\n {/* Bold */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBold().run()}\n disabled={!editor?.can().chain().focus().toggleBold().run()}\n className={cn(\n buttonBase,\n \"font-bold\",\n editor?.isActive(\"bold\") ? buttonActive : buttonInactive,\n )}\n title=\"Bold\"\n >\n B\n </button>\n\n {/* Italic */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleItalic().run()}\n disabled={!editor?.can().chain().focus().toggleItalic().run()}\n className={cn(\n buttonBase,\n \"italic\",\n editor?.isActive(\"italic\") ? buttonActive : buttonInactive,\n )}\n title=\"Italic\"\n >\n I\n </button>\n\n {/* Underline */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleUnderline().run()}\n disabled={!editor?.can().chain().focus().toggleUnderline().run()}\n className={cn(\n buttonBase,\n \"underline\",\n editor?.isActive(\"underline\") ? buttonActive : buttonInactive,\n )}\n title=\"Underline\"\n >\n U\n </button>\n\n {toolbarSeparator}\n\n {/* Align left */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"left\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"left\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align left\"\n >\n <AlignLeft className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align center */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"center\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"center\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align center\"\n >\n <AlignCenter className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align right */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"right\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"right\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align right\"\n >\n <AlignRight className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align justify */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"justify\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"justify\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Justify\"\n >\n <AlignJustify className=\"h-3.5 w-3.5\" />\n </button>\n\n {toolbarSeparator}\n\n {/* Bullet list */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBulletList().run()}\n className={cn(\n buttonBase,\n editor?.isActive(\"bulletList\") ? buttonActive : buttonInactive,\n )}\n title=\"Bullet list\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Ordered list */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleOrderedList().run()}\n className={cn(\n buttonBase,\n editor?.isActive(\"orderedList\") ? buttonActive : buttonInactive,\n )}\n title=\"Ordered list\"\n >\n <ListOrdered className=\"h-3.5 w-3.5\" />\n </button>\n\n {showDueDate && (\n <>\n {toolbarSeparator}\n {/* Due date */}\n {dueDate ? (\n <div className=\"bg-primary/10 flex items-center gap-1 rounded px-2 py-1\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n {formatDateForDisplay(dueDate)}\n </span>\n <button\n type=\"button\"\n onClick={() => setDueDate(undefined)}\n className=\"text-primary/60 hover:text-primary ml-1\"\n title=\"Remove due date\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={() => dateInputRef.current?.showPicker()}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-7 cursor-pointer items-center gap-1 rounded px-2 text-xs font-medium transition-colors\"\n >\n <Calendar className=\"h-3.5 w-3.5\" />\n <span>Due date</span>\n </button>\n <input\n ref={dateInputRef}\n type=\"date\"\n className=\"invisible absolute h-0 w-0\"\n onChange={(e) => {\n if (e.target.value) {\n // Convert YYYY-MM-DD to ISO datetime at local midnight\n const localDate = new Date(e.target.value + \"T00:00:00\");\n setDueDate(localDate.toISOString());\n }\n }}\n />\n </>\n )}\n </>\n )}\n </div>\n\n {/* Editor area */}\n <EditorContent\n editor={editor}\n className={editorClassName ?? \"min-h-[60vh] flex-1 overflow-y-auto p-4\"}\n />\n\n <style>{`\n .ProseMirror {\n outline: none;\n }\n\n .ProseMirror h1 {\n font-size: 1.5rem;\n font-weight: 600;\n line-height: 1.3;\n margin-bottom: 0.5rem;\n }\n\n .ProseMirror h1.is-empty::before,\n .ProseMirror p.is-empty::before {\n color: var(--color-muted-foreground);\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n }\n\n .ProseMirror ul {\n list-style-type: disc;\n padding-left: 1.5rem;\n margin: 0.5rem 0;\n }\n\n .ProseMirror ol {\n list-style-type: decimal;\n padding-left: 1.5rem;\n margin: 0.5rem 0;\n }\n\n .ProseMirror li {\n margin: 0.25rem 0;\n display: list-item;\n }\n\n .ProseMirror li > p {\n margin: 0;\n }\n `}</style>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useRef, useState } from \"react\";\nimport { Calendar, X } from \"lucide-react\";\nimport {\n Button,\n Input,\n Sheet,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from \"@fluid-app/ui-primitives\";\nimport { NoteTaskEditor } from \"./note-task-editor\";\nimport { formatDateForDisplay } from \"../../utils/format-date\";\n\nexport interface NoteTaskModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n mode: \"create\" | \"edit\";\n type: \"note\" | \"task\";\n initialTitle?: string;\n initialBody?: string;\n initialDueDate?: string;\n showDueDate?: boolean;\n onSave: (data: { title: string; body: string; dueDate?: string }) => void;\n isPending?: boolean;\n isCompleted?: boolean;\n onToggleComplete?: () => void;\n isTogglePending?: boolean;\n}\n\nexport function NoteTaskModal({\n open,\n onOpenChange,\n mode,\n type,\n initialTitle = \"\",\n initialBody = \"\",\n initialDueDate,\n showDueDate = false,\n onSave,\n isPending = false,\n isCompleted,\n onToggleComplete,\n isTogglePending = false,\n}: NoteTaskModalProps): React.JSX.Element {\n const [title, setTitle] = useState(initialTitle);\n const [body, setBody] = useState(initialBody);\n const dateInputRef = useRef<HTMLInputElement>(null);\n const [dueDate, setDueDate] = useState<string | undefined>(initialDueDate);\n\n const typeLabel = type === \"note\" ? \"Note\" : \"Task\";\n const sheetTitle = mode === \"edit\" ? `Edit ${typeLabel}` : `New ${typeLabel}`;\n\n const requiresBody = type === \"note\";\n const canSave =\n !!title.trim() && (!requiresBody || !!body.trim()) && !isPending;\n\n const handleSave = () => {\n if (!canSave) return;\n onSave({\n title: title.trim(),\n body,\n dueDate,\n });\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent className=\"flex w-full flex-col sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{sheetTitle}</SheetTitle>\n </SheetHeader>\n\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n <Input\n placeholder={`${typeLabel} title`}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n autoFocus\n />\n\n <NoteTaskEditor\n showTitle={false}\n bodyPlaceholder=\"Start writing...\"\n initialBody={initialBody}\n editorClassName=\"min-h-[200px] flex-1 overflow-y-auto p-4\"\n onChange={(content) => {\n setBody(content.body);\n }}\n />\n\n {showDueDate && (\n <div className=\"flex items-center gap-2\">\n {dueDate ? (\n <div className=\"bg-primary/10 inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-sm font-medium\">\n Due {formatDateForDisplay(dueDate)}\n </span>\n <button\n type=\"button\"\n onClick={() => setDueDate(undefined)}\n className=\"text-primary/60 hover:text-primary ml-1\"\n title=\"Remove due date\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => dateInputRef.current?.showPicker()}\n className=\"text-muted-foreground hover:text-foreground hover:bg-muted inline-flex cursor-pointer items-center gap-1.5 rounded-md px-2.5 py-1.5 text-sm font-medium transition-colors\"\n >\n <Calendar className=\"h-3.5 w-3.5\" />\n <span>Add due date</span>\n </button>\n <input\n ref={dateInputRef}\n type=\"date\"\n className=\"invisible absolute h-0 w-0\"\n onChange={(e) => {\n if (e.target.value) {\n const localDate = new Date(\n e.target.value + \"T00:00:00\",\n );\n setDueDate(localDate.toISOString());\n }\n }}\n />\n </div>\n )}\n </div>\n )}\n </div>\n\n <SheetFooter className=\"flex-row justify-end gap-2 border-t pt-4\">\n {mode === \"edit\" && onToggleComplete && (\n <Button\n variant=\"outline\"\n onClick={onToggleComplete}\n disabled={isTogglePending}\n className=\"mr-auto\"\n >\n {isCompleted ? \"Mark Incomplete\" : \"Mark Complete\"}\n </Button>\n )}\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!canSave}>\n {isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n );\n}\n","\"use client\";\n\nimport React, { useImperativeHandle, useState } from \"react\";\nimport {\n Calendar,\n Plus,\n ClipboardList,\n SquareCheckBig,\n CircleCheck,\n EllipsisVertical,\n} from \"lucide-react\";\nimport {\n cn,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport type { ContactTask } from \"../../hooks/contacts/use-contact-tasks\";\nimport { useToggleTaskCompletion } from \"../../hooks/contacts/use-toggle-task-completion\";\nimport { useDeleteContactTask } from \"../../hooks/contacts/use-delete-contact-task\";\nimport { useCreateContactTask } from \"../../hooks/contacts/use-create-contact-task\";\nimport { useUpdateContactTask } from \"../../hooks/contacts/use-update-contact-task\";\nimport { NoteTaskModal } from \"../editor/note-task-modal\";\n\n// ---------------------------------------------------------------------------\n// Date helpers\n// ---------------------------------------------------------------------------\n\nfunction formatDueDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\nfunction formatRelativeTime(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n } else if (diffDays === 1) {\n return \"Yesterday\";\n } else {\n return `${diffDays} days ago`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Empty state\n// ---------------------------------------------------------------------------\n\nfunction EmptyState({ onCreateTask }: { onCreateTask: () => void }) {\n return (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center\">\n <div className=\"relative mb-6\">\n <div className=\"flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-teal-100 to-emerald-100\">\n <ClipboardList className=\"h-9 w-9 text-teal-500\" />\n </div>\n <div className=\"border-background absolute -right-2 -bottom-1 flex h-9 w-9 items-center justify-center rounded-full border-2 bg-gradient-to-br from-blue-100 to-indigo-100 shadow-sm\">\n <SquareCheckBig className=\"h-4 w-4 text-blue-500\" />\n </div>\n </div>\n <h4 className=\"text-foreground text-base font-semibold\">No tasks yet</h4>\n <p className=\"text-muted-foreground mt-1.5 max-w-[260px] text-sm leading-relaxed\">\n Stay organized by creating tasks to track follow-ups for this contact\n </p>\n <button\n type=\"button\"\n onClick={onCreateTask}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 mt-4 inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n New Task\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Task card\n// ---------------------------------------------------------------------------\n\ninterface TaskCardProps {\n task: ContactTask;\n toggleCompletion: ReturnType<typeof useToggleTaskCompletion>;\n onEdit: (task: ContactTask) => void;\n onDeleteClick: (task: ContactTask) => void;\n}\n\nfunction TaskCard({\n task,\n toggleCompletion,\n onEdit,\n onDeleteClick,\n}: TaskCardProps) {\n const isCompleted = !!task.completed_at;\n\n const { title, body: bodyText } = parseTaskBody(task.body ?? \"\");\n\n const timestamp = task.created_at ? formatRelativeTime(task.created_at) : \"\";\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onEdit(task)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onEdit(task);\n }\n }}\n className=\"border-border bg-card min-w-[250px] cursor-pointer rounded-xl border p-4 transition-colors\"\n >\n <div className=\"flex items-start gap-3\">\n {/* Checkbox */}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n toggleCompletion.mutate({\n taskId: task.id,\n isCompleted: isCompleted,\n });\n }}\n disabled={toggleCompletion.isPending}\n className=\"mt-0.5 shrink-0 transition-opacity hover:opacity-70 disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={isCompleted ? \"Mark as open\" : \"Mark as completed\"}\n >\n {isCompleted ? (\n <CircleCheck className=\"text-primary h-5 w-5\" />\n ) : (\n <div className=\"border-muted-foreground h-5 w-5 rounded-full border-2\" />\n )}\n </button>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n {/* Title & menu row */}\n <div className=\"flex items-start justify-between gap-2\">\n <h4\n className={cn(\n \"text-foreground line-clamp-2 font-semibold\",\n isCompleted && \"text-muted-foreground line-through\",\n )}\n >\n {title}\n </h4>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(e) => e.stopPropagation()}\n >\n <EllipsisVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(e) => {\n e.stopPropagation();\n onDeleteClick(task);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Body text */}\n {bodyText && (\n <p\n className=\"text-muted-foreground mt-1 line-clamp-3 text-sm\"\n style={\n isCompleted ? { textDecoration: \"line-through\" } : undefined\n }\n >\n {bodyText}\n </p>\n )}\n\n {/* Due date & Timestamp */}\n <div className=\"mt-2 flex flex-row items-center gap-2\">\n <span className=\"text-muted-foreground text-xs\">{timestamp}</span>\n {task.due_at && (\n <div className=\"flex items-center gap-1\">\n <Calendar\n className={cn(\n \"h-3.5 w-3.5\",\n isCompleted ? \"text-muted-foreground\" : \"text-primary\",\n )}\n />\n <span\n className={cn(\n \"text-xs font-medium\",\n isCompleted ? \"text-muted-foreground\" : \"text-primary\",\n )}\n >\n Due {formatDueDate(task.due_at)}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport interface TaskListProps {\n tasks: ContactTask[];\n isLoading?: boolean;\n contactId: string;\n /** Hide the built-in \"Tasks (N) / Add Task\" header — used when the consumer\n * renders its own create-task affordance above the list. */\n hideHeader?: boolean;\n /** Ref that receives the openCreateModal callback for external triggering */\n ref?: React.Ref<(() => void) | null>;\n}\n\nexport function TaskList({\n tasks,\n isLoading,\n contactId,\n hideHeader = false,\n ref,\n}: TaskListProps): React.JSX.Element {\n const [taskToDelete, setTaskToDelete] = useState<ContactTask | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [editingTask, setEditingTask] = useState<ContactTask | null>(null);\n\n const toggleCompletion = useToggleTaskCompletion(contactId);\n const deleteTask = useDeleteContactTask(contactId, {\n onSuccess: () => setTaskToDelete(null),\n });\n const createTask = useCreateContactTask(contactId, {\n onSuccess: () => setModalOpen(false),\n });\n const updateTask = useUpdateContactTask(contactId, {\n onSuccess: () => setEditingTask(null),\n });\n\n const openCreateModal = () => {\n setEditingTask(null);\n setModalOpen(true);\n };\n\n // Expose openCreateModal to parent via ref\n useImperativeHandle(ref, () => openCreateModal);\n\n const handleSave = (data: {\n title: string;\n body: string;\n dueDate?: string;\n }) => {\n const taskBody = data.body ? `${data.title}\\n\\n${data.body}` : data.title;\n\n if (editingTask) {\n updateTask.mutate({\n taskId: editingTask.id,\n input: { body: taskBody, due_at: data.dueDate ?? null },\n });\n } else {\n createTask.mutate({ body: taskBody, due_at: data.dueDate ?? null });\n }\n };\n\n const editingParsed = editingTask\n ? parseTaskBody(editingTask.body ?? \"\")\n : null;\n\n const isModalOpen = modalOpen || editingTask !== null;\n const handleModalOpenChange = (open: boolean) => {\n if (!open) {\n setModalOpen(false);\n setEditingTask(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4\">\n {!hideHeader && (\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"bg-muted h-5 w-24 animate-pulse rounded\" />\n <div className=\"bg-muted mt-1 h-4 w-48 animate-pulse rounded\" />\n </div>\n <div className=\"bg-muted h-8 w-24 animate-pulse rounded-lg\" />\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"border-border bg-muted/50 h-32 animate-pulse rounded-xl border\"\n />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {!hideHeader && (\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-foreground text-base font-semibold\">\n Tasks ({tasks.length})\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-sm\">\n Manage tasks and follow-ups for this contact\n </p>\n </div>\n <button\n type=\"button\"\n onClick={openCreateModal}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add Task\n </button>\n </div>\n )}\n\n {/* Content */}\n {tasks.length === 0 ? (\n <EmptyState onCreateTask={openCreateModal} />\n ) : (\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {tasks.map((task) => (\n <TaskCard\n key={task.id}\n task={task}\n toggleCompletion={toggleCompletion}\n onEdit={setEditingTask}\n onDeleteClick={setTaskToDelete}\n />\n ))}\n </div>\n )}\n\n {/* Create/Edit modal */}\n <NoteTaskModal\n key={editingTask?.id ?? \"create\"}\n open={isModalOpen}\n onOpenChange={handleModalOpenChange}\n mode={editingTask ? \"edit\" : \"create\"}\n type=\"task\"\n initialTitle={editingParsed?.title ?? \"\"}\n initialBody={editingParsed?.body ?? \"\"}\n initialDueDate={editingTask?.due_at ?? undefined}\n showDueDate\n onSave={handleSave}\n isPending={createTask.isPending || updateTask.isPending}\n isCompleted={editingTask ? !!editingTask.completed_at : undefined}\n onToggleComplete={\n editingTask\n ? () =>\n toggleCompletion.mutate(\n {\n taskId: editingTask.id,\n isCompleted: !!editingTask.completed_at,\n },\n { onSuccess: () => setEditingTask(null) },\n )\n : undefined\n }\n isTogglePending={toggleCompletion.isPending}\n />\n\n {/* Delete confirmation modal */}\n <AlertDialog\n open={taskToDelete !== null}\n onOpenChange={(open) => {\n if (!open) setTaskToDelete(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete Task</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete this task? This action cannot be\n undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n if (taskToDelete) {\n deleteTask.mutate(taskToDelete.id);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: (noteId: number) => api.deleteNote(noteId, contactId),\n onSuccess: () => {\n fluidToast({ title: \"Note deleted\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateNoteInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { CreateNoteInput };\n\nexport function useCreateContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: (input: CreateNoteInput) => api.createNote(contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Note created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to create note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { UpdateNoteInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { UpdateNoteInput };\n\nexport function useUpdateContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: ({\n noteId,\n input,\n }: {\n noteId: number;\n input: UpdateNoteInput;\n }) => api.updateNote(noteId, contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Note updated\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport React, { useImperativeHandle, useState } from \"react\";\nimport {\n Calendar,\n Paperclip,\n Plus,\n StickyNote,\n Pen,\n EllipsisVertical,\n} from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport type { ContactNote } from \"../../hooks/notes/use-contact-notes\";\nimport { useDeleteContactNote } from \"../../hooks/notes/use-delete-contact-note\";\nimport { useCreateContactNote } from \"../../hooks/notes/use-create-contact-note\";\nimport { useUpdateContactNote } from \"../../hooks/notes/use-update-contact-note\";\nimport { NoteTaskModal } from \"../editor/note-task-modal\";\n\n// ---------------------------------------------------------------------------\n// Date helpers\n// ---------------------------------------------------------------------------\n\nfunction formatDueDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\n// ---------------------------------------------------------------------------\n// Empty state\n// ---------------------------------------------------------------------------\n\nfunction EmptyState({ onCreateNote }: { onCreateNote: () => void }) {\n return (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center\">\n <div className=\"relative mb-6\">\n <div className=\"flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-amber-100 to-yellow-100\">\n <StickyNote className=\"h-9 w-9 text-amber-500\" />\n </div>\n <div className=\"border-background absolute -right-2 -bottom-1 flex h-9 w-9 items-center justify-center rounded-full border-2 bg-gradient-to-br from-orange-100 to-red-100 shadow-sm\">\n <Pen className=\"h-4 w-4 text-orange-500\" />\n </div>\n </div>\n <h4 className=\"text-foreground text-base font-semibold\">No notes yet</h4>\n <p className=\"text-muted-foreground mt-1.5 max-w-[260px] text-sm leading-relaxed\">\n Capture key details and insights about this contact to stay on top of\n every conversation\n </p>\n <button\n type=\"button\"\n onClick={onCreateNote}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 mt-4 inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n New Note\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Note card\n// ---------------------------------------------------------------------------\n\nfunction NoteCard({\n note,\n onEdit,\n onDelete,\n}: {\n note: ContactNote;\n onEdit: (note: ContactNote) => void;\n onDelete: (note: ContactNote) => void;\n}) {\n const assetCount = note.assets?.length ?? 0;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onEdit(note)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onEdit(note);\n }\n }}\n className=\"border-border bg-card hover:border-border/80 cursor-pointer rounded-xl border p-5 transition-colors\"\n >\n {/* Title row with ellipsis menu */}\n <div className=\"flex items-start justify-between gap-2\">\n <h4 className=\"text-foreground line-clamp-1 text-sm font-semibold\">\n {note.title}\n </h4>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n onClick={(e) => e.stopPropagation()}\n className=\"text-muted-foreground inline-flex h-6 w-6 items-center justify-center rounded-md hover:opacity-70\"\n >\n <EllipsisVertical className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(note);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Body */}\n <p className=\"text-muted-foreground mt-1.5 line-clamp-4 text-sm leading-relaxed\">\n {note.body}\n </p>\n\n {/* Meta row */}\n <div className=\"mt-3 flex flex-wrap items-center gap-4\">\n {note.due_at && (\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n Due {formatDueDate(note.due_at)}\n </span>\n </div>\n )}\n {!note.due_at && note.due_date && (\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n Due {formatDueDate(note.due_date)}\n </span>\n </div>\n )}\n {assetCount > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <Paperclip className=\"text-muted-foreground h-3.5 w-3.5\" />\n <span className=\"text-muted-foreground text-xs\">\n {assetCount} {assetCount === 1 ? \"Attachment\" : \"Attachments\"}\n </span>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport interface NotesListProps {\n notes: ContactNote[];\n isLoading?: boolean;\n contactId: string;\n /** Ref that receives the openCreateModal callback for external triggering */\n ref?: React.Ref<(() => void) | null>;\n}\n\nexport function NotesList({\n notes,\n isLoading,\n contactId,\n ref,\n}: NotesListProps): React.JSX.Element {\n const [noteToDelete, setNoteToDelete] = useState<ContactNote | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [editingNote, setEditingNote] = useState<ContactNote | null>(null);\n\n const deleteNote = useDeleteContactNote(contactId);\n const createNote = useCreateContactNote(contactId, {\n onSuccess: () => setModalOpen(false),\n });\n const updateNote = useUpdateContactNote(contactId, {\n onSuccess: () => setEditingNote(null),\n });\n\n const openCreateModal = () => {\n setEditingNote(null);\n setModalOpen(true);\n };\n\n // Expose openCreateModal to parent via ref\n useImperativeHandle(ref, () => openCreateModal);\n\n const handleSave = (data: {\n title: string;\n body: string;\n dueDate?: string;\n }) => {\n if (editingNote) {\n updateNote.mutate({\n noteId: editingNote.id,\n input: { title: data.title, body: data.body },\n });\n } else {\n createNote.mutate({ title: data.title, body: data.body });\n }\n };\n\n const isModalOpen = modalOpen || editingNote !== null;\n const handleModalOpenChange = (open: boolean) => {\n if (!open) {\n setModalOpen(false);\n setEditingNote(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"bg-muted h-5 w-24 animate-pulse rounded\" />\n <div className=\"bg-muted mt-1 h-4 w-48 animate-pulse rounded\" />\n </div>\n <div className=\"bg-muted h-8 w-24 animate-pulse rounded-lg\" />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"border-border bg-muted/50 h-40 animate-pulse rounded-xl border\"\n />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Header */}\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-foreground text-base font-semibold\">\n Notes ({notes.length})\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-sm\">\n Capture key details and insights about this contact\n </p>\n </div>\n <button\n type=\"button\"\n onClick={openCreateModal}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add Note\n </button>\n </div>\n\n {/* Content */}\n {notes.length === 0 ? (\n <EmptyState onCreateNote={openCreateModal} />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {notes.map((note) => (\n <NoteCard\n key={note.id}\n note={note}\n onEdit={setEditingNote}\n onDelete={setNoteToDelete}\n />\n ))}\n </div>\n )}\n\n {/* Create/Edit modal */}\n <NoteTaskModal\n key={editingNote?.id ?? \"create\"}\n open={isModalOpen}\n onOpenChange={handleModalOpenChange}\n mode={editingNote ? \"edit\" : \"create\"}\n type=\"note\"\n initialTitle={editingNote?.title ?? \"\"}\n initialBody={editingNote?.body ?? \"\"}\n onSave={handleSave}\n isPending={createNote.isPending || updateNote.isPending}\n />\n\n {/* Delete confirmation modal */}\n <AlertDialog\n open={!!noteToDelete}\n onOpenChange={(open) => {\n if (!open) setNoteToDelete(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete Note</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete &quot;{noteToDelete?.title}&quot;?\n This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n if (noteToDelete) {\n deleteNote.mutate(noteToDelete.id);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useMemo } from \"react\";\nimport { useFormContext, useWatch } from \"react-hook-form\";\nimport {\n cn,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@fluid-app/ui-primitives\";\n\nconst DEFAULT_COUNTRIES: { name: string; value: string }[] = [];\n\nconst statusOptions = [\n { name: \"New\", value: \"new\" },\n { name: \"Active\", value: \"active\" },\n { name: \"Inactive\", value: \"inactive\" },\n { name: \"Cold\", value: \"cold\" },\n { name: \"Lead\", value: \"lead\" },\n { name: \"Customer\", value: \"customer\" },\n];\n\ntype AvatarPickerRenderProps = {\n value: string | null;\n onChange: (url: string | null) => void;\n};\n\ntype ContactDetailsFormProps = {\n className?: string;\n countries?: { name: string; value: string }[];\n renderAvatarPicker?: (props: AvatarPickerRenderProps) => React.ReactNode;\n};\n\nexport const ContactDetailsForm: React.FC<ContactDetailsFormProps> = ({\n className,\n countries = DEFAULT_COUNTRIES,\n renderAvatarPicker,\n}) => {\n const { control, watch, setValue } = useFormContext();\n const currentStatus = useWatch({ control, name: \"status\" });\n const avatarUrl: string | null =\n (watch(\"avatar_url\") as string | null | undefined) ?? null;\n\n const effectiveStatusOptions = useMemo(() => {\n if (\n currentStatus &&\n typeof currentStatus === \"string\" &&\n !statusOptions.some((o) => o.value === currentStatus)\n ) {\n return [\n {\n name:\n currentStatus.charAt(0).toUpperCase() +\n currentStatus.slice(1).replace(/_/g, \" \"),\n value: currentStatus,\n },\n ...statusOptions,\n ];\n }\n return statusOptions;\n }, [currentStatus]);\n\n const firstInitial =\n (watch(\"first_name\") as string | null | undefined)?.[0] ?? \"\";\n const lastInitial =\n (watch(\"last_name\") as string | null | undefined)?.[0] ?? \"\";\n const initials =\n [firstInitial, lastInitial].filter(Boolean).join(\"\").toUpperCase() || \"?\";\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {renderAvatarPicker && (\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"border-border bg-background relative h-20 w-20 shrink-0 overflow-hidden rounded-full border-2\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center text-lg font-semibold\">\n {initials}\n </div>\n )}\n </div>\n {renderAvatarPicker({\n value: avatarUrl,\n onChange: (url) =>\n setValue(\"avatar_url\", url ?? \"\", { shouldDirty: true }),\n })}\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <FormField\n control={control}\n name=\"first_name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n First Name\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter first name\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"last_name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Last Name\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter last name\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"email\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Email\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter email address\"\n type=\"email\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"phone\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Phone\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter phone number\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"status\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Status\n </FormLabel>\n <Select value={field.value ?? \"\"} onValueChange={field.onChange}>\n <FormControl>\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select status\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent position=\"popper\" sideOffset={4}>\n {effectiveStatusOptions.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"address\"\n render={({ field }) => (\n <FormItem className=\"lg:col-span-2\">\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Full Address\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter street address\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"city\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n City\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter city\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"state\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n State/Province\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter state or province\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"postal_code\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Postal Code\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter postal code\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"country_code\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Country\n </FormLabel>\n <Select value={field.value ?? \"\"} onValueChange={field.onChange}>\n <FormControl>\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select country\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent position=\"popper\" sideOffset={4}>\n {countries.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />\n </div>\n </div>\n );\n};\n","\"use client\";\n\nimport React, { useRef, useState } from \"react\";\nimport { ArrowLeft, Plus } from \"lucide-react\";\nimport {\n Button,\n Card,\n CardContent,\n cn,\n Spinner,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { TaskList } from \"../../tasks/task-list\";\nimport { NotesList } from \"../../notes/notes-list\";\nimport { ContactDetailsForm } from \"../../../../shared/components/contacts/contactDetailsForm\";\nimport type { ContactTask } from \"../../../hooks/contacts/use-contact-tasks\";\nimport type { ContactNote } from \"../../../hooks/notes/use-contact-notes\";\n\nconst VISIBLE_TABS = [\"Tasks\", \"Notes\", \"Profile\"] as const;\ntype TabType = (typeof VISIBLE_TABS)[number];\n\nconst NON_PROFILE_TABS = VISIBLE_TABS.filter(\n (t): t is Exclude<TabType, \"Profile\"> => t !== \"Profile\",\n);\n\nexport interface ContactDetailTabsProps {\n contactId: string;\n contactName: string;\n countryOptions: { name: string; value: string }[];\n isDirty: boolean;\n isSubmitting: boolean;\n onSave: () => void;\n tasks: ContactTask[];\n isLoadingTasks: boolean;\n notes: ContactNote[];\n isLoadingNotes: boolean;\n}\n\nexport function ContactDetailTabs({\n contactId,\n contactName,\n countryOptions,\n isDirty,\n isSubmitting,\n onSave,\n tasks,\n isLoadingTasks,\n notes,\n isLoadingNotes,\n}: ContactDetailTabsProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [activeTab, setActiveTab] = useState<TabType>(\"Tasks\");\n\n const tabLabels: Record<TabType, string> = {\n Tasks: t(\"tab_tasks\"),\n Notes: t(\"tab_notes\"),\n Profile: t(\"edit_profile\"),\n };\n\n const openTaskModalRef = useRef<(() => void) | null>(null);\n\n const isEditingProfile = activeTab === \"Profile\";\n\n return (\n <div className=\"mt-8\">\n {isEditingProfile ? (\n <div className=\"border-border flex flex-col gap-3 border-b sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:gap-x-4 sm:gap-y-2\">\n <div className=\"flex min-w-0 items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"Tasks\")}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground hidden size-9 shrink-0 items-center justify-center rounded-md transition-colors sm:flex\"\n aria-label={t(\"back_to_tasks\")}\n >\n <ArrowLeft className=\"size-4\" />\n </button>\n <span className=\"border-foreground text-foreground -mb-px border-b-2 py-3 text-sm font-medium\">\n {t(\"editing_name\", { name: contactName })}\n </span>\n </div>\n <div className=\"flex w-full flex-col gap-2 sm:w-auto sm:shrink-0 sm:flex-row sm:items-center sm:gap-3\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => setActiveTab(\"Tasks\")}\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {t(\"cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={onSave}\n disabled={!isDirty || isSubmitting}\n aria-busy={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting && <Spinner className=\"size-4\" />}\n {isSubmitting ? t(\"saving\") : t(\"update_contact\")}\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"border-border flex items-center gap-1 border-b\">\n {NON_PROFILE_TABS.map((tab) => {\n const count = tab === \"Tasks\" ? tasks.length : notes.length;\n const isActive = activeTab === tab;\n return (\n <button\n key={tab}\n type=\"button\"\n onClick={() => setActiveTab(tab)}\n className={cn(\n \"relative flex items-center gap-1.5 px-3 py-2.5 text-sm font-semibold transition-colors\",\n isActive\n ? \"text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n {tabLabels[tab]}\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs leading-5 font-bold\",\n isActive\n ? \"bg-foreground text-background\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n {isActive && (\n <span\n className=\"bg-foreground absolute inset-x-0 -bottom-px h-0.5\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"Profile\")}\n className=\"text-muted-foreground hover:text-foreground ml-auto px-3 py-2.5 text-sm font-semibold transition-colors\"\n >\n {t(\"edit_profile\")}\n </button>\n </div>\n )}\n\n <div className=\"pt-6\">\n {activeTab === \"Tasks\" && (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => openTaskModalRef.current?.()}\n className=\"border-border text-muted-foreground hover:border-foreground/30 hover:bg-muted/40 hover:text-foreground flex w-full items-center gap-3 rounded-xl border border-dashed px-5 py-4 text-sm font-medium transition-colors\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {t(\"new_task\")}\n </button>\n <TaskList\n tasks={tasks}\n isLoading={isLoadingTasks}\n contactId={contactId}\n hideHeader\n ref={openTaskModalRef}\n />\n </div>\n )}\n\n {activeTab === \"Notes\" && (\n <NotesList\n notes={notes}\n isLoading={isLoadingNotes}\n contactId={contactId}\n />\n )}\n\n {activeTab === \"Profile\" && (\n <Card>\n <CardContent>\n <p className=\"text-muted-foreground mb-6 text-sm\">\n {t(\"profile_edit_description\")}\n </p>\n <ContactDetailsForm countries={countryOptions} />\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useCallback, useState } from \"react\";\nimport { FormProvider } from \"react-hook-form\";\nimport { ChevronLeft, Mail, MoreHorizontal, Phone, Trash2 } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { useContactDetailPage } from \"../../../../shared/hooks/useContactDetailPage\";\nimport { useContactTasks } from \"../../../hooks/contacts/use-contact-tasks\";\nimport { useContactNotes } from \"../../../hooks/notes/use-contact-notes\";\nimport { ContactDetailHero } from \"./ContactDetailHero\";\nimport { ContactInfoRow } from \"./ContactInfoRow\";\nimport { ContactDetailTabs } from \"./ContactDetailTabs\";\nimport { getDisplayName } from \"./utils\";\n\nexport interface ContactDetailPaneProps {\n contactId: string;\n queryKeyPrefix: string;\n getCountries: () => Promise<{ id: number; name: string; iso?: string }[]>;\n /** Callback to clear selection (used by mobile back button + on delete). */\n onBack: () => void;\n}\n\nexport function ContactDetailPane({\n contactId,\n queryKeyPrefix,\n getCountries,\n onBack,\n}: ContactDetailPaneProps): React.JSX.Element {\n const {\n contact,\n isLoading,\n methods,\n countryOptions,\n isDirty,\n isSubmitting,\n isDeleting,\n onSave,\n onDelete,\n } = useContactDetailPage(contactId, {\n queryKeyPrefix,\n getCountries,\n onDeleteSuccess: onBack,\n });\n\n const { data: tasks = [], isLoading: isLoadingTasks } =\n useContactTasks(contactId);\n const { data: notes = [], isLoading: isLoadingNotes } =\n useContactNotes(contactId);\n\n const { t } = useContactsTranslation();\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n // Close the dialog before dispatching: on success the pane unmounts via\n // onDeleteSuccess; on a non-throwing failure the dialog would otherwise\n // dangle open with the toast already shown.\n const handleConfirmDelete = useCallback(() => {\n setConfirmDelete(false);\n onDelete();\n }, [onDelete]);\n\n if (isLoading) {\n return <ContactDetailSkeleton onBack={onBack} />;\n }\n\n if (!contact) {\n return (\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar\n onBack={onBack}\n phone={null}\n email={null}\n onDelete={null}\n />\n <div className=\"mx-auto flex max-w-md flex-col items-center px-6 py-16 text-center\">\n <h2 className=\"text-foreground text-base font-semibold\">\n {t(\"error_loading\")}\n </h2>\n <p className=\"text-muted-foreground mt-2 text-sm\">\n {t(\"error_loading_description\")}\n </p>\n </div>\n </div>\n );\n }\n\n const fullName = getDisplayName(contact);\n\n return (\n <FormProvider {...methods}>\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar\n onBack={onBack}\n phone={contact.phone ?? null}\n email={contact.email ?? null}\n onDelete={() => setConfirmDelete(true)}\n />\n\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto w-full max-w-[900px] px-6 pt-8 pb-16 md:px-8 md:pt-10\">\n <ContactDetailHero\n contact={contact}\n tasksCount={tasks.length}\n notesCount={notes.length}\n />\n <ContactInfoRow contact={contact} />\n <ContactDetailTabs\n contactId={contactId}\n contactName={fullName}\n countryOptions={countryOptions}\n isDirty={isDirty}\n isSubmitting={isSubmitting}\n onSave={onSave}\n tasks={tasks}\n isLoadingTasks={isLoadingTasks}\n notes={notes}\n isLoadingNotes={isLoadingNotes}\n />\n </div>\n </div>\n\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t(\"delete_name\", { name: fullName })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\"delete_confirm_permanent\")}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isDeleting}>\n {t(\"cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={handleConfirmDelete}\n disabled={isDeleting}\n >\n {isDeleting ? t(\"deleting\") : t(\"delete_contact\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </FormProvider>\n );\n}\n\ninterface DetailTopBarProps {\n onBack: () => void;\n phone: string | null;\n email: string | null;\n onDelete: (() => void) | null;\n}\n\nfunction DetailTopBar({ onBack, phone, email, onDelete }: DetailTopBarProps) {\n const { t } = useContactsTranslation();\n return (\n <div className=\"border-border bg-background/90 sticky top-0 z-10 flex items-center justify-between border-b px-4 py-3 backdrop-blur md:px-8\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onBack}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex size-8 items-center justify-center rounded-full transition-colors md:hidden\"\n aria-label={t(\"back_to_contacts\")}\n >\n <ChevronLeft className=\"size-4\" />\n </button>\n <span className=\"text-muted-foreground hidden text-xs font-semibold tracking-widest uppercase md:inline\">\n {t(\"contact_label\")}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <ActionLink\n href={phone ? `tel:${phone}` : null}\n label={t(\"label_call\")}\n icon={<Phone className=\"size-4\" aria-hidden=\"true\" />}\n />\n <ActionLink\n href={email ? `mailto:${email}` : null}\n label={t(\"label_email\")}\n icon={<Mail className=\"size-4\" aria-hidden=\"true\" />}\n />\n {onDelete && (\n <>\n <div className=\"bg-border mx-1 h-5 w-px\" aria-hidden=\"true\" />\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex size-8 items-center justify-center rounded-full transition-colors\"\n aria-label={t(\"more_actions\")}\n >\n <MoreHorizontal className=\"size-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={onDelete}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {t(\"delete_contact\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n )}\n </div>\n </div>\n );\n}\n\ninterface ActionLinkProps {\n href: string | null;\n label: string;\n icon: React.ReactNode;\n}\n\nfunction ActionLink({ href, label, icon }: ActionLinkProps) {\n const baseClass =\n \"flex size-8 items-center justify-center rounded-full transition-colors\";\n if (!href) {\n return (\n <span\n aria-label={`${label} (unavailable)`}\n className={cn(baseClass, \"text-muted-foreground/40 cursor-default\")}\n >\n {icon}\n </span>\n );\n }\n return (\n <a\n href={href}\n aria-label={label}\n className={cn(\n baseClass,\n \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n )}\n >\n {icon}\n </a>\n );\n}\n\nfunction ContactDetailSkeleton({ onBack }: { onBack: () => void }) {\n return (\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar onBack={onBack} phone={null} email={null} onDelete={null} />\n <div className=\"mx-auto w-full max-w-[900px] flex-1 space-y-6 px-6 pt-8 pb-16 md:px-8 md:pt-10\">\n <div className=\"flex items-start gap-5\">\n <div className=\"bg-muted size-20 animate-pulse rounded-xl\" />\n <div className=\"flex-1 space-y-3\">\n <div className=\"bg-muted h-7 w-48 animate-pulse rounded\" />\n <div className=\"bg-muted h-4 w-24 animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"bg-muted h-24 animate-pulse rounded-xl\" />\n <div className=\"bg-muted h-64 animate-pulse rounded-xl\" />\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { Users } from \"lucide-react\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport function ContactsEmptyState(): React.JSX.Element {\n const { t } = useContactsTranslation();\n return (\n <div className=\"hidden h-full flex-1 flex-col items-center justify-center px-8 text-center md:flex\">\n <div className=\"bg-muted text-muted-foreground flex size-16 items-center justify-center rounded-xl\">\n <Users className=\"size-7\" aria-hidden=\"true\" />\n </div>\n <h2 className=\"text-foreground mt-5 text-base font-semibold\">\n {t(\"empty_select_contact\")}\n </h2>\n <p className=\"text-muted-foreground mt-1 max-w-xs text-sm\">\n {t(\"empty_select_description\")}\n </p>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport { ContactsSidebar } from \"./ContactsSidebar\";\nimport { ContactDetailPane } from \"./ContactDetailPane\";\nimport { ContactsEmptyState } from \"./ContactsEmptyState\";\n\nexport interface RepContactsLayoutProps {\n selectedContactId: string | null;\n onSelect: (id: string | null) => void;\n onAdd: () => void;\n queryKeyPrefix: string;\n getCountries: () => Promise<{ id: number; name: string; iso?: string }[]>;\n}\n\nexport function RepContactsLayout({\n selectedContactId,\n onSelect,\n onAdd,\n queryKeyPrefix,\n getCountries,\n}: RepContactsLayoutProps): React.JSX.Element {\n return (\n <div className=\"bg-background flex h-full overflow-hidden\">\n <aside\n className={cn(\n \"border-border bg-background w-full shrink-0 overflow-hidden border-r md:flex md:w-[420px] md:flex-col\",\n selectedContactId ? \"hidden\" : \"flex flex-col\",\n )}\n >\n <ContactsSidebar\n selectedContactId={selectedContactId}\n onSelect={onSelect}\n onAdd={onAdd}\n />\n </aside>\n\n <main\n className={cn(\n \"bg-background relative flex-1 md:flex md:flex-col\",\n selectedContactId ? \"flex flex-col\" : \"hidden md:flex\",\n )}\n >\n {selectedContactId ? (\n <ContactDetailPane\n key={selectedContactId}\n contactId={selectedContactId}\n queryKeyPrefix={queryKeyPrefix}\n getCountries={getCountries}\n onBack={() => onSelect(null)}\n />\n ) : (\n <ContactsEmptyState />\n )}\n </main>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateContactFormData } from \"../schemas/contactFormSchema\";\n\nexport function useCreateContactMutation(\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: (data: { contact: { id: number } }) => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: (data: CreateContactFormData) =>\n api.createContact(data as unknown as Record<string, unknown>),\n onSuccess: (data) => {\n fluidToast({ title: \"Contact created successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.(data as unknown as { contact: { id: number } });\n },\n onError: (error) => {\n if (options?.onError) {\n options.onError(error);\n } else {\n fluidToast({\n title: \"Failed to create contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n }\n },\n });\n}\n","/**\n * Generated API client functions for portal_tenant_contacts\n *\n * DO NOT EDIT THIS FILE DIRECTLY\n * This file is auto-generated. To update:\n * 1. Update the OpenAPI spec file\n * 2. Run: pnpm generate\n */\n\nimport type { FetchClient } from \"../lib/fetch-client\";\nimport type { operations } from \"../generated/portal-tenant-contacts\";\n\n// ============================================================================\n// contacts\n// ============================================================================\n\n/**\n * List contacts with cursor pagination\n * Returns a paginated list of contacts belonging to the authenticated member.\n *\n * @param client - Fetch client instance\n * @param [params] - params\n */\nexport async function contacts_list(\n client: FetchClient,\n params?: operations[\"contacts_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts`, params);\n}\n\n/**\n * Create a new contact\n * Creates a new contact for the authenticated member.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_create(\n client: FetchClient,\n body: operations[\"contacts_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts`, body);\n}\n\n/**\n * Get a specific contact\n * Returns a single contact by ID.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_show(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_show\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${id}`);\n}\n\n/**\n * Update a contact\n * Updates an existing contact's attributes.\n *\n * @param client - Fetch client instance\n * @param id - id\n * @param body - body\n */\nexport async function contacts_update(\n client: FetchClient,\n id: string | number,\n body: operations[\"contacts_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${id}`, body);\n}\n\n/**\n * Delete a contact\n * Soft-deletes a contact by ID.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_destroy(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${id}`);\n}\n\n/**\n * Delete multiple contacts\n * Soft-deletes multiple contacts by their IDs.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_bulk_destroy(\n client: FetchClient,\n body: operations[\"contacts_bulk_destroy\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_bulk_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/bulk`, { body });\n}\n\n/**\n * List contact groups\n * Returns a paginated list of contact groups belonging to the authenticated member.\n *\n * @param client - Fetch client instance\n * @param [params] - params\n */\nexport async function contacts_groups_list(\n client: FetchClient,\n params?: operations[\"contacts_groups_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_groups_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/groups`, params);\n}\n\n/**\n * Create a new group\n * Creates a new contact group for the authenticated member.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_groups_create(\n client: FetchClient,\n body: operations[\"contacts_groups_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_groups_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/groups`, body);\n}\n\n/**\n * Update a group\n * Updates an existing contact group.\n *\n * @param client - Fetch client instance\n * @param id - id\n * @param body - body\n */\nexport async function contacts_groups_update(\n client: FetchClient,\n id: string | number,\n body: operations[\"contacts_groups_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_groups_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/groups/${id}`, body);\n}\n\n/**\n * Delete a group\n * Removes a contact group.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_groups_destroy(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_groups_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/groups/${id}`);\n}\n\n/**\n * List notes for a contact\n * Returns notes attached to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param [params] - params\n */\nexport async function contacts_notes_list(\n client: FetchClient,\n contact_id: string | number,\n params?: operations[\"contacts_notes_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_notes_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${contact_id}/notes`, params);\n}\n\n/**\n * Create a note for a contact\n * Adds a new note to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param body - body\n */\nexport async function contacts_notes_create(\n client: FetchClient,\n contact_id: string | number,\n body: operations[\"contacts_notes_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_notes_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/${contact_id}/notes`, body);\n}\n\n/**\n * List tasks for a contact\n * Returns tasks assigned to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param [params] - params\n */\nexport async function contacts_tasks_list(\n client: FetchClient,\n contact_id: string | number,\n params?: operations[\"contacts_tasks_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_tasks_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${contact_id}/tasks`, params);\n}\n\n/**\n * Create a task for a contact\n * Adds a new task to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param body - body\n */\nexport async function contacts_tasks_create(\n client: FetchClient,\n contact_id: string | number,\n body: operations[\"contacts_tasks_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_tasks_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/${contact_id}/tasks`, body);\n}\n\n/**\n * Update a note\n * Updates an existing note on a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n * @param body - body\n */\nexport async function contacts_notes_update(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n body: operations[\"contacts_notes_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_notes_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${contact_id}/notes/${id}`, body);\n}\n\n/**\n * Delete a note\n * Removes a note from a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n */\nexport async function contacts_notes_destroy(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n): Promise<\n operations[\"contacts_notes_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${contact_id}/notes/${id}`);\n}\n\n/**\n * Update a task\n * Updates an existing task on a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n * @param body - body\n */\nexport async function contacts_tasks_update(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n body: operations[\"contacts_tasks_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_tasks_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${contact_id}/tasks/${id}`, body);\n}\n\n/**\n * Delete a task\n * Removes a task from a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n */\nexport async function contacts_tasks_destroy(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n): Promise<\n operations[\"contacts_tasks_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${contact_id}/tasks/${id}`);\n}\n","/**\n * Portal Contacts Adapter — Implements ContactsDomainApi using the\n * portal-tenant Contacts BFF endpoints.\n *\n * The existing contacts-ui hooks and components expect the ContactsApi,\n * NotesApi, and TasksApi interfaces from @fluid-app/contacts-core. This\n * adapter translates between the BFF response shapes and the core types\n * so the UI layer works unchanged.\n *\n * Features not available in the BFF (activities, markRead, orders,\n * subscriptionOrders) are omitted — the optional interface lets the\n * UI layer gracefully disable those capabilities.\n */\n\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport type { ContactsApi } from \"@fluid-app/contacts-core/contacts-api\";\nimport type { NotesApi } from \"@fluid-app/contacts-core/notes-api\";\nimport type { TasksApi } from \"@fluid-app/contacts-core/tasks-api\";\nimport type { GroupsApi } from \"@fluid-app/contacts-core/groups-api\";\nimport type { ContactsDomainApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport type {\n Contact,\n ContactGroup,\n ContactNote,\n ContactTask,\n PaginationMeta,\n} from \"@fluid-app/contacts-core/types\";\nimport { portalTenantContacts } from \"@fluid-app/portal-tenant-contacts-api-client\";\n\n// ---------------------------------------------------------------------------\n// Response mappers — BFF shapes → core shapes\n// ---------------------------------------------------------------------------\n\nconst EMPTY_META: PaginationMeta = {\n total_count: 0,\n total_pages: 0,\n current_page: 1,\n next_cursor: null,\n};\n\nfunction paginationFromBff(\n meta: Record<string, unknown> | undefined,\n itemCount: number,\n currentPage: number,\n pageSize: number,\n): PaginationMeta {\n if (!meta) return EMPTY_META;\n const pagination = meta.pagination as Record<string, unknown> | undefined;\n const nextCursor = (pagination?.next_cursor as string | null) ?? null;\n const hasNext = !!nextCursor;\n\n const realTotal = meta.total_count as number | undefined;\n const totalCount =\n realTotal ??\n (hasNext\n ? (currentPage + 1) * pageSize\n : (currentPage - 1) * pageSize + itemCount);\n\n return {\n total_count: totalCount,\n total_pages: Math.max(1, Math.ceil(totalCount / pageSize)),\n current_page: currentPage,\n next_cursor: nextCursor,\n request_id: (meta.request_id as string) ?? undefined,\n timestamp: (meta.timestamp as string) ?? undefined,\n };\n}\n\n/** BFF Contact → core Contact. Fills missing fields with safe defaults. */\nfunction mapContact(raw: Record<string, unknown>): Contact {\n return {\n id: raw.id as number,\n full_name: `${raw.first_name ?? \"\"} ${raw.last_name ?? \"\"}`.trim(),\n first_name: (raw.first_name as string) ?? null,\n last_name: (raw.last_name as string) ?? null,\n email: (raw.email as string) ?? null,\n phone: (raw.phone as string) ?? null,\n status: (raw.status as string) ?? null,\n address: (raw.address as string) ?? null,\n city: (raw.city as string) ?? null,\n state: (raw.state as string) ?? null,\n postal_code: (raw.postal_code as string) ?? null,\n avatar_url: (raw.avatar_url as string) ?? null,\n country: (raw.country as Contact[\"country\"]) ?? null,\n tags: (raw.tags as string[]) ?? [],\n metadata: {},\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n } as Contact;\n}\n\n/** BFF Note → core ContactNote. */\nfunction mapNote(raw: Record<string, unknown>): ContactNote {\n return {\n id: raw.id as number,\n title: (raw.title as string) ?? \"\",\n body: (raw.body as string) ?? \"\",\n note_type: null,\n due_date: null,\n due_time: null,\n pinned: null,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n contact_id: (raw.contact_id as number) ?? 0,\n assets: [],\n };\n}\n\n/** BFF Task → core ContactTask. */\nfunction mapTask(raw: Record<string, unknown>): ContactTask {\n return {\n id: raw.id as number,\n body: (raw.title as string) ?? \"\",\n due_at: (raw.due_date as string) ?? null,\n completed_at:\n (raw.completed_at as string) ??\n (raw.completed ? new Date().toISOString() : null),\n created_at: raw.created_at as string,\n contact_id: (raw.contact_id as number) ?? null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Param mappers — old offset-based params → BFF cursor-based params\n// ---------------------------------------------------------------------------\n\n/**\n * The contacts-ui sends offset pagination params (page, per_page, sort_by,\n * sort_direction, search, status). The BFF expects cursor pagination\n * (page[cursor], page[limit], search, tags). Translate between the two.\n *\n * `cursorCache` maps page numbers → cursor tokens so page-2+ requests can\n * resolve to the correct cursor. The cache is populated from BFF responses.\n */\nfunction mapListParams(\n params: Record<string, unknown> | undefined,\n cursorCache: Map<number, string>,\n): Parameters<typeof portalTenantContacts.contacts_list>[1] {\n if (!params) return undefined;\n\n const mapped: Record<string, unknown> = {};\n\n if (params.per_page || params.limit) {\n mapped[\"page[limit]\"] = params.per_page ?? params.limit;\n }\n\n // Translate offset page number → cursor token\n const page = (params.page as number) ?? 1;\n if (page > 1) {\n const cursor = cursorCache.get(page);\n if (cursor) {\n mapped[\"page[cursor]\"] = cursor;\n }\n }\n\n if (params.search_query || params.search || params.query) {\n mapped.search = params.search_query ?? params.search ?? params.query;\n }\n if (params.tags) {\n mapped.tags = params.tags;\n }\n\n return mapped as Parameters<typeof portalTenantContacts.contacts_list>[1];\n}\n\n// ---------------------------------------------------------------------------\n// Adapter factories\n// ---------------------------------------------------------------------------\n\nfunction createContactsAdapter(client: FetchClient): ContactsApi {\n // Cursor cache: maps page numbers → cursor tokens from BFF responses.\n // Page 1 has no cursor; the BFF response for page N includes\n // next_cursor which becomes the cursor for page N+1.\n const cursorCache = new Map<number, string>();\n\n return {\n getContact: async (id) => {\n const response = await portalTenantContacts.contacts_show(client, id);\n return {\n contact: mapContact(\n (response as Record<string, unknown>).contact as Record<\n string,\n unknown\n >,\n ),\n };\n },\n\n listContacts: async (params) => {\n const raw = params as Record<string, unknown> | undefined;\n const page = (raw?.page as number) ?? 1;\n const pageSize = (raw?.per_page as number) ?? 25;\n\n const response = await portalTenantContacts.contacts_list(\n client,\n mapListParams(raw, cursorCache),\n );\n const body = response as Record<string, unknown>;\n const meta = body.meta as Record<string, unknown> | undefined;\n const pagination = meta?.pagination as\n | Record<string, unknown>\n | undefined;\n\n // Store the next_cursor so the UI can request page + 1\n const nextCursor = pagination?.next_cursor as string | null | undefined;\n if (nextCursor) {\n cursorCache.set(page + 1, nextCursor);\n }\n\n const contacts = ((body.contacts as Record<string, unknown>[]) ?? []).map(\n mapContact,\n );\n return {\n contacts,\n meta: paginationFromBff(meta, contacts.length, page, pageSize),\n };\n },\n\n createContact: async (data) => {\n return portalTenantContacts.contacts_create(client, {\n contact: data,\n } as Parameters<typeof portalTenantContacts.contacts_create>[1]);\n },\n\n updateContact: async (id, data) => {\n return portalTenantContacts.contacts_update(client, id, {\n contact: data,\n } as Parameters<typeof portalTenantContacts.contacts_update>[2]);\n },\n\n deleteContact: async (id) => {\n return portalTenantContacts.contacts_destroy(client, id);\n },\n\n bulkDeleteContacts: async (ids) => {\n return portalTenantContacts.contacts_bulk_destroy(client, { ids });\n },\n\n // listActivities, markRead, listOrders, listSubscriptionOrders are not\n // available through the BFF — omitted so the UI disables these features.\n };\n}\n\nfunction createNotesAdapter(client: FetchClient): NotesApi {\n return {\n listNotes: async (contactId) => {\n const response = await portalTenantContacts.contacts_notes_list(\n client,\n contactId,\n );\n const body = response as Record<string, unknown>;\n return {\n notes: ((body.notes as Record<string, unknown>[]) ?? []).map(mapNote),\n };\n },\n\n createNote: async (contactId, input) => {\n return portalTenantContacts.contacts_notes_create(client, contactId, {\n note: input,\n } as Parameters<typeof portalTenantContacts.contacts_notes_create>[2]);\n },\n\n updateNote: async (noteId, contactId, input) => {\n return portalTenantContacts.contacts_notes_update(\n client,\n contactId,\n noteId,\n {\n note: input,\n } as Parameters<typeof portalTenantContacts.contacts_notes_update>[3],\n );\n },\n\n deleteNote: async (noteId, contactId) => {\n return portalTenantContacts.contacts_notes_destroy(\n client,\n contactId,\n noteId,\n );\n },\n };\n}\n\nfunction createTasksAdapter(client: FetchClient): TasksApi {\n return {\n listTasks: async (contactId) => {\n const response = await portalTenantContacts.contacts_tasks_list(\n client,\n contactId,\n );\n const body = response as Record<string, unknown>;\n return {\n tasks: ((body.tasks as Record<string, unknown>[]) ?? []).map(mapTask),\n };\n },\n\n createTask: async (contactId, input) => {\n return portalTenantContacts.contacts_tasks_create(client, contactId, {\n task: { title: input.body, due_date: input.due_at },\n } as Parameters<typeof portalTenantContacts.contacts_tasks_create>[2]);\n },\n\n updateTask: async (taskId, contactId, input) => {\n return portalTenantContacts.contacts_tasks_update(\n client,\n contactId,\n taskId,\n {\n task: {\n title: input.body ?? undefined,\n completed:\n input.completed_at !== undefined\n ? input.completed_at !== null\n : undefined,\n due_date: input.due_at,\n },\n } as Parameters<typeof portalTenantContacts.contacts_tasks_update>[3],\n );\n },\n\n deleteTask: async (taskId, contactId) => {\n return portalTenantContacts.contacts_tasks_destroy(\n client,\n contactId,\n taskId,\n );\n },\n };\n}\n\n/** BFF Group → core ContactGroup. */\nfunction mapGroup(raw: Record<string, unknown>): ContactGroup {\n return {\n id: raw.id as number,\n name: (raw.name as string) ?? \"\",\n avatar: (raw.avatar as string) ?? null,\n avatar_background: (raw.avatar_background as string) ?? null,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n };\n}\n\nfunction createGroupsAdapter(client: FetchClient): GroupsApi {\n return {\n listGroups: async () => {\n const response = await portalTenantContacts.contacts_groups_list(client);\n const body = response as Record<string, unknown>;\n return {\n groups: ((body.groups as Record<string, unknown>[]) ?? []).map(\n mapGroup,\n ),\n };\n },\n\n createGroup: async (input) => {\n const response = await portalTenantContacts.contacts_groups_create(\n client,\n {\n group: input,\n } as Parameters<typeof portalTenantContacts.contacts_groups_create>[1],\n );\n const body = response as Record<string, unknown>;\n return {\n group: mapGroup(body.group as Record<string, unknown>),\n };\n },\n\n updateGroup: async (groupId, input) => {\n const response = await portalTenantContacts.contacts_groups_update(\n client,\n groupId,\n {\n group: input,\n } as Parameters<typeof portalTenantContacts.contacts_groups_update>[2],\n );\n const body = response as Record<string, unknown>;\n return {\n group: mapGroup(body.group as Record<string, unknown>),\n };\n },\n\n deleteGroup: async (groupId) => {\n return portalTenantContacts.contacts_groups_destroy(client, groupId);\n },\n };\n}\n\n/**\n * Creates a composite ContactsDomainApi backed by the portal-tenant\n * Contacts BFF endpoints.\n */\nexport function createPortalContactsDomainApiAdapter(\n client: FetchClient,\n): ContactsDomainApi {\n return {\n contacts: createContactsAdapter(client),\n notes: createNotesAdapter(client),\n tasks: createTasksAdapter(client),\n groups: createGroupsAdapter(client),\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { ContactsApiProvider } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalContactsDomainApiAdapter } from \"../adapters/contacts-api-adapter\";\n\nexport function PortalContactsApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(\n () => createPortalContactsDomainApiAdapter(client),\n [client],\n );\n\n return <ContactsApiProvider value={api}>{children}</ContactsApiProvider>;\n}\n","export const contactsEn = {\n breadcrumb: \"Contacts\",\n breadcrumb_new: \"New Contact\",\n contact_label: \"Contact\",\n add: \"Add\",\n add_contact: \"Add Contact\",\n adding: \"Adding...\",\n update_contact: \"Update Contact\",\n saving: \"Saving\",\n cancel: \"Cancel\",\n save: \"Save\",\n delete: \"Delete\",\n delete_name: \"Delete {{name}}?\",\n delete_confirm_permanent:\n \"This permanently removes the contact and all of their notes, tasks, and activity. This can't be undone.\",\n delete_contact: \"Delete contact\",\n deleting: \"Deleting...\",\n search_placeholder: \"Search contacts\",\n error_loading: \"Couldn't load contact\",\n error_loading_description:\n \"This contact may have been deleted, you may not have permission to view it, or there was a network error. Try selecting them again.\",\n error_loading_list: \"Couldn't load contacts. Pull down to retry.\",\n error_generic: \"Something went wrong. Please try again later.\",\n loading: \"Loading...\",\n loading_more: \"Loading more...\",\n searching: \"Searching...\",\n people_count: \"{{count}} people across your network\",\n person_count: \"{{count}} person across your network\",\n no_contacts_search: 'No contacts match \"{{term}}\".',\n no_contacts_yet: \"No contacts yet.\",\n no_contacts_filter: \"No contacts match this filter.\",\n empty_select_contact: \"Select a contact\",\n empty_select_description:\n \"Pick someone from your list on the left to see their details, notes, and tasks.\",\n tab_tasks: \"Tasks\",\n tab_notes: \"Notes\",\n edit_profile: \"Edit profile\",\n editing_name: \"Editing {{name}}\",\n profile_edit_description:\n \"Update details below. Your contact card above is paused while you edit.\",\n new_task: \"New task\",\n last_updated: \"Last updated {{date}}\",\n label_email: \"Email\",\n label_phone: \"Phone\",\n label_address: \"Address\",\n label_call: \"Call\",\n not_set: \"Not set\",\n more_actions: \"More actions\",\n back_to_contacts: \"Back to contacts\",\n back_to_tasks: \"Back to Tasks\",\n filter_all: \"All\",\n filter_leads: \"Leads\",\n filter_customers: \"Customers\",\n} as const satisfies Record<string, string>;\n\nexport type ContactsDict = typeof contactsEn;\n","import {\n createDomainTranslations,\n type DomainTranslations,\n} from \"@fluid-app/i18n/translations\";\nimport { createStaticDictAdapter } from \"@fluid-app/i18n/static-dict-adapter\";\nimport type { TranslationApi } from \"@fluid-app/i18n/translation-api\";\nimport { contactsEn, type ContactsDict } from \"./translation-dictionary\";\n\nexport const contactsDomain: DomainTranslations<ContactsDict> =\n createDomainTranslations<ContactsDict>({\n fallback: contactsEn,\n loaders: {\n de: () =>\n import(\"./locale/de.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n el: () =>\n import(\"./locale/el.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n es: () =>\n import(\"./locale/es.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n fr: () =>\n import(\"./locale/fr.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n he: () =>\n import(\"./locale/he.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n hu: () =>\n import(\"./locale/hu.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n id: () =>\n import(\"./locale/id.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n it: () =>\n import(\"./locale/it.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ja: () =>\n import(\"./locale/ja.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ko: () =>\n import(\"./locale/ko.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n nl: () =>\n import(\"./locale/nl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n pl: () =>\n import(\"./locale/pl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n pt: () =>\n import(\"./locale/pt.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ro: () =>\n import(\"./locale/ro.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ru: () =>\n import(\"./locale/ru.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n th: () =>\n import(\"./locale/th.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n tl: () =>\n import(\"./locale/tl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n tr: () =>\n import(\"./locale/tr.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n zh_CN: () =>\n import(\"./locale/zh_CN.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n zh_TW: () =>\n import(\"./locale/zh_TW.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n },\n });\n\nexport function createContactsTranslationAdapter(\n locale: string,\n dict: ContactsDict,\n): TranslationApi<ContactsDict> {\n return createStaticDictAdapter(locale, dict);\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport { useActiveLocale } from \"@fluid-app/i18n/locale-context\";\nimport { useDomainDict } from \"@fluid-app/i18n/use-domain-dict\";\nimport {\n contactsDomain,\n createContactsTranslationAdapter,\n} from \"@fluid-app/contacts-core/translation-adapter\";\nimport { ContactsTranslationProvider } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport function ContactsTranslationBridge({\n children,\n}: {\n children: ReactNode;\n}): React.JSX.Element {\n const { locale } = useActiveLocale();\n const dict = useDomainDict(contactsDomain, locale);\n const api = useMemo(\n () => createContactsTranslationAdapter(locale, dict),\n [locale, dict],\n );\n return (\n <ContactsTranslationProvider value={api}>\n {children}\n </ContactsTranslationProvider>\n );\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { FormProvider } from \"react-hook-form\";\nimport { useZodForm } from \"@fluid-app/ui-primitives\";\nimport type { ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ContactCreateScreen } from \"@fluid-app/contacts-ui/screens/ContactCreateScreen\";\nimport { RepContactsLayout } from \"@fluid-app/contacts-ui/portal/components/contacts/rep-layout/RepContactsLayout\";\nimport { ContactDetailsForm } from \"@fluid-app/contacts-ui/shared/components/contacts/contactDetailsForm\";\nimport { useCreateContactMutation } from \"@fluid-app/contacts-ui/shared/hooks/useCreateContactMutation\";\nimport {\n createContactFormSchema,\n type CreateContactFormData,\n} from \"@fluid-app/contacts-ui/shared/schemas/contactFormSchema\";\nimport { useCountriesApi } from \"@fluid-app/store-core/countries-api-context\";\nimport { PortalContactsApiProvider } from \"../contacts/PortalContactsApiProvider\";\nimport { ContactsTranslationBridge } from \"../providers/ContactsTranslationBridge\";\nimport { storeKeys } from \"../account/query-keys\";\n\ntype NavState =\n | { view: \"browse\"; selectedContactId: string | null }\n | { view: \"new\" };\n\ntype ContactsScreenProps = ComponentProps<\"div\"> & {\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display\n defaultViewMode?: \"list\" | \"grid\";\n\n // Callbacks\n onContactSelect?: (contactId: string) => void;\n onCreateContact?: () => void;\n};\n\nconst QUERY_KEY_PREFIX = \"sdk-contacts\";\n\nfunction ContactBrowseView({\n selectedContactId,\n onSelect,\n onAdd,\n}: {\n selectedContactId: string | null;\n onSelect: (id: string | null) => void;\n onAdd: () => void;\n}) {\n const countriesAdapter = useCountriesApi();\n const getCountries = useCallback(async () => {\n const result = await countriesAdapter.listCountries();\n return result.countries.map((c) => ({ id: 0, name: c.name, iso: c.code }));\n }, [countriesAdapter]);\n\n return (\n <RepContactsLayout\n selectedContactId={selectedContactId}\n onSelect={onSelect}\n onAdd={onAdd}\n queryKeyPrefix={QUERY_KEY_PREFIX}\n getCountries={getCountries}\n />\n );\n}\n\nconst CREATE_DEFAULT_VALUES: CreateContactFormData = {\n first_name: \"\",\n last_name: \"\",\n email: \"\",\n phone: \"\",\n status: \"new\",\n address: \"\",\n city: \"\",\n state: \"\",\n postal_code: \"\",\n country_code: null,\n language_code: null,\n metadata: {},\n affiliate: {},\n};\n\nfunction ContactCreateView({\n onNavigate,\n onCreateContact,\n}: {\n onNavigate: (state: NavState) => void;\n onCreateContact?: () => void;\n}) {\n const formRef = useRef<HTMLFormElement>(null);\n const countriesAdapter = useCountriesApi();\n\n const { data: countriesResponse } = useQuery({\n queryKey: storeKeys.countries(),\n queryFn: () => countriesAdapter.listCountries(),\n });\n\n const countryOptions = useMemo(\n () =>\n (countriesResponse?.countries ?? [])\n .map((c) => ({ name: c.name, value: c.code }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [countriesResponse],\n );\n\n const methods = useZodForm<CreateContactFormData>(createContactFormSchema, {\n defaultValues: CREATE_DEFAULT_VALUES,\n });\n\n const mutation = useCreateContactMutation(QUERY_KEY_PREFIX, {\n onSuccess: (data) => {\n onCreateContact?.();\n const newContactId = data?.contact?.id;\n if (newContactId) {\n onNavigate({\n view: \"browse\",\n selectedContactId: String(newContactId),\n });\n } else {\n onNavigate({ view: \"browse\", selectedContactId: null });\n }\n },\n });\n\n const { mutate } = mutation;\n\n const onSubmit = useMemo(\n () =>\n methods.handleSubmit(\n (data) => {\n const { affiliate, ...contactFields } = data;\n const payload: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(contactFields)) {\n if (value !== \"\" && value !== null && value !== undefined) {\n payload[key] = value;\n }\n }\n\n if (affiliate && Object.keys(affiliate).length > 0) {\n payload.affiliate = affiliate;\n }\n\n mutate(payload as CreateContactFormData);\n },\n () => {\n // Validation errors are shown inline by react-hook-form field controllers.\n // handleSubmit already populates field errors before calling this callback.\n },\n ),\n [methods, mutate],\n );\n\n const handleNavigateToList = useCallback(() => {\n onNavigate({ view: \"browse\", selectedContactId: null });\n }, [onNavigate]);\n\n return (\n <ContactCreateScreen\n onNavigateToList={handleNavigateToList}\n onSubmit={() => formRef.current?.requestSubmit()}\n isPending={mutation.isPending}\n >\n <FormProvider {...methods}>\n <div className=\"mx-auto max-w-7xl space-y-12 md:px-10 md:py-8\">\n <form\n ref={formRef}\n onSubmit={onSubmit}\n className=\"mx-auto space-y-6 lg:max-w-2xl\"\n >\n <ContactDetailsForm countries={countryOptions} />\n </form>\n </div>\n </FormProvider>\n </ContactCreateScreen>\n );\n}\n\nexport function ContactsScreen({\n onContactSelect,\n onCreateContact,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n defaultViewMode,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ContactsScreenProps): React.JSX.Element {\n const [nav, setNav] = useState<NavState>({\n view: \"browse\",\n selectedContactId: null,\n });\n\n const handleSelect = useCallback(\n (id: string | null) => {\n setNav({ view: \"browse\", selectedContactId: id });\n if (id) onContactSelect?.(id);\n },\n [onContactSelect],\n );\n\n const handleAdd = useCallback(() => {\n setNav({ view: \"new\" });\n }, []);\n\n return (\n <ContactsTranslationBridge>\n <PortalContactsApiProvider>\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n {nav.view === \"browse\" && (\n <ContactBrowseView\n selectedContactId={nav.selectedContactId}\n onSelect={handleSelect}\n onAdd={handleAdd}\n />\n )}\n {nav.view === \"new\" && (\n <ContactCreateView\n onNavigate={setNav}\n onCreateContact={onCreateContact}\n />\n )}\n </div>\n </PortalContactsApiProvider>\n </ContactsTranslationBridge>\n );\n}\n\nexport const contactsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ContactsScreen\",\n displayName: \"Contacts Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ContactsScreen-BTBszjeo.cjs","names":["createTranslationContext","Button","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","BreadcrumbPage","cn","cn","ChevronRight","Plus","Search","Input","cn","parseApiErrors","parseApiErrors","z","useZodForm","Mail","Phone","MapPin","parseApiErrors","parseApiErrors","parseApiErrors","parseApiErrors","useEditor","StarterKit","Heading","Placeholder","TextAlign","Underline","cn","AlignLeft","AlignCenter","AlignRight","AlignJustify","List","ListOrdered","Calendar","X","EditorContent","Sheet","SheetContent","SheetHeader","SheetTitle","Input","Calendar","X","SheetFooter","Button","formatDueDate","EmptyState","ClipboardList","SquareCheckBig","Plus","parseTaskBody","CircleCheck","cn","DropdownMenu","DropdownMenuTrigger","Button","EllipsisVertical","DropdownMenuContent","DropdownMenuItem","Calendar","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","parseApiErrors","parseApiErrors","parseApiErrors","StickyNote","Pen","Plus","DropdownMenu","DropdownMenuTrigger","EllipsisVertical","DropdownMenuContent","DropdownMenuItem","Calendar","Paperclip","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","cn","FormField","FormItem","FormLabel","FormControl","Input","FormMessage","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","ArrowLeft","Button","Spinner","cn","Plus","Card","CardContent","FormProvider","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","ChevronLeft","Phone","Mail","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","Trash2","cn","Users","cn","parseApiErrors","portalTenantContacts.contacts_show","portalTenantContacts.contacts_list","portalTenantContacts.contacts_create","portalTenantContacts.contacts_update","portalTenantContacts.contacts_destroy","portalTenantContacts.contacts_bulk_destroy","portalTenantContacts.contacts_notes_list","portalTenantContacts.contacts_notes_create","portalTenantContacts.contacts_notes_update","portalTenantContacts.contacts_notes_destroy","portalTenantContacts.contacts_tasks_list","portalTenantContacts.contacts_tasks_create","portalTenantContacts.contacts_tasks_update","portalTenantContacts.contacts_tasks_destroy","portalTenantContacts.contacts_groups_list","portalTenantContacts.contacts_groups_create","portalTenantContacts.contacts_groups_update","portalTenantContacts.contacts_groups_destroy","usePortalTenantClient","createDomainTranslations","createStaticDictAdapter","useActiveLocale","useDomainDict","useCountriesApi","storeKeys","useZodForm","FormProvider"],"sources":["../../../contacts/core/src/translation-api-context.ts","../../../contacts/ui/src/screens/ContactCreateScreen.tsx","../../../contacts/core/src/contacts-api-context.ts","../../../contacts/core/src/query-keys.ts","../../../contacts/core/src/hooks/use-infinite-contacts.ts","../../../contacts/ui/src/portal/hooks/groups/use-groups.ts","../../../contacts/ui/src/shared/components/contacts/statusBadge.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/utils.ts","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsSidebarRow.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsSidebar.tsx","../../../contacts/ui/src/shared/hooks/useContactDetail.ts","../../../contacts/ui/src/shared/hooks/useUpdateContactMutation.ts","../../../contacts/ui/src/shared/hooks/useDeleteContactMutation.ts","../../../contacts/ui/src/shared/schemas/contactFormSchema.ts","../../../contacts/ui/src/shared/hooks/useContactDetailPage.ts","../../../contacts/ui/src/portal/hooks/contacts/use-contact-tasks.ts","../../../contacts/ui/src/portal/hooks/notes/use-contact-notes.ts","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailHero.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactInfoRow.tsx","../../../contacts/ui/src/portal/hooks/contacts/use-toggle-task-completion.ts","../../../contacts/ui/src/portal/hooks/contacts/use-delete-contact-task.ts","../../../contacts/ui/src/portal/hooks/contacts/use-create-contact-task.ts","../../../contacts/ui/src/portal/hooks/contacts/use-update-contact-task.ts","../../../contacts/ui/src/portal/utils/format-date.ts","../../../contacts/ui/src/portal/components/editor/note-task-editor.tsx","../../../contacts/ui/src/portal/components/editor/note-task-modal.tsx","../../../contacts/ui/src/portal/components/tasks/task-list.tsx","../../../contacts/ui/src/portal/hooks/notes/use-delete-contact-note.ts","../../../contacts/ui/src/portal/hooks/notes/use-create-contact-note.ts","../../../contacts/ui/src/portal/hooks/notes/use-update-contact-note.ts","../../../contacts/ui/src/portal/components/notes/notes-list.tsx","../../../contacts/ui/src/shared/components/contacts/contactDetailsForm.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailTabs.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactDetailPane.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/ContactsEmptyState.tsx","../../../contacts/ui/src/portal/components/contacts/rep-layout/RepContactsLayout.tsx","../../../contacts/ui/src/shared/hooks/useCreateContactMutation.ts","../../../api-clients/portal-tenant-contacts/src/namespaces/portal_tenant_contacts.ts","../src/adapters/contacts-api-adapter.ts","../src/contacts/PortalContactsApiProvider.tsx","../../../contacts/core/src/translation-dictionary.ts","../../../contacts/core/src/translation-adapter.ts","../src/providers/ContactsTranslationBridge.tsx","../src/screens/ContactsScreen.tsx"],"sourcesContent":["import { createTranslationContext } from \"@fluid-app/i18n/translation-api-context-factory\";\nimport type { ContactsDict } from \"./translation-dictionary\";\n\nconst { Provider, useTranslation } =\n createTranslationContext<ContactsDict>(\"Contacts\");\n\nexport const ContactsTranslationProvider = Provider;\nexport const useContactsTranslation = useTranslation;\n","\"use client\";\n\nimport { useMemo, type ReactNode } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n Button,\n} from \"@fluid-app/ui-primitives\";\nimport {\n useScreenHeaderActions,\n useScreenHeaderBreadcrumbs,\n} from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport interface ContactCreateScreenProps {\n onNavigateToList: () => void;\n onSubmit: () => void;\n isPending: boolean;\n children: ReactNode;\n}\n\nexport function ContactCreateScreen({\n onNavigateToList,\n onSubmit,\n isPending,\n children,\n}: ContactCreateScreenProps) {\n const { t } = useContactsTranslation();\n\n const headerActions = useMemo(\n () => (\n <>\n <Button\n variant=\"outline\"\n onClick={onNavigateToList}\n disabled={isPending}\n >\n {t(\"cancel\")}\n </Button>\n <Button onClick={onSubmit} disabled={isPending}>\n {isPending ? t(\"adding\") : t(\"add_contact\")}\n </Button>\n </>\n ),\n [onNavigateToList, onSubmit, isPending, t],\n );\n useScreenHeaderActions(headerActions);\n\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n {t(\"breadcrumb\")}\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n {t(\"breadcrumb_new\")}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [onNavigateToList, t],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return <>{children}</>;\n}\n","import { createContext, useContext } from \"react\";\nimport type { ContactsApi } from \"./contacts-api\";\nimport type { NotesApi } from \"./notes-api\";\nimport type { TasksApi } from \"./tasks-api\";\nimport type { GroupsApi } from \"./groups-api\";\n\nexport interface ContactsDomainApi {\n contacts: ContactsApi;\n notes: NotesApi;\n tasks: TasksApi;\n groups?: GroupsApi;\n}\n\nconst ContactsApiContext = createContext<ContactsDomainApi | null>(null);\n\nexport const ContactsApiProvider = ContactsApiContext.Provider;\n\nexport function useContactsDomainApi(): ContactsDomainApi {\n const api = useContext(ContactsApiContext);\n if (!api) {\n throw new Error(\n \"useContactsDomainApi must be used within a ContactsApiProvider\",\n );\n }\n return api;\n}\n\nexport function useContactsCrud(): ContactsApi {\n return useContactsDomainApi().contacts;\n}\n\nexport function useNotesApi(): NotesApi {\n return useContactsDomainApi().notes;\n}\n\nexport function useTasksApi(): TasksApi {\n return useContactsDomainApi().tasks;\n}\n\n/** Returns GroupsApi if the provider supplies one, otherwise null. */\nexport function useGroupsApi(): GroupsApi | null {\n return useContactsDomainApi().groups ?? null;\n}\n","export const CONTACTS_QUERY_KEYS = {\n all: (prefix: string) => [prefix] as const,\n list: (prefix: string) =>\n [...CONTACTS_QUERY_KEYS.all(prefix), \"list\"] as const,\n detail: (prefix: string, id: string) =>\n [...CONTACTS_QUERY_KEYS.all(prefix), \"detail\", id] as const,\n} as const;\n\nexport const contactsKeys = {\n activities: (contactId: string) =>\n [\"portal-contacts\", \"activities\", contactId] as const,\n tasks: (contactId: string) =>\n [\"portal-contacts\", \"tasks\", contactId] as const,\n notes: (contactId: string) =>\n [\"portal-contacts\", \"notes\", contactId] as const,\n orders: (contactId: string) => [\"rep-contacts\", \"orders\", contactId] as const,\n subscriptionOrders: (contactId: string) =>\n [\"rep-contacts\", \"subscription-orders\", contactId] as const,\n groups: () => [\"portal-contacts\", \"groups\"] as const,\n} as const;\n","import { useInfiniteQuery } from \"@tanstack/react-query\";\nimport { useContactsCrud } from \"../contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"../query-keys\";\n\nexport interface UseInfiniteContactsParams {\n search_query?: string;\n status?: string;\n sort_by?: string;\n sort_direction?: string;\n per_page?: number;\n tags?: string[];\n}\n\nexport function useInfiniteContacts(params: UseInfiniteContactsParams) {\n const api = useContactsCrud();\n return useInfiniteQuery({\n queryKey: [...CONTACTS_QUERY_KEYS.list(\"contacts\"), params],\n queryFn: ({ pageParam }) =>\n api.listContacts({\n ...params,\n page: pageParam,\n }),\n getNextPageParam: (lastPage) => {\n const currentPage = lastPage.meta.current_page;\n // Contacts API is page-number based; next_cursor and total_pages\n // are both used as \"has-next-page\" signals.\n if (currentPage == null) return undefined;\n if (lastPage.meta.next_cursor) return currentPage + 1;\n if (\n lastPage.meta.total_pages != null &&\n currentPage < lastPage.meta.total_pages\n ) {\n return currentPage + 1;\n }\n return undefined;\n },\n initialPageParam: 1,\n });\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useGroupsApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useGroups() {\n const api = useGroupsApi();\n\n return useQuery({\n queryKey: contactsKeys.groups(),\n queryFn: () => api!.listGroups(),\n enabled: !!api,\n select: (data) => data.groups,\n });\n}\n","import React from \"react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\n\nconst statusStyles: Record<string, string> = {\n // Contact statuses\n new: \"border-[var(--status-new-border)] bg-[var(--status-new)] text-[var(--status-new-foreground)]\",\n active:\n \"border-[var(--status-active-border)] bg-[var(--status-active)] text-[var(--status-active-foreground)]\",\n inactive: \"border-border bg-muted text-muted-foreground\",\n lead: \"border-[var(--status-lead-border)] bg-[var(--status-lead)] text-[var(--status-lead-foreground)]\",\n customer:\n \"border-[var(--status-customer-border)] bg-[var(--status-customer)] text-[var(--status-customer-foreground)]\",\n // Semantic categories (orders, subscriptions, etc.)\n success:\n \"border-[var(--badge-success-border)] bg-[var(--badge-success)] text-[var(--badge-success-foreground)]\",\n warning:\n \"border-[var(--badge-warning-border)] bg-[var(--badge-warning)] text-[var(--badge-warning-foreground)]\",\n danger:\n \"border-[var(--badge-danger-border)] bg-[var(--badge-danger)] text-[var(--badge-danger-foreground)]\",\n info: \"border-[var(--badge-info-border)] bg-[var(--badge-info)] text-[var(--badge-info-foreground)]\",\n neutral: \"border-border bg-muted text-muted-foreground\",\n notice:\n \"border-[var(--badge-notice-border)] bg-[var(--badge-notice)] text-[var(--badge-notice-foreground)]\",\n accent:\n \"border-[var(--badge-accent-border)] bg-[var(--badge-accent)] text-[var(--badge-accent-foreground)]\",\n};\n\nconst defaultStyle = \"border-border bg-muted text-muted-foreground\";\n\nexport type StatusBadgeVariant = keyof typeof statusStyles;\n\nexport function getStatusStyle(status: string): string {\n return statusStyles[status] ?? defaultStyle;\n}\n\nexport function StatusBadge({\n status,\n label,\n className,\n}: {\n status: string;\n label?: string;\n className?: string;\n}): React.JSX.Element {\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold capitalize\",\n getStatusStyle(status),\n className,\n )}\n >\n {label ?? status}\n </span>\n );\n}\n","import type { Contact } from \"@fluid-app/contacts-core/types\";\n\nexport function getDisplayName(contact: Contact): string {\n if (contact.full_name && contact.full_name.trim().length > 0) {\n return contact.full_name;\n }\n const parts = [contact.first_name, contact.last_name].filter(Boolean);\n if (parts.length > 0) return parts.join(\" \");\n if (contact.email) return contact.email;\n return \"Contact\";\n}\n\nexport function getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n/** Lowercase relative label derived from `contact.updated_at`.\n * Returns null if the timestamp is missing or unparseable. Lowercase on\n * purpose so callers can compose phrases like \"Last updated 3 days ago\"\n * without an awkward \"Last updated Today\". */\nexport function getRelativeUpdated(contact: Contact): string | null {\n const updated =\n typeof contact.updated_at === \"string\" ? contact.updated_at : null;\n if (!updated) return null;\n const date = new Date(updated);\n if (Number.isNaN(date.getTime())) return null;\n\n const diffMs = Date.now() - date.getTime();\n const day = 1000 * 60 * 60 * 24;\n const diffDays = Math.floor(diffMs / day);\n\n if (diffDays <= 0) return \"today\";\n if (diffDays === 1) return \"yesterday\";\n if (diffDays < 7) return `${diffDays} days ago`;\n if (diffDays < 30) {\n const weeks = Math.floor(diffDays / 7);\n return weeks === 1 ? \"1 week ago\" : `${weeks} weeks ago`;\n }\n if (diffDays < 365) {\n const months = Math.floor(diffDays / 30);\n return months === 1 ? \"1 month ago\" : `${months} months ago`;\n }\n const years = Math.floor(diffDays / 365);\n return years === 1 ? \"1 year ago\" : `${years} years ago`;\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { StatusBadge } from \"../../../../shared/components/contacts/statusBadge\";\nimport { getDisplayName, getInitials, getRelativeUpdated } from \"./utils\";\n\nexport interface ContactsSidebarRowProps {\n contact: Contact;\n isSelected: boolean;\n onSelect: (id: string) => void;\n}\n\nexport function ContactsSidebarRow({\n contact,\n isSelected,\n onSelect,\n}: ContactsSidebarRowProps): React.JSX.Element {\n const name = getDisplayName(contact);\n const id = String(contact.id);\n const status = contact.status?.trim() || null;\n const relativeLabel = getRelativeUpdated(contact);\n const secondary = contact.email ?? status ?? null;\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(id)}\n aria-current={isSelected ? \"true\" : undefined}\n className={cn(\n \"group flex w-full items-center gap-3.5 rounded-xl px-3 py-3 text-left transition-colors\",\n isSelected ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n >\n <div className=\"bg-muted text-muted-foreground relative flex size-12 shrink-0 items-center justify-center overflow-hidden rounded-xl text-base font-semibold shadow-sm\">\n {contact.avatar_url ? (\n <img\n alt={name}\n src={contact.avatar_url}\n className=\"size-12 object-cover\"\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(name)}</span>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-foreground truncate text-sm font-bold tracking-tight\">\n {name}\n </span>\n {status && <StatusBadge status={status} className=\"shrink-0\" />}\n </div>\n <div className=\"text-muted-foreground mt-0.5 flex items-center gap-2 text-sm\">\n {secondary && <span className=\"truncate\">{secondary}</span>}\n {secondary && relativeLabel && (\n <span\n className=\"text-muted-foreground/60 shrink-0 text-xs\"\n aria-hidden=\"true\"\n >\n ·\n </span>\n )}\n {relativeLabel && (\n <span className=\"text-muted-foreground/60 shrink-0 text-xs\">\n {relativeLabel}\n </span>\n )}\n </div>\n </div>\n\n <ChevronRight\n className={cn(\n \"size-4 shrink-0 transition-all\",\n isSelected\n ? \"text-foreground\"\n : \"text-muted-foreground/60 group-hover:text-foreground group-hover:translate-x-0.5\",\n )}\n aria-hidden=\"true\"\n />\n </button>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Plus, Search } from \"lucide-react\";\nimport { cn, Input } from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useGroups } from \"../../../hooks/groups/use-groups\";\nimport { ContactsSidebarRow } from \"./ContactsSidebarRow\";\n\nexport interface ContactsSidebarProps {\n selectedContactId: string | null;\n onSelect: (id: string) => void;\n onAdd: () => void;\n}\n\nconst DEBOUNCE_MS = 200;\n\ntype FilterValue =\n | { kind: \"all\" }\n | { kind: \"status\"; status: \"lead\" | \"customer\" }\n | { kind: \"group\"; tag: string };\n\nfunction useBuiltInFilters(): {\n id: string;\n label: string;\n value: FilterValue;\n}[] {\n const { t } = useContactsTranslation();\n return [\n { id: \"all\", label: t(\"filter_all\"), value: { kind: \"all\" } },\n {\n id: \"status:lead\",\n label: t(\"filter_leads\"),\n value: { kind: \"status\", status: \"lead\" },\n },\n {\n id: \"status:customer\",\n label: t(\"filter_customers\"),\n value: { kind: \"status\", status: \"customer\" },\n },\n ];\n}\n\nfunction filterId(value: FilterValue): string {\n if (value.kind === \"all\") return \"all\";\n if (value.kind === \"status\") return `status:${value.status}`;\n return `group:${value.tag}`;\n}\n\nexport function ContactsSidebar({\n selectedContactId,\n onSelect,\n onAdd,\n}: ContactsSidebarProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [filter, setFilter] = useState<FilterValue>({ kind: \"all\" });\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const { data: groups = [] } = useGroups();\n\n const queryParams = useMemo(\n () => ({\n search_query: debouncedSearch || undefined,\n tags: filter.kind === \"group\" ? [filter.tag] : undefined,\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 50,\n }),\n [debouncedSearch, filter],\n );\n\n const {\n data,\n isLoading,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n isError,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n const visibleContacts = useMemo(() => {\n if (filter.kind === \"status\") {\n return contacts.filter((c) => c.status === filter.status);\n }\n return contacts;\n }, [contacts, filter]);\n\n // Server `total_count` ignores the client-side status filter, so when a\n // status pill is active we report the locally-filtered count instead.\n const serverTotalCount = data?.pages[0]?.meta.total_count ?? contacts.length;\n const subtitleCount =\n filter.kind === \"status\" ? visibleContacts.length : serverTotalCount;\n\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // Auto-select the first contact on initial load so the right pane shows\n // detail instead of the empty state. Desktop only — on mobile the layout\n // hides the sidebar when a contact is selected, so auto-selecting would\n // drop the rep straight into a detail view with no list visible. Ref\n // guards re-fires so explicit deselects (back button, post-delete, filter\n // changes) don't get clobbered.\n const hasAutoSelectedRef = useRef(false);\n useEffect(() => {\n if (hasAutoSelectedRef.current) return;\n if (selectedContactId) {\n hasAutoSelectedRef.current = true;\n return;\n }\n if (isLoading || visibleContacts.length === 0) return;\n const isDesktop =\n typeof window === \"undefined\" ||\n window.matchMedia(\"(min-width: 768px)\").matches;\n if (!isDesktop) {\n hasAutoSelectedRef.current = true;\n return;\n }\n const first = visibleContacts[0];\n if (first) {\n hasAutoSelectedRef.current = true;\n onSelect(String(first.id));\n }\n }, [selectedContactId, isLoading, visibleContacts, onSelect]);\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel || !hasNextPage) return;\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (entry?.isIntersecting && !isFetchingNextPage) {\n fetchNextPage();\n }\n });\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n const activeFilterId = filterId(filter);\n\n return (\n <>\n <div className=\"px-7 pt-8 pb-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <h1 className=\"text-foreground text-2xl font-extrabold tracking-tight\">\n {t(\"breadcrumb\")}\n </h1>\n <p className=\"text-muted-foreground mt-1.5 text-sm\">\n {isLoading\n ? t(\"loading\")\n : hasNextPage && filter.kind === \"status\"\n ? t(\"searching\")\n : subtitleCount === 1\n ? t(\"person_count\", { count: subtitleCount })\n : t(\"people_count\", { count: subtitleCount })}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={onAdd}\n className=\"bg-foreground text-background hover:bg-foreground/90 inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-bold transition-colors\"\n >\n <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n {t(\"add\")}\n </button>\n </div>\n </div>\n\n <div className=\"px-6 pb-3\">\n <div className=\"bg-muted focus-within:ring-foreground/20 flex items-center gap-2.5 rounded-xl px-3.5 py-2.5 transition focus-within:ring-2\">\n <Search\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n <Input\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={t(\"search_placeholder\")}\n type=\"search\"\n className=\"placeholder:text-muted-foreground/80 h-auto flex-1 border-0 bg-transparent p-0 text-sm font-medium shadow-none focus-visible:ring-0\"\n aria-label={t(\"search_placeholder\")}\n />\n </div>\n </div>\n\n <FilterPills\n activeId={activeFilterId}\n groups={groups.map((g) => g.name)}\n onChange={setFilter}\n />\n\n <div className=\"flex-1 overflow-y-auto px-3 pb-8\">\n {isError ? (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {t(\"error_loading_list\")}\n </div>\n ) : isLoading ? (\n <SidebarSkeleton />\n ) : visibleContacts.length === 0 ? (\n // Status filters apply client-side, so an empty visible list with\n // more pages still pending means matching contacts may be on later\n // pages. Keep the sentinel mounted so the IntersectionObserver can\n // continue paging until we either find matches or exhaust the data.\n <div className=\"space-y-2\">\n {hasNextPage || isFetchingNextPage ? (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {t(\"searching\")}\n </div>\n ) : (\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : filter.kind === \"all\"\n ? t(\"no_contacts_yet\")\n : t(\"no_contacts_filter\")}\n </div>\n )}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n </div>\n ) : (\n <div className=\"space-y-1\">\n {visibleContacts.map((contact) => (\n <ContactsSidebarRow\n key={contact.id}\n contact={contact}\n isSelected={String(contact.id) === selectedContactId}\n onSelect={onSelect}\n />\n ))}\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground py-3 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </div>\n )}\n </div>\n </>\n );\n}\n\ninterface FilterPillsProps {\n activeId: string;\n groups: string[];\n onChange: (filter: FilterValue) => void;\n}\n\nfunction FilterPills({ activeId, groups, onChange }: FilterPillsProps) {\n const builtInFilters = useBuiltInFilters();\n const allFilters = useMemo<\n { id: string; label: string; value: FilterValue }[]\n >(\n () => [\n ...builtInFilters,\n ...groups.map((tag) => ({\n id: `group:${tag}`,\n label: tag,\n value: { kind: \"group\" as const, tag },\n })),\n ],\n [builtInFilters, groups],\n );\n\n return (\n <div className=\"px-6 pb-4\">\n <div className=\"flex gap-1.5 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {allFilters.map(({ id, label, value }) => {\n const isActive = id === activeId;\n return (\n <button\n key={id}\n type=\"button\"\n onClick={() => onChange(value)}\n aria-pressed={isActive}\n className={cn(\n \"shrink-0 rounded-full px-4 py-1.5 text-sm font-semibold capitalize transition-colors\",\n isActive\n ? \"bg-foreground text-background\"\n : \"border-border bg-muted text-foreground hover:bg-muted/70 border\",\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"space-y-1.5 px-1\">\n {[0, 1, 2, 3, 4].map((i) => (\n <div\n key={i}\n className=\"flex items-center gap-3 rounded-xl px-3 py-3\"\n aria-hidden=\"true\"\n >\n <div className=\"bg-muted size-12 shrink-0 animate-pulse rounded-xl\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"bg-muted h-3.5 w-3/5 animate-pulse rounded\" />\n <div className=\"bg-muted h-3 w-4/5 animate-pulse rounded\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useContactDetail(\n contactId: string,\n queryKeyPrefix = \"contacts\",\n) {\n const api = useContactsCrud();\n\n return useQuery({\n queryKey: CONTACTS_QUERY_KEYS.detail(queryKeyPrefix, contactId),\n queryFn: () => api.getContact(contactId),\n enabled: !!contactId,\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\ntype UpdateInput = {\n id: string;\n data: Record<string, unknown>;\n};\n\nexport function useUpdateContactMutation(\n contactId: string,\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: ({ id, data }: UpdateInput) => api.updateContact(id, data),\n onSuccess: () => {\n fluidToast({ title: \"Contact updated successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to save contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n options?.onError?.(error);\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactMutation(\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: (contactId: string) => api.deleteContact(contactId),\n onSuccess: () => {\n fluidToast({ title: \"Contact deleted successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n options?.onError?.(error);\n },\n });\n}\n","import { z } from \"zod\";\n\n/**\n * Form schema for creating a contact.\n * Matches CompanyContactCreate / ContactCreate from the OpenAPI spec.\n *\n * @see CompanyContactCreate in company_contacts.d.ts\n * @see ContactCreate in users_contacts.d.ts\n */\nexport const createContactFormSchema = z.object({\n first_name: z.string().min(1, { message: \"First name is required\" }),\n last_name: z.string().min(1, { message: \"Last name is required\" }),\n status: z.string().nullable().optional(),\n email: z.string().email().or(z.literal(\"\")).nullable().optional(),\n phone: z.string().nullable().optional(),\n address: z.string().nullable().optional(),\n city: z.string().nullable().optional(),\n state: z.string().nullable().optional(),\n postal_code: z.string().nullable().optional(),\n country_code: z.coerce.string().nullable().optional(),\n language_code: z.coerce.string().nullable().optional(),\n affiliate: z.record(z.string(), z.unknown()).nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type CreateContactFormData = z.infer<typeof createContactFormSchema>;\n\n/**\n * Form schema for editing a contact.\n * Same fields as create plus id. Uses .passthrough() so extra fields\n * from the Contact read model (full_name, avatar_url, etc.) don't\n * cause validation failures.\n *\n * @see CompanyContactUpdate in company_contacts.d.ts\n */\nexport const editContactFormSchema = createContactFormSchema.passthrough();\n\nexport type EditContactFormData = z.infer<typeof editContactFormSchema>;\n","\"use client\";\n\nimport { useMemo, useCallback } from \"react\";\nimport { useZodForm, fluidToast } from \"@fluid-app/ui-primitives\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useContactDetail } from \"./useContactDetail\";\nimport { useUpdateContactMutation } from \"./useUpdateContactMutation\";\nimport { useDeleteContactMutation } from \"./useDeleteContactMutation\";\nimport {\n createContactFormSchema,\n editContactFormSchema,\n type EditContactFormData,\n} from \"../schemas/contactFormSchema\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\n\nconst mutableKeys = Object.keys(\n createContactFormSchema.shape,\n) as (keyof EditContactFormData)[];\n\nexport function useContactDetailPage(\n contactId: string,\n options?: {\n queryKeyPrefix?: string;\n getCountries?: () => Promise<{ id: number; name: string; iso?: string }[]>;\n onDeleteSuccess?: () => void;\n },\n): {\n contact: Contact | undefined;\n isLoading: boolean;\n methods: UseFormReturn<EditContactFormData>;\n countryOptions: { name: string; value: string }[];\n isDirty: boolean;\n isSubmitting: boolean;\n isDeleting: boolean;\n onSave: () => void;\n onDelete: () => void;\n} {\n const queryKeyPrefix = options?.queryKeyPrefix ?? \"contacts\";\n\n const { data, isLoading } = useContactDetail(contactId, queryKeyPrefix);\n\n const { data: countries } = useQuery({\n queryKey: [\"countries\"],\n queryFn: options?.getCountries ?? (() => Promise.resolve([])),\n enabled: !!options?.getCountries,\n });\n\n const countryOptions = useMemo(\n () =>\n [\n ...(countries?.map((c) => ({\n name: c.name,\n value: c.iso ?? c.id.toString(),\n })) ?? []),\n ].sort((a, b) => a.name.localeCompare(b.name)),\n [countries],\n );\n\n const contact = data?.contact;\n\n // Map nested country object to the ISO code the form select expects\n const formValues = useMemo(() => {\n if (!contact) return undefined;\n return {\n ...contact,\n country_code:\n contact.country?.iso ?? contact.country_id?.toString() ?? null,\n } as unknown as EditContactFormData;\n }, [contact]);\n\n const methods = useZodForm<EditContactFormData>(editContactFormSchema, {\n values: formValues,\n mode: \"onBlur\",\n });\n\n const updateMutation = useUpdateContactMutation(contactId, queryKeyPrefix, {\n onSuccess: () => {\n methods.reset(methods.getValues());\n },\n });\n\n const deleteMutation = useDeleteContactMutation(queryKeyPrefix, {\n onSuccess: () => {\n options?.onDeleteSuccess?.();\n },\n });\n\n const onSave = useCallback(() => {\n methods.handleSubmit(\n (formData) => {\n const payload: Record<string, unknown> = {};\n for (const key of mutableKeys) {\n if (key in formData) {\n payload[key] = formData[key];\n }\n }\n\n updateMutation.mutate({\n id: contactId,\n data: payload,\n });\n },\n (errors) => {\n const errorMessages = Object.entries(errors)\n .map(([field, err]) => {\n const msg =\n typeof err?.message === \"string\" ? err.message : \"invalid\";\n return `${field.replace(/_/g, \" \")}: ${msg}`;\n })\n .join(\", \");\n fluidToast({\n title: \"Please fix the form errors before saving\",\n description: errorMessages || undefined,\n type: \"error\",\n });\n },\n )();\n }, [methods, updateMutation, contactId]);\n\n const onDelete = useCallback(() => {\n deleteMutation.mutate(contactId);\n }, [deleteMutation, contactId]);\n\n return {\n contact,\n isLoading,\n methods,\n countryOptions,\n isDirty: methods.formState.isDirty,\n isSubmitting: updateMutation.isPending,\n isDeleting: deleteMutation.isPending,\n onSave,\n onDelete,\n };\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { ContactTask } from \"@fluid-app/contacts-core/types\";\n\nexport type { ContactTask };\n\nexport const CONTACT_TASKS_QUERY_KEY = (contactId: string) =>\n contactsKeys.tasks(contactId);\n\nexport function useContactTasks(contactId: string) {\n const api = useTasksApi();\n\n return useQuery({\n queryKey: contactsKeys.tasks(contactId),\n queryFn: () => api.listTasks(contactId),\n enabled: !!contactId,\n select: (data) => data.tasks,\n });\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { ContactNote } from \"@fluid-app/contacts-core/types\";\n\nexport type { ContactNote };\n\nexport const CONTACT_NOTES_QUERY_KEY = (contactId: string) =>\n contactsKeys.notes(contactId);\n\nexport function useContactNotes(contactId: string) {\n const api = useNotesApi();\n\n return useQuery({\n queryKey: contactsKeys.notes(contactId),\n queryFn: () => api.listNotes(contactId),\n enabled: !!contactId,\n select: (data) => data.notes,\n });\n}\n","\"use client\";\n\nimport React from \"react\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { StatusBadge } from \"../../../../shared/components/contacts/statusBadge\";\nimport { getDisplayName, getInitials, getRelativeUpdated } from \"./utils\";\n\nexport interface ContactDetailHeroProps {\n contact: Contact;\n tasksCount: number;\n notesCount: number;\n}\n\nexport function ContactDetailHero({\n contact,\n tasksCount,\n notesCount,\n}: ContactDetailHeroProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const name = getDisplayName(contact);\n const status = contact.status?.trim();\n const lastUpdated = getRelativeUpdated(contact);\n\n return (\n <div className=\"flex flex-col gap-5 md:flex-row md:items-start md:justify-between md:gap-8\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:gap-5\">\n <div className=\"bg-muted text-muted-foreground relative flex size-20 shrink-0 items-center justify-center overflow-hidden rounded-xl text-2xl font-semibold shadow-sm md:size-24 md:text-2xl\">\n {contact.avatar_url ? (\n <img\n alt={name}\n src={contact.avatar_url}\n className=\"size-full object-cover\"\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(name)}</span>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-foreground text-2xl leading-tight font-extrabold tracking-tight\">\n {name}\n </h2>\n <div className=\"mt-3 flex flex-wrap items-center gap-2.5\">\n {status && <StatusBadge status={status} />}\n {lastUpdated && (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"last_updated\", { date: lastUpdated })}\n </span>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"bg-muted flex shrink-0 gap-6 rounded-xl px-5 py-4\">\n <Stat label={t(\"tab_tasks\")} value={tasksCount} />\n <div className=\"bg-border w-px\" aria-hidden=\"true\" />\n <Stat label={t(\"tab_notes\")} value={notesCount} />\n </div>\n </div>\n );\n}\n\nfunction Stat({ label, value }: { label: string; value: number }) {\n return (\n <div>\n <div className=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\">\n {label}\n </div>\n <div className=\"text-foreground mt-1 text-lg font-bold tracking-tight\">\n {value}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { Mail, MapPin, Phone } from \"lucide-react\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport interface ContactInfoRowProps {\n contact: Contact;\n}\n\nfunction buildAddressLine(contact: Contact): string | null {\n const parts = [\n contact.address,\n contact.city,\n contact.state,\n contact.postal_code,\n ].filter((part): part is string => Boolean(part?.trim()));\n if (parts.length === 0) return null;\n return parts.join(\", \");\n}\n\nexport function ContactInfoRow({\n contact,\n}: ContactInfoRowProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const address = buildAddressLine(contact);\n\n return (\n <div className=\"border-border bg-card mt-6 grid grid-cols-1 gap-x-6 gap-y-3 rounded-xl border p-4 md:grid-cols-3 md:p-5\">\n <InfoCell\n icon={<Mail className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_email\")}\n value={contact.email}\n notSetLabel={t(\"not_set\")}\n />\n <InfoCell\n icon={<Phone className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_phone\")}\n value={contact.phone}\n notSetLabel={t(\"not_set\")}\n />\n <InfoCell\n icon={<MapPin className=\"size-3.5\" aria-hidden=\"true\" />}\n label={t(\"label_address\")}\n value={address}\n notSetLabel={t(\"not_set\")}\n />\n </div>\n );\n}\n\ninterface InfoCellProps {\n icon: React.ReactNode;\n label: string;\n value: string | null | undefined;\n notSetLabel: string;\n}\n\nfunction InfoCell({ icon, label, value, notSetLabel }: InfoCellProps) {\n return (\n <div className=\"min-w-0\">\n <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs font-bold tracking-wider uppercase\">\n <span className=\"text-muted-foreground\">{icon}</span>\n {label}\n </div>\n <div className=\"text-foreground mt-1 truncate text-sm font-medium\">\n {value && value.trim().length > 0 ? (\n value\n ) : (\n <span className=\"text-muted-foreground/60 font-normal italic\">\n {notSetLabel}\n </span>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useToggleTaskCompletion(contactId: string) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: ({\n taskId,\n isCompleted,\n }: {\n taskId: number;\n isCompleted: boolean;\n }) =>\n api.updateTask(taskId, contactId, {\n completed_at: isCompleted ? null : new Date().toISOString(),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: (taskId: number) => api.deleteTask(taskId, contactId),\n onSuccess: () => {\n fluidToast({ title: \"Task deleted\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateTaskInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { CreateTaskInput };\n\nexport function useCreateContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: (input: CreateTaskInput) => api.createTask(contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Task created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to create task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useTasksApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { UpdateTaskInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { UpdateTaskInput };\n\nexport function useUpdateContactTask(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useTasksApi();\n\n return useMutation({\n mutationFn: ({\n taskId,\n input,\n }: {\n taskId: number;\n input: UpdateTaskInput;\n }) => api.updateTask(taskId, contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Task updated\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update task\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","export function formatDateForDisplay(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { useEditor, EditorContent } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Heading from \"@tiptap/extension-heading\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport Underline from \"@tiptap/extension-underline\";\nimport {\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n List,\n ListOrdered,\n Calendar,\n X,\n} from \"lucide-react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport { formatDateForDisplay } from \"../../utils/format-date\";\n\nexport interface NoteTaskEditorProps {\n titlePlaceholder?: string;\n bodyPlaceholder?: string;\n onChange?: (content: {\n title: string;\n body: string;\n dueDate?: string;\n }) => void;\n className?: string;\n /** Pre-populate the title (for edit mode) */\n initialTitle?: string;\n /** Pre-populate the body (for edit mode) */\n initialBody?: string;\n /** Show due date picker */\n showDueDate?: boolean;\n /** Pre-populate the due date (ISO string, for edit mode) */\n initialDueDate?: string;\n /** When false, the editor is body-only (no H1 title). Default true. */\n showTitle?: boolean;\n /** Override for the editor content area min-height class */\n editorClassName?: string;\n}\n\nfunction extractTitleAndBody(editor: ReturnType<typeof useEditor>): {\n title: string;\n body: string;\n} {\n if (!editor) return { title: \"\", body: \"\" };\n\n const doc = editor.state.doc;\n let title = \"\";\n const bodyParts: string[] = [];\n\n doc.forEach((node) => {\n if (node.type.name === \"heading\" && !title) {\n title = node.textContent.trim();\n } else {\n const text = node.textContent.trim();\n if (text) bodyParts.push(text);\n }\n });\n\n return { title, body: bodyParts.join(\"\\n\") };\n}\n\nfunction extractBodyOnly(editor: ReturnType<typeof useEditor>): string {\n if (!editor) return \"\";\n const parts: string[] = [];\n editor.state.doc.forEach((node) => {\n const text = node.textContent.trim();\n if (text) parts.push(text);\n });\n return parts.join(\"\\n\");\n}\n\nexport function NoteTaskEditor({\n titlePlaceholder = \"New Note\",\n bodyPlaceholder = \"Start writing...\",\n onChange,\n className,\n initialTitle,\n initialBody,\n showDueDate = false,\n initialDueDate,\n showTitle = true,\n editorClassName,\n}: NoteTaskEditorProps): React.JSX.Element {\n const [dueDate, setDueDate] = useState<string | undefined>(initialDueDate);\n const dueDateRef = useRef(initialDueDate);\n const dateInputRef = useRef<HTMLInputElement>(null);\n\n // Keep ref in sync with state so onUpdate always reads the latest value\n useEffect(() => {\n dueDateRef.current = dueDate;\n }, [dueDate]);\n\n const initialContent = showTitle\n ? initialTitle || initialBody\n ? `<h1>${initialTitle ?? \"\"}</h1>${initialBody ?? \"\"}`\n : undefined\n : initialBody || undefined;\n\n const extensions = [\n StarterKit.configure({\n heading: showTitle ? false : { levels: [] as const },\n bulletList: {\n keepMarks: true,\n keepAttributes: false,\n },\n orderedList: {\n keepMarks: true,\n keepAttributes: false,\n },\n }),\n ...(showTitle ? [Heading.configure({ levels: [1] })] : []),\n Placeholder.configure({\n placeholder: ({ node }) => {\n if (node.type.name === \"heading\") {\n return titlePlaceholder;\n }\n return bodyPlaceholder;\n },\n }),\n TextAlign.configure({\n types: showTitle ? [\"heading\", \"paragraph\"] : [\"paragraph\"],\n alignments: [\"left\", \"center\", \"right\", \"justify\"],\n }),\n Underline,\n ];\n\n const defaultContent = showTitle\n ? {\n type: \"doc\" as const,\n content: [{ type: \"heading\" as const, attrs: { level: 1 } }],\n }\n : undefined;\n\n const editor = useEditor({\n extensions,\n content: initialContent ?? defaultContent,\n onUpdate: ({ editor }) => {\n if (showTitle) {\n const { title, body } = extractTitleAndBody(editor);\n onChange?.({ title, body, dueDate: dueDateRef.current });\n } else {\n const body = extractBodyOnly(editor);\n onChange?.({ title: \"\", body, dueDate: dueDateRef.current });\n }\n },\n });\n\n const fireOnChange = () => {\n if (!editor || !onChange) return;\n if (showTitle) {\n const { title, body } = extractTitleAndBody(editor);\n onChange({ title, body, dueDate });\n } else {\n const body = extractBodyOnly(editor);\n onChange({ title: \"\", body, dueDate });\n }\n };\n\n // Fire onChange once on mount so the parent's ref is populated with the\n // initial values before the user makes any edits.\n useEffect(() => {\n fireOnChange();\n // We only want this to run once after the editor is first created.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor]);\n\n // Notify parent when due date changes\n useEffect(() => {\n fireOnChange();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dueDate]);\n\n const buttonBase =\n \"flex h-7 w-7 items-center justify-center rounded text-xs transition-colors\";\n const buttonActive = \"bg-muted text-primary\";\n const buttonInactive = \"text-muted-foreground hover:bg-muted/50\";\n\n const toolbarSeparator = <div className=\"bg-border mx-1 h-5 w-px\" />;\n\n return (\n <div\n className={cn(\n \"border-border flex flex-col overflow-hidden rounded-lg border\",\n className,\n )}\n >\n {/* Toolbar */}\n <div className=\"border-border bg-muted/50 flex items-center gap-0.5 border-b px-2 py-1.5\">\n {/* Bold */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBold().run()}\n disabled={!editor?.can().chain().focus().toggleBold().run()}\n className={cn(\n buttonBase,\n \"font-bold\",\n editor?.isActive(\"bold\") ? buttonActive : buttonInactive,\n )}\n title=\"Bold\"\n >\n B\n </button>\n\n {/* Italic */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleItalic().run()}\n disabled={!editor?.can().chain().focus().toggleItalic().run()}\n className={cn(\n buttonBase,\n \"italic\",\n editor?.isActive(\"italic\") ? buttonActive : buttonInactive,\n )}\n title=\"Italic\"\n >\n I\n </button>\n\n {/* Underline */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleUnderline().run()}\n disabled={!editor?.can().chain().focus().toggleUnderline().run()}\n className={cn(\n buttonBase,\n \"underline\",\n editor?.isActive(\"underline\") ? buttonActive : buttonInactive,\n )}\n title=\"Underline\"\n >\n U\n </button>\n\n {toolbarSeparator}\n\n {/* Align left */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"left\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"left\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align left\"\n >\n <AlignLeft className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align center */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"center\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"center\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align center\"\n >\n <AlignCenter className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align right */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"right\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"right\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Align right\"\n >\n <AlignRight className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Align justify */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().setTextAlign(\"justify\").run()}\n className={cn(\n buttonBase,\n editor?.isActive({ textAlign: \"justify\" })\n ? buttonActive\n : buttonInactive,\n )}\n title=\"Justify\"\n >\n <AlignJustify className=\"h-3.5 w-3.5\" />\n </button>\n\n {toolbarSeparator}\n\n {/* Bullet list */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBulletList().run()}\n className={cn(\n buttonBase,\n editor?.isActive(\"bulletList\") ? buttonActive : buttonInactive,\n )}\n title=\"Bullet list\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </button>\n\n {/* Ordered list */}\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleOrderedList().run()}\n className={cn(\n buttonBase,\n editor?.isActive(\"orderedList\") ? buttonActive : buttonInactive,\n )}\n title=\"Ordered list\"\n >\n <ListOrdered className=\"h-3.5 w-3.5\" />\n </button>\n\n {showDueDate && (\n <>\n {toolbarSeparator}\n {/* Due date */}\n {dueDate ? (\n <div className=\"bg-primary/10 flex items-center gap-1 rounded px-2 py-1\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n {formatDateForDisplay(dueDate)}\n </span>\n <button\n type=\"button\"\n onClick={() => setDueDate(undefined)}\n className=\"text-primary/60 hover:text-primary ml-1\"\n title=\"Remove due date\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={() => dateInputRef.current?.showPicker()}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-7 cursor-pointer items-center gap-1 rounded px-2 text-xs font-medium transition-colors\"\n >\n <Calendar className=\"h-3.5 w-3.5\" />\n <span>Due date</span>\n </button>\n <input\n ref={dateInputRef}\n type=\"date\"\n className=\"invisible absolute h-0 w-0\"\n onChange={(e) => {\n if (e.target.value) {\n // Convert YYYY-MM-DD to ISO datetime at local midnight\n const localDate = new Date(e.target.value + \"T00:00:00\");\n setDueDate(localDate.toISOString());\n }\n }}\n />\n </>\n )}\n </>\n )}\n </div>\n\n {/* Editor area */}\n <EditorContent\n editor={editor}\n className={editorClassName ?? \"min-h-[60vh] flex-1 overflow-y-auto p-4\"}\n />\n\n <style>{`\n .ProseMirror {\n outline: none;\n }\n\n .ProseMirror h1 {\n font-size: 1.5rem;\n font-weight: 600;\n line-height: 1.3;\n margin-bottom: 0.5rem;\n }\n\n .ProseMirror h1.is-empty::before,\n .ProseMirror p.is-empty::before {\n color: var(--color-muted-foreground);\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n }\n\n .ProseMirror ul {\n list-style-type: disc;\n padding-left: 1.5rem;\n margin: 0.5rem 0;\n }\n\n .ProseMirror ol {\n list-style-type: decimal;\n padding-left: 1.5rem;\n margin: 0.5rem 0;\n }\n\n .ProseMirror li {\n margin: 0.25rem 0;\n display: list-item;\n }\n\n .ProseMirror li > p {\n margin: 0;\n }\n `}</style>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useRef, useState } from \"react\";\nimport { Calendar, X } from \"lucide-react\";\nimport {\n Button,\n Input,\n Sheet,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from \"@fluid-app/ui-primitives\";\nimport { NoteTaskEditor } from \"./note-task-editor\";\nimport { formatDateForDisplay } from \"../../utils/format-date\";\n\nexport interface NoteTaskModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n mode: \"create\" | \"edit\";\n type: \"note\" | \"task\";\n initialTitle?: string;\n initialBody?: string;\n initialDueDate?: string;\n showDueDate?: boolean;\n onSave: (data: { title: string; body: string; dueDate?: string }) => void;\n isPending?: boolean;\n isCompleted?: boolean;\n onToggleComplete?: () => void;\n isTogglePending?: boolean;\n}\n\nexport function NoteTaskModal({\n open,\n onOpenChange,\n mode,\n type,\n initialTitle = \"\",\n initialBody = \"\",\n initialDueDate,\n showDueDate = false,\n onSave,\n isPending = false,\n isCompleted,\n onToggleComplete,\n isTogglePending = false,\n}: NoteTaskModalProps): React.JSX.Element {\n const [title, setTitle] = useState(initialTitle);\n const [body, setBody] = useState(initialBody);\n const dateInputRef = useRef<HTMLInputElement>(null);\n const [dueDate, setDueDate] = useState<string | undefined>(initialDueDate);\n\n const typeLabel = type === \"note\" ? \"Note\" : \"Task\";\n const sheetTitle = mode === \"edit\" ? `Edit ${typeLabel}` : `New ${typeLabel}`;\n\n const requiresBody = type === \"note\";\n const canSave =\n !!title.trim() && (!requiresBody || !!body.trim()) && !isPending;\n\n const handleSave = () => {\n if (!canSave) return;\n onSave({\n title: title.trim(),\n body,\n dueDate,\n });\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent className=\"flex w-full flex-col sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{sheetTitle}</SheetTitle>\n </SheetHeader>\n\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n <Input\n placeholder={`${typeLabel} title`}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n autoFocus\n />\n\n <NoteTaskEditor\n showTitle={false}\n bodyPlaceholder=\"Start writing...\"\n initialBody={initialBody}\n editorClassName=\"min-h-[200px] flex-1 overflow-y-auto p-4\"\n onChange={(content) => {\n setBody(content.body);\n }}\n />\n\n {showDueDate && (\n <div className=\"flex items-center gap-2\">\n {dueDate ? (\n <div className=\"bg-primary/10 inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-sm font-medium\">\n Due {formatDateForDisplay(dueDate)}\n </span>\n <button\n type=\"button\"\n onClick={() => setDueDate(undefined)}\n className=\"text-primary/60 hover:text-primary ml-1\"\n title=\"Remove due date\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => dateInputRef.current?.showPicker()}\n className=\"text-muted-foreground hover:text-foreground hover:bg-muted inline-flex cursor-pointer items-center gap-1.5 rounded-md px-2.5 py-1.5 text-sm font-medium transition-colors\"\n >\n <Calendar className=\"h-3.5 w-3.5\" />\n <span>Add due date</span>\n </button>\n <input\n ref={dateInputRef}\n type=\"date\"\n className=\"invisible absolute h-0 w-0\"\n onChange={(e) => {\n if (e.target.value) {\n const localDate = new Date(\n e.target.value + \"T00:00:00\",\n );\n setDueDate(localDate.toISOString());\n }\n }}\n />\n </div>\n )}\n </div>\n )}\n </div>\n\n <SheetFooter className=\"flex-row justify-end gap-2 border-t pt-4\">\n {mode === \"edit\" && onToggleComplete && (\n <Button\n variant=\"outline\"\n onClick={onToggleComplete}\n disabled={isTogglePending}\n className=\"mr-auto\"\n >\n {isCompleted ? \"Mark Incomplete\" : \"Mark Complete\"}\n </Button>\n )}\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!canSave}>\n {isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n );\n}\n","\"use client\";\n\nimport React, { useImperativeHandle, useState } from \"react\";\nimport {\n Calendar,\n Plus,\n ClipboardList,\n SquareCheckBig,\n CircleCheck,\n EllipsisVertical,\n} from \"lucide-react\";\nimport {\n cn,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport type { ContactTask } from \"../../hooks/contacts/use-contact-tasks\";\nimport { useToggleTaskCompletion } from \"../../hooks/contacts/use-toggle-task-completion\";\nimport { useDeleteContactTask } from \"../../hooks/contacts/use-delete-contact-task\";\nimport { useCreateContactTask } from \"../../hooks/contacts/use-create-contact-task\";\nimport { useUpdateContactTask } from \"../../hooks/contacts/use-update-contact-task\";\nimport { NoteTaskModal } from \"../editor/note-task-modal\";\n\n// ---------------------------------------------------------------------------\n// Date helpers\n// ---------------------------------------------------------------------------\n\nfunction formatDueDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\nfunction formatRelativeTime(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n } else if (diffDays === 1) {\n return \"Yesterday\";\n } else {\n return `${diffDays} days ago`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Empty state\n// ---------------------------------------------------------------------------\n\nfunction EmptyState({ onCreateTask }: { onCreateTask: () => void }) {\n return (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center\">\n <div className=\"relative mb-6\">\n <div className=\"flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-teal-100 to-emerald-100\">\n <ClipboardList className=\"h-9 w-9 text-teal-500\" />\n </div>\n <div className=\"border-background absolute -right-2 -bottom-1 flex h-9 w-9 items-center justify-center rounded-full border-2 bg-gradient-to-br from-blue-100 to-indigo-100 shadow-sm\">\n <SquareCheckBig className=\"h-4 w-4 text-blue-500\" />\n </div>\n </div>\n <h4 className=\"text-foreground text-base font-semibold\">No tasks yet</h4>\n <p className=\"text-muted-foreground mt-1.5 max-w-[260px] text-sm leading-relaxed\">\n Stay organized by creating tasks to track follow-ups for this contact\n </p>\n <button\n type=\"button\"\n onClick={onCreateTask}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 mt-4 inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n New Task\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Task card\n// ---------------------------------------------------------------------------\n\ninterface TaskCardProps {\n task: ContactTask;\n toggleCompletion: ReturnType<typeof useToggleTaskCompletion>;\n onEdit: (task: ContactTask) => void;\n onDeleteClick: (task: ContactTask) => void;\n}\n\nfunction TaskCard({\n task,\n toggleCompletion,\n onEdit,\n onDeleteClick,\n}: TaskCardProps) {\n const isCompleted = !!task.completed_at;\n\n const { title, body: bodyText } = parseTaskBody(task.body ?? \"\");\n\n const timestamp = task.created_at ? formatRelativeTime(task.created_at) : \"\";\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onEdit(task)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onEdit(task);\n }\n }}\n className=\"border-border bg-card min-w-[250px] cursor-pointer rounded-xl border p-4 transition-colors\"\n >\n <div className=\"flex items-start gap-3\">\n {/* Checkbox */}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n toggleCompletion.mutate({\n taskId: task.id,\n isCompleted: isCompleted,\n });\n }}\n disabled={toggleCompletion.isPending}\n className=\"mt-0.5 shrink-0 transition-opacity hover:opacity-70 disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={isCompleted ? \"Mark as open\" : \"Mark as completed\"}\n >\n {isCompleted ? (\n <CircleCheck className=\"text-primary h-5 w-5\" />\n ) : (\n <div className=\"border-muted-foreground h-5 w-5 rounded-full border-2\" />\n )}\n </button>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n {/* Title & menu row */}\n <div className=\"flex items-start justify-between gap-2\">\n <h4\n className={cn(\n \"text-foreground line-clamp-2 font-semibold\",\n isCompleted && \"text-muted-foreground line-through\",\n )}\n >\n {title}\n </h4>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(e) => e.stopPropagation()}\n >\n <EllipsisVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(e) => {\n e.stopPropagation();\n onDeleteClick(task);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Body text */}\n {bodyText && (\n <p\n className=\"text-muted-foreground mt-1 line-clamp-3 text-sm\"\n style={\n isCompleted ? { textDecoration: \"line-through\" } : undefined\n }\n >\n {bodyText}\n </p>\n )}\n\n {/* Due date & Timestamp */}\n <div className=\"mt-2 flex flex-row items-center gap-2\">\n <span className=\"text-muted-foreground text-xs\">{timestamp}</span>\n {task.due_at && (\n <div className=\"flex items-center gap-1\">\n <Calendar\n className={cn(\n \"h-3.5 w-3.5\",\n isCompleted ? \"text-muted-foreground\" : \"text-primary\",\n )}\n />\n <span\n className={cn(\n \"text-xs font-medium\",\n isCompleted ? \"text-muted-foreground\" : \"text-primary\",\n )}\n >\n Due {formatDueDate(task.due_at)}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport interface TaskListProps {\n tasks: ContactTask[];\n isLoading?: boolean;\n contactId: string;\n /** Hide the built-in \"Tasks (N) / Add Task\" header — used when the consumer\n * renders its own create-task affordance above the list. */\n hideHeader?: boolean;\n /** Ref that receives the openCreateModal callback for external triggering */\n ref?: React.Ref<(() => void) | null>;\n}\n\nexport function TaskList({\n tasks,\n isLoading,\n contactId,\n hideHeader = false,\n ref,\n}: TaskListProps): React.JSX.Element {\n const [taskToDelete, setTaskToDelete] = useState<ContactTask | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [editingTask, setEditingTask] = useState<ContactTask | null>(null);\n\n const toggleCompletion = useToggleTaskCompletion(contactId);\n const deleteTask = useDeleteContactTask(contactId, {\n onSuccess: () => setTaskToDelete(null),\n });\n const createTask = useCreateContactTask(contactId, {\n onSuccess: () => setModalOpen(false),\n });\n const updateTask = useUpdateContactTask(contactId, {\n onSuccess: () => setEditingTask(null),\n });\n\n const openCreateModal = () => {\n setEditingTask(null);\n setModalOpen(true);\n };\n\n // Expose openCreateModal to parent via ref\n useImperativeHandle(ref, () => openCreateModal);\n\n const handleSave = (data: {\n title: string;\n body: string;\n dueDate?: string;\n }) => {\n const taskBody = data.body ? `${data.title}\\n\\n${data.body}` : data.title;\n\n if (editingTask) {\n updateTask.mutate({\n taskId: editingTask.id,\n input: { body: taskBody, due_at: data.dueDate ?? null },\n });\n } else {\n createTask.mutate({ body: taskBody, due_at: data.dueDate ?? null });\n }\n };\n\n const editingParsed = editingTask\n ? parseTaskBody(editingTask.body ?? \"\")\n : null;\n\n const isModalOpen = modalOpen || editingTask !== null;\n const handleModalOpenChange = (open: boolean) => {\n if (!open) {\n setModalOpen(false);\n setEditingTask(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4\">\n {!hideHeader && (\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"bg-muted h-5 w-24 animate-pulse rounded\" />\n <div className=\"bg-muted mt-1 h-4 w-48 animate-pulse rounded\" />\n </div>\n <div className=\"bg-muted h-8 w-24 animate-pulse rounded-lg\" />\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"border-border bg-muted/50 h-32 animate-pulse rounded-xl border\"\n />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {!hideHeader && (\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-foreground text-base font-semibold\">\n Tasks ({tasks.length})\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-sm\">\n Manage tasks and follow-ups for this contact\n </p>\n </div>\n <button\n type=\"button\"\n onClick={openCreateModal}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add Task\n </button>\n </div>\n )}\n\n {/* Content */}\n {tasks.length === 0 ? (\n <EmptyState onCreateTask={openCreateModal} />\n ) : (\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {tasks.map((task) => (\n <TaskCard\n key={task.id}\n task={task}\n toggleCompletion={toggleCompletion}\n onEdit={setEditingTask}\n onDeleteClick={setTaskToDelete}\n />\n ))}\n </div>\n )}\n\n {/* Create/Edit modal */}\n <NoteTaskModal\n key={editingTask?.id ?? \"create\"}\n open={isModalOpen}\n onOpenChange={handleModalOpenChange}\n mode={editingTask ? \"edit\" : \"create\"}\n type=\"task\"\n initialTitle={editingParsed?.title ?? \"\"}\n initialBody={editingParsed?.body ?? \"\"}\n initialDueDate={editingTask?.due_at ?? undefined}\n showDueDate\n onSave={handleSave}\n isPending={createTask.isPending || updateTask.isPending}\n isCompleted={editingTask ? !!editingTask.completed_at : undefined}\n onToggleComplete={\n editingTask\n ? () =>\n toggleCompletion.mutate(\n {\n taskId: editingTask.id,\n isCompleted: !!editingTask.completed_at,\n },\n { onSuccess: () => setEditingTask(null) },\n )\n : undefined\n }\n isTogglePending={toggleCompletion.isPending}\n />\n\n {/* Delete confirmation modal */}\n <AlertDialog\n open={taskToDelete !== null}\n onOpenChange={(open) => {\n if (!open) setTaskToDelete(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete Task</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete this task? This action cannot be\n undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n if (taskToDelete) {\n deleteTask.mutate(taskToDelete.id);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\n\nexport function useDeleteContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: (noteId: number) => api.deleteNote(noteId, contactId),\n onSuccess: () => {\n fluidToast({ title: \"Note deleted\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to delete note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateNoteInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { CreateNoteInput };\n\nexport function useCreateContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: (input: CreateNoteInput) => api.createNote(contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Note created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to create note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useNotesApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { UpdateNoteInput } from \"@fluid-app/contacts-core/types\";\n\nexport type { UpdateNoteInput };\n\nexport function useUpdateContactNote(\n contactId: string,\n options?: { onSuccess?: () => void },\n) {\n const queryClient = useQueryClient();\n const api = useNotesApi();\n\n return useMutation({\n mutationFn: ({\n noteId,\n input,\n }: {\n noteId: number;\n input: UpdateNoteInput;\n }) => api.updateNote(noteId, contactId, input),\n onSuccess: () => {\n fluidToast({ title: \"Note updated\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: contactsKeys.notes(contactId),\n });\n options?.onSuccess?.();\n },\n onError: (error) => {\n fluidToast({\n title: \"Failed to update note\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n },\n });\n}\n","\"use client\";\n\nimport React, { useImperativeHandle, useState } from \"react\";\nimport {\n Calendar,\n Paperclip,\n Plus,\n StickyNote,\n Pen,\n EllipsisVertical,\n} from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport type { ContactNote } from \"../../hooks/notes/use-contact-notes\";\nimport { useDeleteContactNote } from \"../../hooks/notes/use-delete-contact-note\";\nimport { useCreateContactNote } from \"../../hooks/notes/use-create-contact-note\";\nimport { useUpdateContactNote } from \"../../hooks/notes/use-update-contact-note\";\nimport { NoteTaskModal } from \"../editor/note-task-modal\";\n\n// ---------------------------------------------------------------------------\n// Date helpers\n// ---------------------------------------------------------------------------\n\nfunction formatDueDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\n// ---------------------------------------------------------------------------\n// Empty state\n// ---------------------------------------------------------------------------\n\nfunction EmptyState({ onCreateNote }: { onCreateNote: () => void }) {\n return (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center\">\n <div className=\"relative mb-6\">\n <div className=\"flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-amber-100 to-yellow-100\">\n <StickyNote className=\"h-9 w-9 text-amber-500\" />\n </div>\n <div className=\"border-background absolute -right-2 -bottom-1 flex h-9 w-9 items-center justify-center rounded-full border-2 bg-gradient-to-br from-orange-100 to-red-100 shadow-sm\">\n <Pen className=\"h-4 w-4 text-orange-500\" />\n </div>\n </div>\n <h4 className=\"text-foreground text-base font-semibold\">No notes yet</h4>\n <p className=\"text-muted-foreground mt-1.5 max-w-[260px] text-sm leading-relaxed\">\n Capture key details and insights about this contact to stay on top of\n every conversation\n </p>\n <button\n type=\"button\"\n onClick={onCreateNote}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 mt-4 inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n New Note\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Note card\n// ---------------------------------------------------------------------------\n\nfunction NoteCard({\n note,\n onEdit,\n onDelete,\n}: {\n note: ContactNote;\n onEdit: (note: ContactNote) => void;\n onDelete: (note: ContactNote) => void;\n}) {\n const assetCount = note.assets?.length ?? 0;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onEdit(note)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onEdit(note);\n }\n }}\n className=\"border-border bg-card hover:border-border/80 cursor-pointer rounded-xl border p-5 transition-colors\"\n >\n {/* Title row with ellipsis menu */}\n <div className=\"flex items-start justify-between gap-2\">\n <h4 className=\"text-foreground line-clamp-1 text-sm font-semibold\">\n {note.title}\n </h4>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n onClick={(e) => e.stopPropagation()}\n className=\"text-muted-foreground inline-flex h-6 w-6 items-center justify-center rounded-md hover:opacity-70\"\n >\n <EllipsisVertical className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(note);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Body */}\n <p className=\"text-muted-foreground mt-1.5 line-clamp-4 text-sm leading-relaxed\">\n {note.body}\n </p>\n\n {/* Meta row */}\n <div className=\"mt-3 flex flex-wrap items-center gap-4\">\n {note.due_at && (\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n Due {formatDueDate(note.due_at)}\n </span>\n </div>\n )}\n {!note.due_at && note.due_date && (\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"text-primary h-3.5 w-3.5\" />\n <span className=\"text-primary text-xs font-medium\">\n Due {formatDueDate(note.due_date)}\n </span>\n </div>\n )}\n {assetCount > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <Paperclip className=\"text-muted-foreground h-3.5 w-3.5\" />\n <span className=\"text-muted-foreground text-xs\">\n {assetCount} {assetCount === 1 ? \"Attachment\" : \"Attachments\"}\n </span>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport interface NotesListProps {\n notes: ContactNote[];\n isLoading?: boolean;\n contactId: string;\n /** Ref that receives the openCreateModal callback for external triggering */\n ref?: React.Ref<(() => void) | null>;\n}\n\nexport function NotesList({\n notes,\n isLoading,\n contactId,\n ref,\n}: NotesListProps): React.JSX.Element {\n const [noteToDelete, setNoteToDelete] = useState<ContactNote | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [editingNote, setEditingNote] = useState<ContactNote | null>(null);\n\n const deleteNote = useDeleteContactNote(contactId);\n const createNote = useCreateContactNote(contactId, {\n onSuccess: () => setModalOpen(false),\n });\n const updateNote = useUpdateContactNote(contactId, {\n onSuccess: () => setEditingNote(null),\n });\n\n const openCreateModal = () => {\n setEditingNote(null);\n setModalOpen(true);\n };\n\n // Expose openCreateModal to parent via ref\n useImperativeHandle(ref, () => openCreateModal);\n\n const handleSave = (data: {\n title: string;\n body: string;\n dueDate?: string;\n }) => {\n if (editingNote) {\n updateNote.mutate({\n noteId: editingNote.id,\n input: { title: data.title, body: data.body },\n });\n } else {\n createNote.mutate({ title: data.title, body: data.body });\n }\n };\n\n const isModalOpen = modalOpen || editingNote !== null;\n const handleModalOpenChange = (open: boolean) => {\n if (!open) {\n setModalOpen(false);\n setEditingNote(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"bg-muted h-5 w-24 animate-pulse rounded\" />\n <div className=\"bg-muted mt-1 h-4 w-48 animate-pulse rounded\" />\n </div>\n <div className=\"bg-muted h-8 w-24 animate-pulse rounded-lg\" />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"border-border bg-muted/50 h-40 animate-pulse rounded-xl border\"\n />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Header */}\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-foreground text-base font-semibold\">\n Notes ({notes.length})\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-sm\">\n Capture key details and insights about this contact\n </p>\n </div>\n <button\n type=\"button\"\n onClick={openCreateModal}\n className=\"bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add Note\n </button>\n </div>\n\n {/* Content */}\n {notes.length === 0 ? (\n <EmptyState onCreateNote={openCreateModal} />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {notes.map((note) => (\n <NoteCard\n key={note.id}\n note={note}\n onEdit={setEditingNote}\n onDelete={setNoteToDelete}\n />\n ))}\n </div>\n )}\n\n {/* Create/Edit modal */}\n <NoteTaskModal\n key={editingNote?.id ?? \"create\"}\n open={isModalOpen}\n onOpenChange={handleModalOpenChange}\n mode={editingNote ? \"edit\" : \"create\"}\n type=\"note\"\n initialTitle={editingNote?.title ?? \"\"}\n initialBody={editingNote?.body ?? \"\"}\n onSave={handleSave}\n isPending={createNote.isPending || updateNote.isPending}\n />\n\n {/* Delete confirmation modal */}\n <AlertDialog\n open={!!noteToDelete}\n onOpenChange={(open) => {\n if (!open) setNoteToDelete(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete Note</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete &quot;{noteToDelete?.title}&quot;?\n This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n if (noteToDelete) {\n deleteNote.mutate(noteToDelete.id);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useMemo } from \"react\";\nimport { useFormContext, useWatch } from \"react-hook-form\";\nimport {\n cn,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@fluid-app/ui-primitives\";\n\nconst DEFAULT_COUNTRIES: { name: string; value: string }[] = [];\n\nconst statusOptions = [\n { name: \"New\", value: \"new\" },\n { name: \"Active\", value: \"active\" },\n { name: \"Inactive\", value: \"inactive\" },\n { name: \"Cold\", value: \"cold\" },\n { name: \"Lead\", value: \"lead\" },\n { name: \"Customer\", value: \"customer\" },\n];\n\ntype AvatarPickerRenderProps = {\n value: string | null;\n onChange: (url: string | null) => void;\n};\n\ntype ContactDetailsFormProps = {\n className?: string;\n countries?: { name: string; value: string }[];\n renderAvatarPicker?: (props: AvatarPickerRenderProps) => React.ReactNode;\n};\n\nexport const ContactDetailsForm: React.FC<ContactDetailsFormProps> = ({\n className,\n countries = DEFAULT_COUNTRIES,\n renderAvatarPicker,\n}) => {\n const { control, watch, setValue } = useFormContext();\n const currentStatus = useWatch({ control, name: \"status\" });\n const avatarUrl: string | null =\n (watch(\"avatar_url\") as string | null | undefined) ?? null;\n\n const effectiveStatusOptions = useMemo(() => {\n if (\n currentStatus &&\n typeof currentStatus === \"string\" &&\n !statusOptions.some((o) => o.value === currentStatus)\n ) {\n return [\n {\n name:\n currentStatus.charAt(0).toUpperCase() +\n currentStatus.slice(1).replace(/_/g, \" \"),\n value: currentStatus,\n },\n ...statusOptions,\n ];\n }\n return statusOptions;\n }, [currentStatus]);\n\n const firstInitial =\n (watch(\"first_name\") as string | null | undefined)?.[0] ?? \"\";\n const lastInitial =\n (watch(\"last_name\") as string | null | undefined)?.[0] ?? \"\";\n const initials =\n [firstInitial, lastInitial].filter(Boolean).join(\"\").toUpperCase() || \"?\";\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {renderAvatarPicker && (\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"border-border bg-background relative h-20 w-20 shrink-0 overflow-hidden rounded-full border-2\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center text-lg font-semibold\">\n {initials}\n </div>\n )}\n </div>\n {renderAvatarPicker({\n value: avatarUrl,\n onChange: (url) =>\n setValue(\"avatar_url\", url ?? \"\", { shouldDirty: true }),\n })}\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <FormField\n control={control}\n name=\"first_name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n First Name\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter first name\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"last_name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Last Name\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter last name\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"email\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Email\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter email address\"\n type=\"email\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"phone\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Phone\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter phone number\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"status\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Status\n </FormLabel>\n <Select value={field.value ?? \"\"} onValueChange={field.onChange}>\n <FormControl>\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select status\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent position=\"popper\" sideOffset={4}>\n {effectiveStatusOptions.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"address\"\n render={({ field }) => (\n <FormItem className=\"lg:col-span-2\">\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Full Address\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter street address\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"city\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n City\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter city\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"state\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n State/Province\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter state or province\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"postal_code\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Postal Code\n </FormLabel>\n <FormControl>\n <Input\n placeholder=\"Enter postal code\"\n {...field}\n value={field.value ?? \"\"}\n className=\"ring-input\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={control}\n name=\"country_code\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"font-inter text-foreground font-medium\">\n Country\n </FormLabel>\n <Select value={field.value ?? \"\"} onValueChange={field.onChange}>\n <FormControl>\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select country\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent position=\"popper\" sideOffset={4}>\n {countries.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />\n </div>\n </div>\n );\n};\n","\"use client\";\n\nimport React, { useRef, useState } from \"react\";\nimport { ArrowLeft, Plus } from \"lucide-react\";\nimport {\n Button,\n Card,\n CardContent,\n cn,\n Spinner,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { TaskList } from \"../../tasks/task-list\";\nimport { NotesList } from \"../../notes/notes-list\";\nimport { ContactDetailsForm } from \"../../../../shared/components/contacts/contactDetailsForm\";\nimport type { ContactTask } from \"../../../hooks/contacts/use-contact-tasks\";\nimport type { ContactNote } from \"../../../hooks/notes/use-contact-notes\";\n\nconst VISIBLE_TABS = [\"Tasks\", \"Notes\", \"Profile\"] as const;\ntype TabType = (typeof VISIBLE_TABS)[number];\n\nconst NON_PROFILE_TABS = VISIBLE_TABS.filter(\n (t): t is Exclude<TabType, \"Profile\"> => t !== \"Profile\",\n);\n\nexport interface ContactDetailTabsProps {\n contactId: string;\n contactName: string;\n countryOptions: { name: string; value: string }[];\n isDirty: boolean;\n isSubmitting: boolean;\n onSave: () => void;\n tasks: ContactTask[];\n isLoadingTasks: boolean;\n notes: ContactNote[];\n isLoadingNotes: boolean;\n}\n\nexport function ContactDetailTabs({\n contactId,\n contactName,\n countryOptions,\n isDirty,\n isSubmitting,\n onSave,\n tasks,\n isLoadingTasks,\n notes,\n isLoadingNotes,\n}: ContactDetailTabsProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [activeTab, setActiveTab] = useState<TabType>(\"Tasks\");\n\n const tabLabels: Record<TabType, string> = {\n Tasks: t(\"tab_tasks\"),\n Notes: t(\"tab_notes\"),\n Profile: t(\"edit_profile\"),\n };\n\n const openTaskModalRef = useRef<(() => void) | null>(null);\n\n const isEditingProfile = activeTab === \"Profile\";\n\n return (\n <div className=\"mt-8\">\n {isEditingProfile ? (\n <div className=\"border-border flex flex-col gap-3 border-b sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:gap-x-4 sm:gap-y-2\">\n <div className=\"flex min-w-0 items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"Tasks\")}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground hidden size-9 shrink-0 items-center justify-center rounded-md transition-colors sm:flex\"\n aria-label={t(\"back_to_tasks\")}\n >\n <ArrowLeft className=\"size-4\" />\n </button>\n <span className=\"border-foreground text-foreground -mb-px border-b-2 py-3 text-sm font-medium\">\n {t(\"editing_name\", { name: contactName })}\n </span>\n </div>\n <div className=\"flex w-full flex-col gap-2 sm:w-auto sm:shrink-0 sm:flex-row sm:items-center sm:gap-3\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => setActiveTab(\"Tasks\")}\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {t(\"cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={onSave}\n disabled={!isDirty || isSubmitting}\n aria-busy={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting && <Spinner className=\"size-4\" />}\n {isSubmitting ? t(\"saving\") : t(\"update_contact\")}\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"border-border flex items-center gap-1 border-b\">\n {NON_PROFILE_TABS.map((tab) => {\n const count = tab === \"Tasks\" ? tasks.length : notes.length;\n const isActive = activeTab === tab;\n return (\n <button\n key={tab}\n type=\"button\"\n onClick={() => setActiveTab(tab)}\n className={cn(\n \"relative flex items-center gap-1.5 px-3 py-2.5 text-sm font-semibold transition-colors\",\n isActive\n ? \"text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n {tabLabels[tab]}\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs leading-5 font-bold\",\n isActive\n ? \"bg-foreground text-background\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n {isActive && (\n <span\n className=\"bg-foreground absolute inset-x-0 -bottom-px h-0.5\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"Profile\")}\n className=\"text-muted-foreground hover:text-foreground ml-auto px-3 py-2.5 text-sm font-semibold transition-colors\"\n >\n {t(\"edit_profile\")}\n </button>\n </div>\n )}\n\n <div className=\"pt-6\">\n {activeTab === \"Tasks\" && (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => openTaskModalRef.current?.()}\n className=\"border-border text-muted-foreground hover:border-foreground/30 hover:bg-muted/40 hover:text-foreground flex w-full items-center gap-3 rounded-xl border border-dashed px-5 py-4 text-sm font-medium transition-colors\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {t(\"new_task\")}\n </button>\n <TaskList\n tasks={tasks}\n isLoading={isLoadingTasks}\n contactId={contactId}\n hideHeader\n ref={openTaskModalRef}\n />\n </div>\n )}\n\n {activeTab === \"Notes\" && (\n <NotesList\n notes={notes}\n isLoading={isLoadingNotes}\n contactId={contactId}\n />\n )}\n\n {activeTab === \"Profile\" && (\n <Card>\n <CardContent>\n <p className=\"text-muted-foreground mb-6 text-sm\">\n {t(\"profile_edit_description\")}\n </p>\n <ContactDetailsForm countries={countryOptions} />\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useCallback, useState } from \"react\";\nimport { FormProvider } from \"react-hook-form\";\nimport { ChevronLeft, Mail, MoreHorizontal, Phone, Trash2 } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { useContactDetailPage } from \"../../../../shared/hooks/useContactDetailPage\";\nimport { useContactTasks } from \"../../../hooks/contacts/use-contact-tasks\";\nimport { useContactNotes } from \"../../../hooks/notes/use-contact-notes\";\nimport { ContactDetailHero } from \"./ContactDetailHero\";\nimport { ContactInfoRow } from \"./ContactInfoRow\";\nimport { ContactDetailTabs } from \"./ContactDetailTabs\";\nimport { getDisplayName } from \"./utils\";\n\nexport interface ContactDetailPaneProps {\n contactId: string;\n queryKeyPrefix: string;\n getCountries: () => Promise<{ id: number; name: string; iso?: string }[]>;\n /** Callback to clear selection (used by mobile back button + on delete). */\n onBack: () => void;\n}\n\nexport function ContactDetailPane({\n contactId,\n queryKeyPrefix,\n getCountries,\n onBack,\n}: ContactDetailPaneProps): React.JSX.Element {\n const {\n contact,\n isLoading,\n methods,\n countryOptions,\n isDirty,\n isSubmitting,\n isDeleting,\n onSave,\n onDelete,\n } = useContactDetailPage(contactId, {\n queryKeyPrefix,\n getCountries,\n onDeleteSuccess: onBack,\n });\n\n const { data: tasks = [], isLoading: isLoadingTasks } =\n useContactTasks(contactId);\n const { data: notes = [], isLoading: isLoadingNotes } =\n useContactNotes(contactId);\n\n const { t } = useContactsTranslation();\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n // Close the dialog before dispatching: on success the pane unmounts via\n // onDeleteSuccess; on a non-throwing failure the dialog would otherwise\n // dangle open with the toast already shown.\n const handleConfirmDelete = useCallback(() => {\n setConfirmDelete(false);\n onDelete();\n }, [onDelete]);\n\n if (isLoading) {\n return <ContactDetailSkeleton onBack={onBack} />;\n }\n\n if (!contact) {\n return (\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar\n onBack={onBack}\n phone={null}\n email={null}\n onDelete={null}\n />\n <div className=\"mx-auto flex max-w-md flex-col items-center px-6 py-16 text-center\">\n <h2 className=\"text-foreground text-base font-semibold\">\n {t(\"error_loading\")}\n </h2>\n <p className=\"text-muted-foreground mt-2 text-sm\">\n {t(\"error_loading_description\")}\n </p>\n </div>\n </div>\n );\n }\n\n const fullName = getDisplayName(contact);\n\n return (\n <FormProvider {...methods}>\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar\n onBack={onBack}\n phone={contact.phone ?? null}\n email={contact.email ?? null}\n onDelete={() => setConfirmDelete(true)}\n />\n\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto w-full max-w-[900px] px-6 pt-8 pb-16 md:px-8 md:pt-10\">\n <ContactDetailHero\n contact={contact}\n tasksCount={tasks.length}\n notesCount={notes.length}\n />\n <ContactInfoRow contact={contact} />\n <ContactDetailTabs\n contactId={contactId}\n contactName={fullName}\n countryOptions={countryOptions}\n isDirty={isDirty}\n isSubmitting={isSubmitting}\n onSave={onSave}\n tasks={tasks}\n isLoadingTasks={isLoadingTasks}\n notes={notes}\n isLoadingNotes={isLoadingNotes}\n />\n </div>\n </div>\n\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t(\"delete_name\", { name: fullName })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\"delete_confirm_permanent\")}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isDeleting}>\n {t(\"cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={handleConfirmDelete}\n disabled={isDeleting}\n >\n {isDeleting ? t(\"deleting\") : t(\"delete_contact\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </FormProvider>\n );\n}\n\ninterface DetailTopBarProps {\n onBack: () => void;\n phone: string | null;\n email: string | null;\n onDelete: (() => void) | null;\n}\n\nfunction DetailTopBar({ onBack, phone, email, onDelete }: DetailTopBarProps) {\n const { t } = useContactsTranslation();\n return (\n <div className=\"border-border bg-background/90 sticky top-0 z-10 flex items-center justify-between border-b px-4 py-3 backdrop-blur md:px-8\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onBack}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex size-8 items-center justify-center rounded-full transition-colors md:hidden\"\n aria-label={t(\"back_to_contacts\")}\n >\n <ChevronLeft className=\"size-4\" />\n </button>\n <span className=\"text-muted-foreground hidden text-xs font-semibold tracking-widest uppercase md:inline\">\n {t(\"contact_label\")}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <ActionLink\n href={phone ? `tel:${phone}` : null}\n label={t(\"label_call\")}\n icon={<Phone className=\"size-4\" aria-hidden=\"true\" />}\n />\n <ActionLink\n href={email ? `mailto:${email}` : null}\n label={t(\"label_email\")}\n icon={<Mail className=\"size-4\" aria-hidden=\"true\" />}\n />\n {onDelete && (\n <>\n <div className=\"bg-border mx-1 h-5 w-px\" aria-hidden=\"true\" />\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex size-8 items-center justify-center rounded-full transition-colors\"\n aria-label={t(\"more_actions\")}\n >\n <MoreHorizontal className=\"size-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={onDelete}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {t(\"delete_contact\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n )}\n </div>\n </div>\n );\n}\n\ninterface ActionLinkProps {\n href: string | null;\n label: string;\n icon: React.ReactNode;\n}\n\nfunction ActionLink({ href, label, icon }: ActionLinkProps) {\n const baseClass =\n \"flex size-8 items-center justify-center rounded-full transition-colors\";\n if (!href) {\n return (\n <span\n aria-label={`${label} (unavailable)`}\n className={cn(baseClass, \"text-muted-foreground/40 cursor-default\")}\n >\n {icon}\n </span>\n );\n }\n return (\n <a\n href={href}\n aria-label={label}\n className={cn(\n baseClass,\n \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n )}\n >\n {icon}\n </a>\n );\n}\n\nfunction ContactDetailSkeleton({ onBack }: { onBack: () => void }) {\n return (\n <div className=\"flex h-full flex-1 flex-col\">\n <DetailTopBar onBack={onBack} phone={null} email={null} onDelete={null} />\n <div className=\"mx-auto w-full max-w-[900px] flex-1 space-y-6 px-6 pt-8 pb-16 md:px-8 md:pt-10\">\n <div className=\"flex items-start gap-5\">\n <div className=\"bg-muted size-20 animate-pulse rounded-xl\" />\n <div className=\"flex-1 space-y-3\">\n <div className=\"bg-muted h-7 w-48 animate-pulse rounded\" />\n <div className=\"bg-muted h-4 w-24 animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"bg-muted h-24 animate-pulse rounded-xl\" />\n <div className=\"bg-muted h-64 animate-pulse rounded-xl\" />\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { Users } from \"lucide-react\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport function ContactsEmptyState(): React.JSX.Element {\n const { t } = useContactsTranslation();\n return (\n <div className=\"hidden h-full flex-1 flex-col items-center justify-center px-8 text-center md:flex\">\n <div className=\"bg-muted text-muted-foreground flex size-16 items-center justify-center rounded-xl\">\n <Users className=\"size-7\" aria-hidden=\"true\" />\n </div>\n <h2 className=\"text-foreground mt-5 text-base font-semibold\">\n {t(\"empty_select_contact\")}\n </h2>\n <p className=\"text-muted-foreground mt-1 max-w-xs text-sm\">\n {t(\"empty_select_description\")}\n </p>\n </div>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@fluid-app/ui-primitives\";\nimport { ContactsSidebar } from \"./ContactsSidebar\";\nimport { ContactDetailPane } from \"./ContactDetailPane\";\nimport { ContactsEmptyState } from \"./ContactsEmptyState\";\n\nexport interface RepContactsLayoutProps {\n selectedContactId: string | null;\n onSelect: (id: string | null) => void;\n onAdd: () => void;\n queryKeyPrefix: string;\n getCountries: () => Promise<{ id: number; name: string; iso?: string }[]>;\n}\n\nexport function RepContactsLayout({\n selectedContactId,\n onSelect,\n onAdd,\n queryKeyPrefix,\n getCountries,\n}: RepContactsLayoutProps): React.JSX.Element {\n return (\n <div className=\"bg-background flex h-full overflow-hidden\">\n <aside\n className={cn(\n \"border-border bg-background w-full shrink-0 overflow-hidden border-r md:flex md:w-[420px] md:flex-col\",\n selectedContactId ? \"hidden\" : \"flex flex-col\",\n )}\n >\n <ContactsSidebar\n selectedContactId={selectedContactId}\n onSelect={onSelect}\n onAdd={onAdd}\n />\n </aside>\n\n <main\n className={cn(\n \"bg-background relative flex-1 md:flex md:flex-col\",\n selectedContactId ? \"flex flex-col\" : \"hidden md:flex\",\n )}\n >\n {selectedContactId ? (\n <ContactDetailPane\n key={selectedContactId}\n contactId={selectedContactId}\n queryKeyPrefix={queryKeyPrefix}\n getCountries={getCountries}\n onBack={() => onSelect(null)}\n />\n ) : (\n <ContactsEmptyState />\n )}\n </main>\n </div>\n );\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { parseApiErrors } from \"@fluid-app/api-client-core\";\nimport { useContactsCrud } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { CONTACTS_QUERY_KEYS } from \"@fluid-app/contacts-core/query-keys\";\nimport type { CreateContactFormData } from \"../schemas/contactFormSchema\";\n\nexport function useCreateContactMutation(\n queryKeyPrefix = \"contacts\",\n options?: {\n onSuccess?: (data: { contact: { id: number } }) => void;\n onError?: (error: unknown) => void;\n },\n) {\n const queryClient = useQueryClient();\n const api = useContactsCrud();\n\n return useMutation({\n mutationFn: (data: CreateContactFormData) =>\n api.createContact(data as unknown as Record<string, unknown>),\n onSuccess: (data) => {\n fluidToast({ title: \"Contact created successfully\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: CONTACTS_QUERY_KEYS.all(queryKeyPrefix),\n });\n options?.onSuccess?.(data as unknown as { contact: { id: number } });\n },\n onError: (error) => {\n if (options?.onError) {\n options.onError(error);\n } else {\n fluidToast({\n title: \"Failed to create contact\",\n type: \"error\",\n description: parseApiErrors(error),\n });\n }\n },\n });\n}\n","/**\n * Generated API client functions for portal_tenant_contacts\n *\n * DO NOT EDIT THIS FILE DIRECTLY\n * This file is auto-generated. To update:\n * 1. Update the OpenAPI spec file\n * 2. Run: pnpm generate\n */\n\nimport type { FetchClient } from \"../lib/fetch-client\";\nimport type { operations } from \"../generated/portal-tenant-contacts\";\n\n// ============================================================================\n// contacts\n// ============================================================================\n\n/**\n * List contacts with cursor pagination\n * Returns a paginated list of contacts belonging to the authenticated member.\n *\n * @param client - Fetch client instance\n * @param [params] - params\n */\nexport async function contacts_list(\n client: FetchClient,\n params?: operations[\"contacts_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts`, params);\n}\n\n/**\n * Create a new contact\n * Creates a new contact for the authenticated member.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_create(\n client: FetchClient,\n body: operations[\"contacts_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts`, body);\n}\n\n/**\n * Get a specific contact\n * Returns a single contact by ID.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_show(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_show\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${id}`);\n}\n\n/**\n * Update a contact\n * Updates an existing contact's attributes.\n *\n * @param client - Fetch client instance\n * @param id - id\n * @param body - body\n */\nexport async function contacts_update(\n client: FetchClient,\n id: string | number,\n body: operations[\"contacts_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${id}`, body);\n}\n\n/**\n * Delete a contact\n * Soft-deletes a contact by ID.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_destroy(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${id}`);\n}\n\n/**\n * Delete multiple contacts\n * Soft-deletes multiple contacts by their IDs.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_bulk_destroy(\n client: FetchClient,\n body: operations[\"contacts_bulk_destroy\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_bulk_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/bulk`, { body });\n}\n\n/**\n * List contact groups\n * Returns a paginated list of contact groups belonging to the authenticated member.\n *\n * @param client - Fetch client instance\n * @param [params] - params\n */\nexport async function contacts_groups_list(\n client: FetchClient,\n params?: operations[\"contacts_groups_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_groups_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/groups`, params);\n}\n\n/**\n * Create a new group\n * Creates a new contact group for the authenticated member.\n *\n * @param client - Fetch client instance\n * @param body - body\n */\nexport async function contacts_groups_create(\n client: FetchClient,\n body: operations[\"contacts_groups_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_groups_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/groups`, body);\n}\n\n/**\n * Update a group\n * Updates an existing contact group.\n *\n * @param client - Fetch client instance\n * @param id - id\n * @param body - body\n */\nexport async function contacts_groups_update(\n client: FetchClient,\n id: string | number,\n body: operations[\"contacts_groups_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_groups_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/groups/${id}`, body);\n}\n\n/**\n * Delete a group\n * Removes a contact group.\n *\n * @param client - Fetch client instance\n * @param id - id\n */\nexport async function contacts_groups_destroy(\n client: FetchClient,\n id: string | number,\n): Promise<\n operations[\"contacts_groups_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/groups/${id}`);\n}\n\n/**\n * List notes for a contact\n * Returns notes attached to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param [params] - params\n */\nexport async function contacts_notes_list(\n client: FetchClient,\n contact_id: string | number,\n params?: operations[\"contacts_notes_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_notes_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${contact_id}/notes`, params);\n}\n\n/**\n * Create a note for a contact\n * Adds a new note to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param body - body\n */\nexport async function contacts_notes_create(\n client: FetchClient,\n contact_id: string | number,\n body: operations[\"contacts_notes_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_notes_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/${contact_id}/notes`, body);\n}\n\n/**\n * List tasks for a contact\n * Returns tasks assigned to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param [params] - params\n */\nexport async function contacts_tasks_list(\n client: FetchClient,\n contact_id: string | number,\n params?: operations[\"contacts_tasks_list\"][\"parameters\"][\"query\"],\n): Promise<\n operations[\"contacts_tasks_list\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.get(`/api/contacts/${contact_id}/tasks`, params);\n}\n\n/**\n * Create a task for a contact\n * Adds a new task to a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param body - body\n */\nexport async function contacts_tasks_create(\n client: FetchClient,\n contact_id: string | number,\n body: operations[\"contacts_tasks_create\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_tasks_create\"][\"responses\"][201][\"content\"][\"application/json\"]\n> {\n return client.post(`/api/contacts/${contact_id}/tasks`, body);\n}\n\n/**\n * Update a note\n * Updates an existing note on a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n * @param body - body\n */\nexport async function contacts_notes_update(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n body: operations[\"contacts_notes_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_notes_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${contact_id}/notes/${id}`, body);\n}\n\n/**\n * Delete a note\n * Removes a note from a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n */\nexport async function contacts_notes_destroy(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n): Promise<\n operations[\"contacts_notes_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${contact_id}/notes/${id}`);\n}\n\n/**\n * Update a task\n * Updates an existing task on a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n * @param body - body\n */\nexport async function contacts_tasks_update(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n body: operations[\"contacts_tasks_update\"][\"requestBody\"][\"content\"][\"application/json\"],\n): Promise<\n operations[\"contacts_tasks_update\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.patch(`/api/contacts/${contact_id}/tasks/${id}`, body);\n}\n\n/**\n * Delete a task\n * Removes a task from a contact.\n *\n * @param client - Fetch client instance\n * @param contact_id - contact_id\n * @param id - id\n */\nexport async function contacts_tasks_destroy(\n client: FetchClient,\n contact_id: string | number,\n id: string | number,\n): Promise<\n operations[\"contacts_tasks_destroy\"][\"responses\"][200][\"content\"][\"application/json\"]\n> {\n return client.delete(`/api/contacts/${contact_id}/tasks/${id}`);\n}\n","/**\n * Portal Contacts Adapter — Implements ContactsDomainApi using the\n * portal-tenant Contacts BFF endpoints.\n *\n * The existing contacts-ui hooks and components expect the ContactsApi,\n * NotesApi, and TasksApi interfaces from @fluid-app/contacts-core. This\n * adapter translates between the BFF response shapes and the core types\n * so the UI layer works unchanged.\n *\n * Features not available in the BFF (activities, markRead, orders,\n * subscriptionOrders) are omitted — the optional interface lets the\n * UI layer gracefully disable those capabilities.\n */\n\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport type { ContactsApi } from \"@fluid-app/contacts-core/contacts-api\";\nimport type { NotesApi } from \"@fluid-app/contacts-core/notes-api\";\nimport type { TasksApi } from \"@fluid-app/contacts-core/tasks-api\";\nimport type { GroupsApi } from \"@fluid-app/contacts-core/groups-api\";\nimport type { ContactsDomainApi } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport type {\n Contact,\n ContactGroup,\n ContactNote,\n ContactTask,\n PaginationMeta,\n} from \"@fluid-app/contacts-core/types\";\nimport { portalTenantContacts } from \"@fluid-app/portal-tenant-contacts-api-client\";\n\n// ---------------------------------------------------------------------------\n// Response mappers — BFF shapes → core shapes\n// ---------------------------------------------------------------------------\n\nconst EMPTY_META: PaginationMeta = {\n total_count: 0,\n total_pages: 0,\n current_page: 1,\n next_cursor: null,\n};\n\nfunction paginationFromBff(\n meta: Record<string, unknown> | undefined,\n itemCount: number,\n currentPage: number,\n pageSize: number,\n): PaginationMeta {\n if (!meta) return EMPTY_META;\n const pagination = meta.pagination as Record<string, unknown> | undefined;\n const nextCursor = (pagination?.next_cursor as string | null) ?? null;\n const hasNext = !!nextCursor;\n\n const realTotal = meta.total_count as number | undefined;\n const totalCount =\n realTotal ??\n (hasNext\n ? (currentPage + 1) * pageSize\n : (currentPage - 1) * pageSize + itemCount);\n\n return {\n total_count: totalCount,\n total_pages: Math.max(1, Math.ceil(totalCount / pageSize)),\n current_page: currentPage,\n next_cursor: nextCursor,\n request_id: (meta.request_id as string) ?? undefined,\n timestamp: (meta.timestamp as string) ?? undefined,\n };\n}\n\n/** BFF Contact → core Contact. Fills missing fields with safe defaults. */\nfunction mapContact(raw: Record<string, unknown>): Contact {\n return {\n id: raw.id as number,\n full_name: `${raw.first_name ?? \"\"} ${raw.last_name ?? \"\"}`.trim(),\n first_name: (raw.first_name as string) ?? null,\n last_name: (raw.last_name as string) ?? null,\n email: (raw.email as string) ?? null,\n phone: (raw.phone as string) ?? null,\n status: (raw.status as string) ?? null,\n address: (raw.address as string) ?? null,\n city: (raw.city as string) ?? null,\n state: (raw.state as string) ?? null,\n postal_code: (raw.postal_code as string) ?? null,\n avatar_url: (raw.avatar_url as string) ?? null,\n country: (raw.country as Contact[\"country\"]) ?? null,\n tags: (raw.tags as string[]) ?? [],\n metadata: {},\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n } as Contact;\n}\n\n/** BFF Note → core ContactNote. */\nfunction mapNote(raw: Record<string, unknown>): ContactNote {\n return {\n id: raw.id as number,\n title: (raw.title as string) ?? \"\",\n body: (raw.body as string) ?? \"\",\n note_type: null,\n due_date: null,\n due_time: null,\n pinned: null,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n contact_id: (raw.contact_id as number) ?? 0,\n assets: [],\n };\n}\n\n/** BFF Task → core ContactTask. */\nfunction mapTask(raw: Record<string, unknown>): ContactTask {\n return {\n id: raw.id as number,\n body: (raw.title as string) ?? \"\",\n due_at: (raw.due_date as string) ?? null,\n completed_at:\n (raw.completed_at as string) ??\n (raw.completed ? new Date().toISOString() : null),\n created_at: raw.created_at as string,\n contact_id: (raw.contact_id as number) ?? null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Param mappers — old offset-based params → BFF cursor-based params\n// ---------------------------------------------------------------------------\n\n/**\n * The contacts-ui sends offset pagination params (page, per_page, sort_by,\n * sort_direction, search, status). The BFF expects cursor pagination\n * (page[cursor], page[limit], search, tags). Translate between the two.\n *\n * `cursorCache` maps page numbers → cursor tokens so page-2+ requests can\n * resolve to the correct cursor. The cache is populated from BFF responses.\n */\nfunction mapListParams(\n params: Record<string, unknown> | undefined,\n cursorCache: Map<number, string>,\n): Parameters<typeof portalTenantContacts.contacts_list>[1] {\n if (!params) return undefined;\n\n const mapped: Record<string, unknown> = {};\n\n if (params.per_page || params.limit) {\n mapped[\"page[limit]\"] = params.per_page ?? params.limit;\n }\n\n // Translate offset page number → cursor token\n const page = (params.page as number) ?? 1;\n if (page > 1) {\n const cursor = cursorCache.get(page);\n if (cursor) {\n mapped[\"page[cursor]\"] = cursor;\n }\n }\n\n if (params.search_query || params.search || params.query) {\n mapped.search = params.search_query ?? params.search ?? params.query;\n }\n if (params.tags) {\n mapped.tags = params.tags;\n }\n\n return mapped as Parameters<typeof portalTenantContacts.contacts_list>[1];\n}\n\n// ---------------------------------------------------------------------------\n// Adapter factories\n// ---------------------------------------------------------------------------\n\nfunction createContactsAdapter(client: FetchClient): ContactsApi {\n // Cursor cache: maps page numbers → cursor tokens from BFF responses.\n // Page 1 has no cursor; the BFF response for page N includes\n // next_cursor which becomes the cursor for page N+1.\n const cursorCache = new Map<number, string>();\n\n return {\n getContact: async (id) => {\n const response = await portalTenantContacts.contacts_show(client, id);\n return {\n contact: mapContact(\n (response as Record<string, unknown>).contact as Record<\n string,\n unknown\n >,\n ),\n };\n },\n\n listContacts: async (params) => {\n const raw = params as Record<string, unknown> | undefined;\n const page = (raw?.page as number) ?? 1;\n const pageSize = (raw?.per_page as number) ?? 25;\n\n const response = await portalTenantContacts.contacts_list(\n client,\n mapListParams(raw, cursorCache),\n );\n const body = response as Record<string, unknown>;\n const meta = body.meta as Record<string, unknown> | undefined;\n const pagination = meta?.pagination as\n | Record<string, unknown>\n | undefined;\n\n // Store the next_cursor so the UI can request page + 1\n const nextCursor = pagination?.next_cursor as string | null | undefined;\n if (nextCursor) {\n cursorCache.set(page + 1, nextCursor);\n }\n\n const contacts = ((body.contacts as Record<string, unknown>[]) ?? []).map(\n mapContact,\n );\n return {\n contacts,\n meta: paginationFromBff(meta, contacts.length, page, pageSize),\n };\n },\n\n createContact: async (data) => {\n return portalTenantContacts.contacts_create(client, {\n contact: data,\n } as Parameters<typeof portalTenantContacts.contacts_create>[1]);\n },\n\n updateContact: async (id, data) => {\n return portalTenantContacts.contacts_update(client, id, {\n contact: data,\n } as Parameters<typeof portalTenantContacts.contacts_update>[2]);\n },\n\n deleteContact: async (id) => {\n return portalTenantContacts.contacts_destroy(client, id);\n },\n\n bulkDeleteContacts: async (ids) => {\n return portalTenantContacts.contacts_bulk_destroy(client, { ids });\n },\n\n // listActivities, markRead, listOrders, listSubscriptionOrders are not\n // available through the BFF — omitted so the UI disables these features.\n };\n}\n\nfunction createNotesAdapter(client: FetchClient): NotesApi {\n return {\n listNotes: async (contactId) => {\n const response = await portalTenantContacts.contacts_notes_list(\n client,\n contactId,\n );\n const body = response as Record<string, unknown>;\n return {\n notes: ((body.notes as Record<string, unknown>[]) ?? []).map(mapNote),\n };\n },\n\n createNote: async (contactId, input) => {\n return portalTenantContacts.contacts_notes_create(client, contactId, {\n note: input,\n } as Parameters<typeof portalTenantContacts.contacts_notes_create>[2]);\n },\n\n updateNote: async (noteId, contactId, input) => {\n return portalTenantContacts.contacts_notes_update(\n client,\n contactId,\n noteId,\n {\n note: input,\n } as Parameters<typeof portalTenantContacts.contacts_notes_update>[3],\n );\n },\n\n deleteNote: async (noteId, contactId) => {\n return portalTenantContacts.contacts_notes_destroy(\n client,\n contactId,\n noteId,\n );\n },\n };\n}\n\nfunction createTasksAdapter(client: FetchClient): TasksApi {\n return {\n listTasks: async (contactId) => {\n const response = await portalTenantContacts.contacts_tasks_list(\n client,\n contactId,\n );\n const body = response as Record<string, unknown>;\n return {\n tasks: ((body.tasks as Record<string, unknown>[]) ?? []).map(mapTask),\n };\n },\n\n createTask: async (contactId, input) => {\n return portalTenantContacts.contacts_tasks_create(client, contactId, {\n task: { title: input.body, due_date: input.due_at },\n } as Parameters<typeof portalTenantContacts.contacts_tasks_create>[2]);\n },\n\n updateTask: async (taskId, contactId, input) => {\n return portalTenantContacts.contacts_tasks_update(\n client,\n contactId,\n taskId,\n {\n task: {\n title: input.body ?? undefined,\n completed:\n input.completed_at !== undefined\n ? input.completed_at !== null\n : undefined,\n due_date: input.due_at,\n },\n } as Parameters<typeof portalTenantContacts.contacts_tasks_update>[3],\n );\n },\n\n deleteTask: async (taskId, contactId) => {\n return portalTenantContacts.contacts_tasks_destroy(\n client,\n contactId,\n taskId,\n );\n },\n };\n}\n\n/** BFF Group → core ContactGroup. */\nfunction mapGroup(raw: Record<string, unknown>): ContactGroup {\n return {\n id: raw.id as number,\n name: (raw.name as string) ?? \"\",\n avatar: (raw.avatar as string) ?? null,\n avatar_background: (raw.avatar_background as string) ?? null,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n };\n}\n\nfunction createGroupsAdapter(client: FetchClient): GroupsApi {\n return {\n listGroups: async () => {\n const response = await portalTenantContacts.contacts_groups_list(client);\n const body = response as Record<string, unknown>;\n return {\n groups: ((body.groups as Record<string, unknown>[]) ?? []).map(\n mapGroup,\n ),\n };\n },\n\n createGroup: async (input) => {\n const response = await portalTenantContacts.contacts_groups_create(\n client,\n {\n group: input,\n } as Parameters<typeof portalTenantContacts.contacts_groups_create>[1],\n );\n const body = response as Record<string, unknown>;\n return {\n group: mapGroup(body.group as Record<string, unknown>),\n };\n },\n\n updateGroup: async (groupId, input) => {\n const response = await portalTenantContacts.contacts_groups_update(\n client,\n groupId,\n {\n group: input,\n } as Parameters<typeof portalTenantContacts.contacts_groups_update>[2],\n );\n const body = response as Record<string, unknown>;\n return {\n group: mapGroup(body.group as Record<string, unknown>),\n };\n },\n\n deleteGroup: async (groupId) => {\n return portalTenantContacts.contacts_groups_destroy(client, groupId);\n },\n };\n}\n\n/**\n * Creates a composite ContactsDomainApi backed by the portal-tenant\n * Contacts BFF endpoints.\n */\nexport function createPortalContactsDomainApiAdapter(\n client: FetchClient,\n): ContactsDomainApi {\n return {\n contacts: createContactsAdapter(client),\n notes: createNotesAdapter(client),\n tasks: createTasksAdapter(client),\n groups: createGroupsAdapter(client),\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { ContactsApiProvider } from \"@fluid-app/contacts-core/contacts-api-context\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalContactsDomainApiAdapter } from \"../adapters/contacts-api-adapter\";\n\nexport function PortalContactsApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(\n () => createPortalContactsDomainApiAdapter(client),\n [client],\n );\n\n return <ContactsApiProvider value={api}>{children}</ContactsApiProvider>;\n}\n","export const contactsEn = {\n breadcrumb: \"Contacts\",\n breadcrumb_new: \"New Contact\",\n contact_label: \"Contact\",\n add: \"Add\",\n add_contact: \"Add Contact\",\n adding: \"Adding...\",\n update_contact: \"Update Contact\",\n saving: \"Saving\",\n cancel: \"Cancel\",\n save: \"Save\",\n delete: \"Delete\",\n delete_name: \"Delete {{name}}?\",\n delete_confirm_permanent:\n \"This permanently removes the contact and all of their notes, tasks, and activity. This can't be undone.\",\n delete_contact: \"Delete contact\",\n deleting: \"Deleting...\",\n search_placeholder: \"Search contacts\",\n error_loading: \"Couldn't load contact\",\n error_loading_description:\n \"This contact may have been deleted, you may not have permission to view it, or there was a network error. Try selecting them again.\",\n error_loading_list: \"Couldn't load contacts. Pull down to retry.\",\n error_generic: \"Something went wrong. Please try again later.\",\n loading: \"Loading...\",\n loading_more: \"Loading more...\",\n searching: \"Searching...\",\n people_count: \"{{count}} people across your network\",\n person_count: \"{{count}} person across your network\",\n no_contacts_search: 'No contacts match \"{{term}}\".',\n no_contacts_yet: \"No contacts yet.\",\n no_contacts_filter: \"No contacts match this filter.\",\n empty_select_contact: \"Select a contact\",\n empty_select_description:\n \"Pick someone from your list on the left to see their details, notes, and tasks.\",\n tab_tasks: \"Tasks\",\n tab_notes: \"Notes\",\n edit_profile: \"Edit profile\",\n editing_name: \"Editing {{name}}\",\n profile_edit_description:\n \"Update details below. Your contact card above is paused while you edit.\",\n new_task: \"New task\",\n last_updated: \"Last updated {{date}}\",\n label_email: \"Email\",\n label_phone: \"Phone\",\n label_address: \"Address\",\n label_call: \"Call\",\n not_set: \"Not set\",\n more_actions: \"More actions\",\n back_to_contacts: \"Back to contacts\",\n back_to_tasks: \"Back to Tasks\",\n filter_all: \"All\",\n filter_leads: \"Leads\",\n filter_customers: \"Customers\",\n} as const satisfies Record<string, string>;\n\nexport type ContactsDict = typeof contactsEn;\n","import {\n createDomainTranslations,\n type DomainTranslations,\n} from \"@fluid-app/i18n/translations\";\nimport { createStaticDictAdapter } from \"@fluid-app/i18n/static-dict-adapter\";\nimport type { TranslationApi } from \"@fluid-app/i18n/translation-api\";\nimport { contactsEn, type ContactsDict } from \"./translation-dictionary\";\n\nexport const contactsDomain: DomainTranslations<ContactsDict> =\n createDomainTranslations<ContactsDict>({\n fallback: contactsEn,\n loaders: {\n de: () =>\n import(\"./locale/de.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n el: () =>\n import(\"./locale/el.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n es: () =>\n import(\"./locale/es.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n fr: () =>\n import(\"./locale/fr.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n he: () =>\n import(\"./locale/he.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n hu: () =>\n import(\"./locale/hu.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n id: () =>\n import(\"./locale/id.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n it: () =>\n import(\"./locale/it.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ja: () =>\n import(\"./locale/ja.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ko: () =>\n import(\"./locale/ko.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n nl: () =>\n import(\"./locale/nl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n pl: () =>\n import(\"./locale/pl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n pt: () =>\n import(\"./locale/pt.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ro: () =>\n import(\"./locale/ro.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n ru: () =>\n import(\"./locale/ru.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n th: () =>\n import(\"./locale/th.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n tl: () =>\n import(\"./locale/tl.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n tr: () =>\n import(\"./locale/tr.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n zh_CN: () =>\n import(\"./locale/zh_CN.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n zh_TW: () =>\n import(\"./locale/zh_TW.json\").then(\n (m): ContactsDict => m.default as ContactsDict,\n ),\n },\n });\n\nexport function createContactsTranslationAdapter(\n locale: string,\n dict: ContactsDict,\n): TranslationApi<ContactsDict> {\n return createStaticDictAdapter(locale, dict);\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport { useActiveLocale } from \"@fluid-app/i18n/locale-context\";\nimport { useDomainDict } from \"@fluid-app/i18n/use-domain-dict\";\nimport {\n contactsDomain,\n createContactsTranslationAdapter,\n} from \"@fluid-app/contacts-core/translation-adapter\";\nimport { ContactsTranslationProvider } from \"@fluid-app/contacts-core/translation-api-context\";\n\nexport function ContactsTranslationBridge({\n children,\n}: {\n children: ReactNode;\n}): React.JSX.Element {\n const { locale } = useActiveLocale();\n const dict = useDomainDict(contactsDomain, locale);\n const api = useMemo(\n () => createContactsTranslationAdapter(locale, dict),\n [locale, dict],\n );\n return (\n <ContactsTranslationProvider value={api}>\n {children}\n </ContactsTranslationProvider>\n );\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { FormProvider } from \"react-hook-form\";\nimport { useZodForm } from \"@fluid-app/ui-primitives\";\nimport type { ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ContactCreateScreen } from \"@fluid-app/contacts-ui/screens/ContactCreateScreen\";\nimport { RepContactsLayout } from \"@fluid-app/contacts-ui/portal/components/contacts/rep-layout/RepContactsLayout\";\nimport { ContactDetailsForm } from \"@fluid-app/contacts-ui/shared/components/contacts/contactDetailsForm\";\nimport { useCreateContactMutation } from \"@fluid-app/contacts-ui/shared/hooks/useCreateContactMutation\";\nimport {\n createContactFormSchema,\n type CreateContactFormData,\n} from \"@fluid-app/contacts-ui/shared/schemas/contactFormSchema\";\nimport { useCountriesApi } from \"@fluid-app/store-core/countries-api-context\";\nimport { PortalContactsApiProvider } from \"../contacts/PortalContactsApiProvider\";\nimport { ContactsTranslationBridge } from \"../providers/ContactsTranslationBridge\";\nimport { storeKeys } from \"../account/query-keys\";\n\ntype NavState =\n | { view: \"browse\"; selectedContactId: string | null }\n | { view: \"new\" };\n\ntype ContactsScreenProps = ComponentProps<\"div\"> & {\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display\n defaultViewMode?: \"list\" | \"grid\";\n\n // Callbacks\n onContactSelect?: (contactId: string) => void;\n onCreateContact?: () => void;\n};\n\nconst QUERY_KEY_PREFIX = \"sdk-contacts\";\n\nfunction ContactBrowseView({\n selectedContactId,\n onSelect,\n onAdd,\n}: {\n selectedContactId: string | null;\n onSelect: (id: string | null) => void;\n onAdd: () => void;\n}) {\n const countriesAdapter = useCountriesApi();\n const getCountries = useCallback(async () => {\n const result = await countriesAdapter.listCountries();\n return result.countries.map((c) => ({ id: 0, name: c.name, iso: c.code }));\n }, [countriesAdapter]);\n\n return (\n <RepContactsLayout\n selectedContactId={selectedContactId}\n onSelect={onSelect}\n onAdd={onAdd}\n queryKeyPrefix={QUERY_KEY_PREFIX}\n getCountries={getCountries}\n />\n );\n}\n\nconst CREATE_DEFAULT_VALUES: CreateContactFormData = {\n first_name: \"\",\n last_name: \"\",\n email: \"\",\n phone: \"\",\n status: \"new\",\n address: \"\",\n city: \"\",\n state: \"\",\n postal_code: \"\",\n country_code: null,\n language_code: null,\n metadata: {},\n affiliate: {},\n};\n\nfunction ContactCreateView({\n onNavigate,\n onCreateContact,\n}: {\n onNavigate: (state: NavState) => void;\n onCreateContact?: () => void;\n}) {\n const formRef = useRef<HTMLFormElement>(null);\n const countriesAdapter = useCountriesApi();\n\n const { data: countriesResponse } = useQuery({\n queryKey: storeKeys.countries(),\n queryFn: () => countriesAdapter.listCountries(),\n });\n\n const countryOptions = useMemo(\n () =>\n (countriesResponse?.countries ?? [])\n .map((c) => ({ name: c.name, value: c.code }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [countriesResponse],\n );\n\n const methods = useZodForm<CreateContactFormData>(createContactFormSchema, {\n defaultValues: CREATE_DEFAULT_VALUES,\n });\n\n const mutation = useCreateContactMutation(QUERY_KEY_PREFIX, {\n onSuccess: (data) => {\n onCreateContact?.();\n const newContactId = data?.contact?.id;\n if (newContactId) {\n onNavigate({\n view: \"browse\",\n selectedContactId: String(newContactId),\n });\n } else {\n onNavigate({ view: \"browse\", selectedContactId: null });\n }\n },\n });\n\n const { mutate } = mutation;\n\n const onSubmit = useMemo(\n () =>\n methods.handleSubmit(\n (data) => {\n const { affiliate, ...contactFields } = data;\n const payload: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(contactFields)) {\n if (value !== \"\" && value !== null && value !== undefined) {\n payload[key] = value;\n }\n }\n\n if (affiliate && Object.keys(affiliate).length > 0) {\n payload.affiliate = affiliate;\n }\n\n mutate(payload as CreateContactFormData);\n },\n () => {\n // Validation errors are shown inline by react-hook-form field controllers.\n // handleSubmit already populates field errors before calling this callback.\n },\n ),\n [methods, mutate],\n );\n\n const handleNavigateToList = useCallback(() => {\n onNavigate({ view: \"browse\", selectedContactId: null });\n }, [onNavigate]);\n\n return (\n <ContactCreateScreen\n onNavigateToList={handleNavigateToList}\n onSubmit={() => formRef.current?.requestSubmit()}\n isPending={mutation.isPending}\n >\n <FormProvider {...methods}>\n <div className=\"mx-auto max-w-7xl space-y-12 md:px-10 md:py-8\">\n <form\n ref={formRef}\n onSubmit={onSubmit}\n className=\"mx-auto space-y-6 lg:max-w-2xl\"\n >\n <ContactDetailsForm countries={countryOptions} />\n </form>\n </div>\n </FormProvider>\n </ContactCreateScreen>\n );\n}\n\nexport function ContactsScreen({\n onContactSelect,\n onCreateContact,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n defaultViewMode,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ContactsScreenProps): React.JSX.Element {\n const [nav, setNav] = useState<NavState>({\n view: \"browse\",\n selectedContactId: null,\n });\n\n const handleSelect = useCallback(\n (id: string | null) => {\n setNav({ view: \"browse\", selectedContactId: id });\n if (id) onContactSelect?.(id);\n },\n [onContactSelect],\n );\n\n const handleAdd = useCallback(() => {\n setNav({ view: \"new\" });\n }, []);\n\n return (\n <ContactsTranslationBridge>\n <PortalContactsApiProvider>\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n {nav.view === \"browse\" && (\n <ContactBrowseView\n selectedContactId={nav.selectedContactId}\n onSelect={handleSelect}\n onAdd={handleAdd}\n />\n )}\n {nav.view === \"new\" && (\n <ContactCreateView\n onNavigate={setNav}\n onCreateContact={onCreateContact}\n />\n )}\n </div>\n </PortalContactsApiProvider>\n </ContactsTranslationBridge>\n );\n}\n\nexport const contactsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ContactsScreen\",\n displayName: \"Contacts Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}