@fluid-app/portal-sdk 0.1.372 → 0.1.374

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 (101) hide show
  1. package/dist/{ContactsScreen-BVAzJjVs.cjs → ContactsScreen-C28RoYHu.cjs} +2 -2
  2. package/dist/{ContactsScreen-BVAzJjVs.cjs.map → ContactsScreen-C28RoYHu.cjs.map} +1 -1
  3. package/dist/{ContactsScreen-BKKowprR.cjs → ContactsScreen-CCXFgzcN.cjs} +2 -2
  4. package/dist/{ContactsScreen-BHy20ML1.mjs → ContactsScreen-DvPP4F22.mjs} +2 -2
  5. package/dist/{ContactsScreen-BHy20ML1.mjs.map → ContactsScreen-DvPP4F22.mjs.map} +1 -1
  6. package/dist/{ContactsTranslationBridge-BGeau5_N.mjs → ContactsTranslationBridge-Ckjj_Iu9.mjs} +3 -1
  7. package/dist/{ContactsTranslationBridge-BGeau5_N.mjs.map → ContactsTranslationBridge-Ckjj_Iu9.mjs.map} +1 -1
  8. package/dist/{ContactsTranslationBridge-D9gEIAp3.cjs → ContactsTranslationBridge-Dx_1jAxz.cjs} +3 -1
  9. package/dist/{ContactsTranslationBridge-D9gEIAp3.cjs.map → ContactsTranslationBridge-Dx_1jAxz.cjs.map} +1 -1
  10. package/dist/{ContainerWidget-mSWihekF.mjs → ContainerWidget-C1Nk6GPZ.mjs} +2 -2
  11. package/dist/{ContainerWidget-mSWihekF.mjs.map → ContainerWidget-C1Nk6GPZ.mjs.map} +1 -1
  12. package/dist/{ContainerWidget-bMMdFhLg.cjs → ContainerWidget-DVQxqY3k.cjs} +2 -2
  13. package/dist/{ContainerWidget-bMMdFhLg.cjs.map → ContainerWidget-DVQxqY3k.cjs.map} +1 -1
  14. package/dist/{ContainerWidget-C2LMzXVj.cjs → ContainerWidget-fhiIAoZA.cjs} +2 -2
  15. package/dist/{FluidProvider-C6d1TUVm.cjs → FluidProvider-BvVjhwrv.cjs} +11 -10
  16. package/dist/{FluidProvider-C6d1TUVm.cjs.map → FluidProvider-BvVjhwrv.cjs.map} +1 -1
  17. package/dist/{FluidProvider-C80gc4Yi.mjs → FluidProvider-Cx0wNNF7.mjs} +11 -10
  18. package/dist/{FluidProvider-C80gc4Yi.mjs.map → FluidProvider-Cx0wNNF7.mjs.map} +1 -1
  19. package/dist/{LayoutWidget-BqUbneWw.cjs → LayoutWidget-CzM4gn1-.cjs} +12 -10
  20. package/dist/LayoutWidget-CzM4gn1-.cjs.map +1 -0
  21. package/dist/{LayoutWidget-C1BzDeQI.cjs → LayoutWidget-D-wlt7T1.cjs} +1 -1
  22. package/dist/{LayoutWidget-D3qYKt9F.mjs → LayoutWidget-DXPXYYd_.mjs} +12 -10
  23. package/dist/LayoutWidget-DXPXYYd_.mjs.map +1 -0
  24. package/dist/{MessagingScreen-PZyO11S1.cjs → MessagingScreen-6fuZJ_0Q.cjs} +7 -7
  25. package/dist/{MessagingScreen-DKzYThAY.mjs → MessagingScreen-BEVwNvC3.mjs} +2 -2
  26. package/dist/{MessagingScreen-DKzYThAY.mjs.map → MessagingScreen-BEVwNvC3.mjs.map} +1 -1
  27. package/dist/{MessagingScreen-DqxRu2x3.cjs → MessagingScreen-BTcBx8v4.cjs} +2 -2
  28. package/dist/{MessagingScreen-DqxRu2x3.cjs.map → MessagingScreen-BTcBx8v4.cjs.map} +1 -1
  29. package/dist/{MessagingScreen-D3si8TPx.mjs → MessagingScreen-Bw3pawb5.mjs} +7 -7
  30. package/dist/{OrdersScreen-CUfyr7Y0.cjs → OrdersScreen-BZUSgBTy.cjs} +2 -2
  31. package/dist/{OrdersScreen-CUfyr7Y0.cjs.map → OrdersScreen-BZUSgBTy.cjs.map} +1 -1
  32. package/dist/{OrdersScreen-NSQ51uu5.cjs → OrdersScreen-CViKIru5.cjs} +7 -7
  33. package/dist/{OrdersScreen-BbDkjTd_.mjs → OrdersScreen-DcA6QoGF.mjs} +7 -7
  34. package/dist/{OrdersScreen-ewbXb5cz.mjs → OrdersScreen-Kkk88xDy.mjs} +2 -2
  35. package/dist/{OrdersScreen-ewbXb5cz.mjs.map → OrdersScreen-Kkk88xDy.mjs.map} +1 -1
  36. package/dist/{ProfileScreen-MypXufrO.cjs → ProfileScreen-C2-nARkW.cjs} +8 -8
  37. package/dist/{ProfileScreen-BCwdwO_p.mjs → ProfileScreen-CZJA8dZS.mjs} +4 -4
  38. package/dist/{ProfileScreen-BCwdwO_p.mjs.map → ProfileScreen-CZJA8dZS.mjs.map} +1 -1
  39. package/dist/{ProfileScreen-D7UA604p.mjs → ProfileScreen-DjCRBTlH.mjs} +8 -8
  40. package/dist/{ProfileScreen-DlIXDIeu.cjs → ProfileScreen-j-5VwfqY.cjs} +4 -4
  41. package/dist/{ProfileScreen-DlIXDIeu.cjs.map → ProfileScreen-j-5VwfqY.cjs.map} +1 -1
  42. package/dist/{ShopScreen-BKVNW6ya.mjs → ShopScreen-BT5QKVbL.mjs} +7 -7
  43. package/dist/{ShopScreen-CgN-6gic.mjs → ShopScreen-CyRX0aOs.mjs} +48 -42
  44. package/dist/ShopScreen-CyRX0aOs.mjs.map +1 -0
  45. package/dist/{ShopScreen-BC9NDysQ.cjs → ShopScreen-D3Pzmg6Q.cjs} +7 -7
  46. package/dist/{ShopScreen-29SZwMWF.cjs → ShopScreen-DVlQAOHj.cjs} +48 -42
  47. package/dist/ShopScreen-DVlQAOHj.cjs.map +1 -0
  48. package/dist/{ShopWidget-BbCPV2_Y.cjs → ShopWidget-C_R5RGoe.cjs} +13 -23
  49. package/dist/ShopWidget-C_R5RGoe.cjs.map +1 -0
  50. package/dist/{ShopWidget-BF0zWjS6.cjs → ShopWidget-CaPQVMlr.cjs} +1 -1
  51. package/dist/{ShopWidget-YMXis5SJ.mjs → ShopWidget-N0OqYNM-.mjs} +13 -23
  52. package/dist/ShopWidget-N0OqYNM-.mjs.map +1 -0
  53. package/dist/{SubscriptionsScreen-M2WaVHH7.mjs → SubscriptionsScreen-C-UXQeNC.mjs} +4 -4
  54. package/dist/{SubscriptionsScreen-M2WaVHH7.mjs.map → SubscriptionsScreen-C-UXQeNC.mjs.map} +1 -1
  55. package/dist/{SubscriptionsScreen-Dz6Y_1oD.cjs → SubscriptionsScreen-OITPOl3Y.cjs} +4 -4
  56. package/dist/{SubscriptionsScreen-Dz6Y_1oD.cjs.map → SubscriptionsScreen-OITPOl3Y.cjs.map} +1 -1
  57. package/dist/{SubscriptionsScreen-dN42J-MR.cjs → SubscriptionsScreen-amFuxymL.cjs} +8 -8
  58. package/dist/{SubscriptionsScreen-CPiLzWhm.mjs → SubscriptionsScreen-lvMO6Bkp.mjs} +8 -8
  59. package/dist/{ToDoWidget-3bkkxozQ.cjs → ToDoWidget-Cr0VP7k6.cjs} +1 -1
  60. package/dist/{ToDoWidget-BZyJIX1X.mjs → ToDoWidget-DiGklfKG.mjs} +32 -39
  61. package/dist/ToDoWidget-DiGklfKG.mjs.map +1 -0
  62. package/dist/{ToDoWidget-CgFDCQNX.cjs → ToDoWidget-aSYTB02O.cjs} +31 -38
  63. package/dist/ToDoWidget-aSYTB02O.cjs.map +1 -0
  64. package/dist/{authoring-V0sXg_j4.d.mts → authoring-D0yimRFr.d.mts} +2 -2
  65. package/dist/{authoring-V0sXg_j4.d.mts.map → authoring-D0yimRFr.d.mts.map} +1 -1
  66. package/dist/{authoring--rXPyZca.d.cts → authoring-Di7OJapg.d.cts} +2 -2
  67. package/dist/{authoring--rXPyZca.d.cts.map → authoring-Di7OJapg.d.cts.map} +1 -1
  68. package/dist/index.cjs +26 -26
  69. package/dist/index.d.cts +2 -2
  70. package/dist/index.d.cts.map +1 -1
  71. package/dist/index.d.mts +2 -2
  72. package/dist/index.d.mts.map +1 -1
  73. package/dist/index.mjs +26 -26
  74. package/dist/preview/preview-entry.cjs +7 -7
  75. package/dist/preview/preview-entry.d.cts +1 -1
  76. package/dist/preview/preview-entry.d.mts +1 -1
  77. package/dist/preview/preview-entry.mjs +7 -7
  78. package/dist/{use-portal-card-add-3ds-flow-DKXraYw-.mjs → use-portal-card-add-3ds-flow-BLjXfmje.mjs} +2 -2
  79. package/dist/{use-portal-card-add-3ds-flow-DKXraYw-.mjs.map → use-portal-card-add-3ds-flow-BLjXfmje.mjs.map} +1 -1
  80. package/dist/{use-portal-card-add-3ds-flow-C0YUg213.cjs → use-portal-card-add-3ds-flow-C2uzzhr8.cjs} +2 -2
  81. package/dist/{use-portal-card-add-3ds-flow-C0YUg213.cjs.map → use-portal-card-add-3ds-flow-C2uzzhr8.cjs.map} +1 -1
  82. package/dist/{widget-package-descriptor-ByCz_FNh.d.cts → widget-package-descriptor-Chc8Gb6V.d.cts} +8 -8
  83. package/dist/widget-package-descriptor-Chc8Gb6V.d.cts.map +1 -0
  84. package/dist/{widget-package-descriptor-CPIPAdUO.d.mts → widget-package-descriptor-fjHqObKE.d.mts} +8 -8
  85. package/dist/{widget-package-descriptor-CPIPAdUO.d.mts.map → widget-package-descriptor-fjHqObKE.d.mts.map} +1 -1
  86. package/dist/{widget-package-utils-BdS0B0pI.mjs → widget-package-utils-DG2ibxqS.mjs} +2 -2
  87. package/dist/{widget-package-utils-BdS0B0pI.mjs.map → widget-package-utils-DG2ibxqS.mjs.map} +1 -1
  88. package/dist/{widget-package-utils-BWn56ZFw.cjs → widget-package-utils-pdLitM72.cjs} +2 -2
  89. package/dist/{widget-package-utils-BWn56ZFw.cjs.map → widget-package-utils-pdLitM72.cjs.map} +1 -1
  90. package/dist/widgets/authoring.d.cts +1 -1
  91. package/dist/widgets/authoring.d.mts +1 -1
  92. package/package.json +16 -16
  93. package/dist/LayoutWidget-BqUbneWw.cjs.map +0 -1
  94. package/dist/LayoutWidget-D3qYKt9F.mjs.map +0 -1
  95. package/dist/ShopScreen-29SZwMWF.cjs.map +0 -1
  96. package/dist/ShopScreen-CgN-6gic.mjs.map +0 -1
  97. package/dist/ShopWidget-BbCPV2_Y.cjs.map +0 -1
  98. package/dist/ShopWidget-YMXis5SJ.mjs.map +0 -1
  99. package/dist/ToDoWidget-BZyJIX1X.mjs.map +0 -1
  100. package/dist/ToDoWidget-CgFDCQNX.cjs.map +0 -1
  101. package/dist/widget-package-descriptor-ByCz_FNh.d.cts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ToDoWidget-BZyJIX1X.mjs","names":[],"sources":["../../widgets/src/hooks/use-todos.preview.ts","../../widgets/src/hooks/use-todos.ts","../../widgets/src/hooks/use-update-todo.ts","../../widgets/src/hooks/use-delete-todo.ts","../../widgets/src/hooks/use-create-todo.ts","../../widgets/src/widgets/CreateTodoDialog.tsx","../../widgets/src/widgets/EditTodoDialog.tsx","../../widgets/src/widgets/ToDoWidget.tsx"],"sourcesContent":["import type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nexport const PREVIEW_DATA: Todo[] = [\n {\n id: 1,\n body: \"Send follow-up email to new leads\",\n dueAt: daysFromNow(1),\n completedAt: null,\n createdAt: daysFromNow(-2),\n contactId: 101,\n contactName: \"Sarah Johnson\",\n },\n {\n id: 2,\n body: \"Prepare slides for team training\",\n dueAt: daysFromNow(3),\n completedAt: null,\n createdAt: daysFromNow(-1),\n contactId: null,\n contactName: null,\n },\n {\n id: 3,\n body: \"Review monthly sales report\",\n dueAt: daysFromNow(-1),\n completedAt: null,\n createdAt: daysFromNow(-5),\n contactId: 102,\n contactName: \"Mike Chen\",\n },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport type { TodosStateFilter } from \"@fluid-app/portal-core/widgets-api\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-todos.preview\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nexport type { TodosStateFilter } from \"@fluid-app/portal-core/widgets-api\";\n\n/**\n * Shared cache key for the todos list. Both useTodos (read) and\n * useUpdateTodo (write) use this — drift would silently break optimistic\n * updates. The `state` arg is included so the active/completed lists\n * cache independently.\n */\nexport function todosQueryKey(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n state?: TodosStateFilter;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n args.state ?? \"incomplete\",\n ] as const;\n}\n\nexport function todosQueryKeyPrefix(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n ] as const;\n}\n\nexport interface UseTodosOptions {\n state?: TodosStateFilter;\n}\n\nexport function useTodos(\n options?: UseTodosOptions,\n): UseQueryResult<Todo[], Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n const state = options?.state;\n\n return useQuery({\n queryKey: todosQueryKey(\n state !== undefined\n ? { baseUrl, isPreview, state }\n : { baseUrl, isPreview },\n ),\n queryFn: ({ signal }) =>\n widgetsApi.fetchTodos(\n state !== undefined ? { state } : undefined,\n signal,\n ),\n enabled: !isPreview,\n ...(isPreview &&\n (state === undefined || state === \"incomplete\") && {\n placeholderData: PREVIEW_DATA,\n }),\n ...(isPreview &&\n state !== undefined &&\n state !== \"incomplete\" && {\n placeholderData: [],\n }),\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey, todosQueryKeyPrefix } from \"./use-todos\";\n\nexport interface UpdateTodoVariables {\n id: number;\n body?: string;\n due_at?: string | null;\n completed?: boolean;\n /**\n * Used to invalidate `contactsKeys.tasks(contactId)` after a successful\n * update so the in-contact tasks view stays in sync.\n */\n contactId?: number | null;\n}\n\nexport function useUpdateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id, body, due_at, completed }: UpdateTodoVariables) => {\n // Defense in depth: ToDoWidget already disables the checkbox in\n // preview mode, but if any other caller fires this mutation while\n // previewing we'd PATCH demo data on the real backend. Fail closed.\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo updates are disabled in preview mode\"),\n );\n }\n const input: {\n body?: string;\n due_at?: string | null;\n completed?: boolean;\n } = {};\n if (body !== undefined) input.body = body;\n if (due_at !== undefined) input.due_at = due_at;\n if (completed !== undefined) input.completed = completed;\n return widgetsApi.updateTodo(id, input);\n },\n onMutate: async (variables) => {\n // Only apply the optimistic-completion shortcut when the caller is\n // toggling completion alone (the checkbox case). Body/due_at edits\n // come from the dialog and fall back to invalidate-on-success.\n const isCompletionToggle =\n variables.completed !== undefined &&\n variables.body === undefined &&\n variables.due_at === undefined;\n if (!isCompletionToggle) return { previous: undefined };\n\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === variables.id\n ? {\n ...todo,\n completedAt: variables.completed\n ? new Date().toISOString()\n : null,\n }\n : todo,\n ),\n );\n return { previous };\n },\n onSuccess: (updated, variables) => {\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === updated.id ? updated : todo,\n ),\n );\n // Match the documented test plan: completing toasts, un-completing\n // is silent. Body/due_at edits also toast as \"Todo updated\".\n const isCompletionToggle =\n variables.completed !== undefined &&\n variables.body === undefined &&\n variables.due_at === undefined;\n if (isCompletionToggle) {\n if (variables.completed) {\n fluidToast({ title: \"Todo completed\", type: \"success\" });\n }\n } else {\n fluidToast({ title: \"Todo updated\", type: \"success\" });\n }\n // Keep the contact-scoped tasks view in sync when the todo is\n // attached to a contact.\n if (variables.contactId != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contactId)),\n });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to update todo\", type: \"error\" });\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKeyPrefix({ baseUrl, isPreview }),\n });\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey, todosQueryKeyPrefix } from \"./use-todos\";\n\nexport interface DeleteTodoVariables {\n id: number;\n /**\n * Used to invalidate `contactsKeys.tasks(contactId)` after a successful\n * delete so the in-contact tasks view stays in sync.\n */\n contactId?: number | null;\n}\n\nexport function useDeleteTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id }: DeleteTodoVariables) => {\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo deletion is disabled in preview mode\"),\n );\n }\n return widgetsApi.deleteTodo(id);\n },\n onMutate: async ({ id }) => {\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).filter((todo) => todo.id !== id),\n );\n return { previous };\n },\n onSuccess: (_result, variables) => {\n fluidToast({ title: \"Todo deleted\", type: \"success\" });\n if (variables.contactId != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contactId)),\n });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to delete todo\", type: \"error\" });\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKeyPrefix({ baseUrl, isPreview }),\n });\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport { todosQueryKey } from \"./use-todos\";\n\nexport interface CreateTodoVariables {\n body: string;\n due_at: string | null;\n contact_id: number | null;\n}\n\nexport function useCreateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useMutation({\n mutationFn: (variables: CreateTodoVariables) => {\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo creation is disabled in preview mode\"),\n );\n }\n return widgetsApi.createTodo(variables);\n },\n onSuccess: (_created, variables) => {\n fluidToast({ title: \"Todo created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n });\n if (variables.contact_id != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contact_id)),\n });\n }\n },\n onError: () => {\n fluidToast({ title: \"Failed to create todo\", type: \"error\" });\n },\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Check, Search, UserRound } from \"lucide-react\";\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n cn,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport { useCreateTodo } from \"../hooks/use-create-todo\";\n\nconst SEARCH_DEBOUNCE_MS = 200;\n\nfunction getContactInitials(contact: Contact): string | undefined {\n const firstInitial = contact.first_name?.trim().charAt(0);\n const lastInitial = contact.last_name?.trim().charAt(0);\n const explicitInitials = `${firstInitial ?? \"\"}${lastInitial ?? \"\"}`;\n\n if (explicitInitials) return explicitInitials.toUpperCase();\n\n const initials = contact.full_name\n .trim()\n .split(/\\s+/)\n .slice(0, 2)\n .map((part) => part.charAt(0))\n .join(\"\")\n .toUpperCase();\n\n return initials || undefined;\n}\n\nfunction ContactBadgeAvatar({\n contact,\n}: {\n contact: Contact | null;\n}): React.JSX.Element {\n const initials = contact ? getContactInitials(contact) : undefined;\n\n return (\n <Avatar className=\"size-4 text-current\" aria-hidden=\"true\">\n {contact?.avatar_url ? (\n <AvatarImage src={contact.avatar_url} alt=\"\" />\n ) : null}\n <AvatarFallback className=\"bg-transparent text-[0.625rem] font-semibold text-current\">\n {initials ?? <UserRound className=\"size-3\" aria-hidden=\"true\" />}\n </AvatarFallback>\n </Avatar>\n );\n}\n\nexport interface CreateTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function CreateTodoDialog({\n open,\n onOpenChange,\n}: CreateTodoDialogProps): React.JSX.Element {\n const [selectedContact, setSelectedContact] = useState<Contact | null>(null);\n // Anchor nested popovers inside the dialog's themed portal subtree.\n // ui-primitives PopoverContent reads this via usePortalContainer(), so the\n // task date popover inherits portal theme variables instead of falling back\n // to document.body. Dialog also applies pointer-events: none to the body\n // while open, which kills clicks and scroll on a body-portaled popover in\n // WebKit. See edit-bill-date-dialog for the canonical pattern.\n const [themedPopoverContainer, setThemedPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n const { t } = useContactsTranslation();\n\n const createTodo = useCreateTodo();\n\n // Reset state when the dialog closes so the next open starts fresh.\n useEffect(() => {\n if (!open) setSelectedContact(null);\n }, [open]);\n\n const handleSubmit = (values: { body: string; due_at: string | null }) => {\n createTodo.mutate(\n {\n body: values.body,\n due_at: values.due_at,\n contact_id: selectedContact ? selectedContact.id : null,\n },\n {\n onSuccess: () => onOpenChange(false),\n },\n );\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-xl sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>{t(\"add_todo_dialog_title\")}</DialogTitle>\n </DialogHeader>\n\n <PortalContainerProvider container={themedPopoverContainer}>\n <div className=\"mt-2 flex flex-col gap-3\">\n <TaskComposerForm\n onSubmit={handleSubmit}\n isSubmitting={createTodo.isPending}\n metadataControls={\n <ContactPicker\n value={selectedContact}\n onSelect={setSelectedContact}\n onClear={() => setSelectedContact(null)}\n />\n }\n />\n </div>\n </PortalContainerProvider>\n {/* Portal target for the popover. Must live INSIDE DialogContent so\n it ends up in the dialog's body-level portal — otherwise it\n renders inline next to the widget, and any transformed ancestor\n (builder canvas zoom, etc.) would break `position: fixed`.\n Intentionally NOT aria-hidden — the popover content portaled\n into this container has its own listbox/option semantics that\n screen readers need to reach. `pointer-events-none` keeps the\n empty overlay from capturing clicks; the popover content sets\n `pointer-events-auto` so it remains interactive. */}\n <div\n ref={setThemedPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ContactPickerProps {\n value: Contact | null;\n onSelect: (contact: Contact) => void;\n onClear: () => void;\n}\n\nfunction ContactPicker({\n value,\n onSelect,\n onClear,\n}: ContactPickerProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, SEARCH_DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const queryParams = useMemo(\n () => ({\n ...(debouncedSearch ? { search_query: debouncedSearch } : {}),\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 25,\n }),\n [debouncedSearch],\n );\n\n const {\n data,\n isLoading,\n isError,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n // Auto-load the next page when the sentinel scrolls into view, so reps\n // with many contacts can reach all of them without typing a precise\n // search query.\n useEffect(() => {\n if (!open) return;\n\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 }, [open, hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n const selectedContactLabel = value ? value.full_name : t(\"select_contact\");\n\n return (\n <div className=\"flex min-w-0 items-center\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={t(\"contact_picker_trigger_aria\", {\n selection: selectedContactLabel,\n })}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n className={cn(\n \"flex max-w-40 min-w-0 shrink items-center gap-1 rounded-full px-3 py-1 text-left text-xs font-medium transition-colors\",\n value\n ? \"bg-primary text-primary-foreground\"\n : \"bg-muted text-muted-foreground hover:bg-muted/70\",\n )}\n >\n <ContactBadgeAvatar contact={value} />\n <span className=\"min-w-0 truncate\">{selectedContactLabel}</span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"bg-popover text-popover-foreground pointer-events-auto z-[9999] w-72 max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border p-0 shadow-md\"\n >\n <div className=\"border-border flex items-center gap-2 border-b px-3 py-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 aria-label={t(\"search_placeholder\")}\n className=\"h-7 border-0 px-0 shadow-none focus-visible:ring-0\"\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto py-1\" role=\"listbox\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={value === null}\n onClick={() => {\n onClear();\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"text-muted-foreground truncate italic\">\n {t(\"no_contact\")}\n </span>\n {value === null && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n {isLoading ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {t(\"loading\")}\n </div>\n ) : isError ? (\n <div className=\"text-destructive px-3 py-6 text-center text-xs\">\n {t(\"error_loading_list\")}\n </div>\n ) : contacts.length === 0 ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : t(\"no_contacts_yet\")}\n </div>\n ) : (\n <>\n {contacts.map((contact) => {\n const isSelected = value?.id === contact.id;\n return (\n <button\n key={contact.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n onSelect(contact);\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"truncate\">{contact.full_name}</span>\n {isSelected && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground px-3 py-2 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\n\nexport interface EditTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n todo: Todo | null;\n}\n\nexport function EditTodoDialog({\n open,\n onOpenChange,\n todo,\n}: EditTodoDialogProps): React.JSX.Element | null {\n const { t } = useContactsTranslation();\n const updateTodo = useUpdateTodo();\n // Anchor nested popovers inside the dialog's themed portal subtree.\n // ui-primitives PopoverContent reads this via usePortalContainer(), so the\n // task date popover inherits portal theme variables instead of falling back\n // to document.body.\n const [themedPopoverContainer, setThemedPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n\n if (!todo) return null;\n\n const handleSubmit = (values: { body: string; due_at: string | null }) => {\n updateTodo.mutate(\n {\n id: todo.id,\n body: values.body,\n due_at: values.due_at,\n contactId: todo.contactId,\n },\n {\n onSuccess: () => onOpenChange(false),\n },\n );\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-md sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>{t(\"edit_todo\")}</DialogTitle>\n </DialogHeader>\n <PortalContainerProvider container={themedPopoverContainer}>\n <TaskComposerForm\n key={todo.id}\n initialBody={todo.body}\n initialDueAt={todo.dueAt}\n onSubmit={handleSubmit}\n isSubmitting={updateTodo.isPending}\n submitLabel={t(\"save_changes\")}\n submittingLabel={t(\"saving\")}\n />\n </PortalContainerProvider>\n <div\n ref={setThemedPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n","import { useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport {\n Button,\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 {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport {\n ChevronDown,\n ChevronUp,\n EllipsisVertical,\n ListChecks,\n Plus,\n} from \"lucide-react\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport {\n ALL_DAY_PATTERN,\n LOCAL_TIMED_DUE_AT_PATTERN,\n} from \"@fluid-app/contacts-ui/portal/utils/format-date\";\nimport { useTodos } from \"../hooks/use-todos\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\nimport { useDeleteTodo } from \"../hooks/use-delete-todo\";\nimport { ErrorState } from \"../components/error-state\";\nimport { CreateTodoDialog } from \"./CreateTodoDialog\";\nimport { EditTodoDialog } from \"./EditTodoDialog\";\n\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nfunction usesSingularPluralForm(locale: string, count: number): boolean {\n const tag = locale.replace(/_/g, \"-\");\n let rules = pluralRulesCache.get(tag);\n if (!rules) {\n rules = new Intl.PluralRules(tag);\n pluralRulesCache.set(tag, rules);\n }\n\n return rules.select(count) === \"one\";\n}\n\ntype ToDoWidgetProps = ComponentProps<\"div\"> & {\n // Title\n titleEnabled?: boolean;\n titleText?: string;\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content\n maxItems?: number;\n};\n\n/**\n * Format a todo due_at ISO string as a short date + time (e.g. \"Jun 1, 9:00 AM\").\n * Mirrors the mobile widget formatting.\n *\n * All-day / date-only values (bare YYYY-MM-DD or timezone-qualified ISO strings\n * whose time component is 00:00) are formatted in UTC so the displayed calendar\n * date matches the source prefix without shifting. Local timed values produced\n * by the task composer, including explicit 00:00, use a single locale-native\n * formatter with both date and time parts.\n */\nfunction formatDueAt(dateStr: string, locale?: string): string {\n const normalizedLocale = locale?.replace(/_/g, \"-\") ?? \"en-US\";\n\n // Detect date-only / all-day: bare YYYY-MM-DD or timezone-qualified ISO whose\n // time is exactly 00:00 (including fractional seconds and offset variants like\n // 2024-06-01T00:00:00.000+02:00). Local timed strings from the task composer\n // remain timed, so 2024-06-01T00:00:00 displays 12:00 AM instead of all-day.\n if (\n ALL_DAY_PATTERN.test(dateStr) &&\n !LOCAL_TIMED_DUE_AT_PATTERN.test(dateStr)\n ) {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(dateStr);\n if (match?.[1] && match[2] && match[3]) {\n const date = new Date(\n Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])),\n );\n return date.toLocaleDateString(normalizedLocale, {\n month: \"short\",\n day: \"numeric\",\n timeZone: \"UTC\",\n });\n }\n }\n\n // Genuinely timed value — use a single formatter so ordering and\n // separators are locale-native.\n const date = new Date(dateStr);\n return date.toLocaleString(normalizedLocale, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n}\n\nexport function ToDoWidget({\n // Title defaults\n titleEnabled = true,\n titleText = \"To-Do\",\n titleFontSize = \"lg\",\n titleColor = \"foreground\",\n\n // Styling defaults\n background = {\n type: \"solid\",\n color: \"background\",\n },\n textColor = \"foreground\",\n accentColor = \"primary\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n\n // Content defaults\n maxItems = 5,\n\n className,\n ...props\n}: ToDoWidgetProps): React.JSX.Element {\n const { t, locale } = useContactsTranslation();\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n const { data: todos = [], isLoading, isError } = useTodos();\n const { data: completedTodos = [], isLoading: isCompletedLoading } = useTodos(\n { state: \"completed\" },\n );\n const updateTodo = useUpdateTodo();\n const deleteTodo = useDeleteTodo();\n const { isPreview } = useWidgetPreviewContext();\n const [pendingIds, setPendingIds] = useState<Set<number>>(new Set());\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n const [editingTodo, setEditingTodo] = useState<Todo | null>(null);\n const [isDoneExpanded, setIsDoneExpanded] = useState(false);\n\n const toggleTodo = (todo: Todo, completed: boolean) => {\n if (isPreview || pendingIds.has(todo.id)) return;\n setPendingIds((prev) => new Set(prev).add(todo.id));\n updateTodo.mutate(\n { id: todo.id, completed, contactId: todo.contactId },\n {\n onSettled: () =>\n setPendingIds((prev) => {\n const next = new Set(prev);\n next.delete(todo.id);\n return next;\n }),\n },\n );\n };\n\n const activeTodos = todos.filter((todo) => !todo.completedAt);\n const todosToShow = activeTodos.slice(0, maxItems);\n const remainingCount = activeTodos.length - todosToShow.length;\n const isEmpty = activeTodos.length === 0;\n\n // Group todos by contactId so same-named contacts stay separate.\n const groupedTodos = todosToShow.reduce<\n {\n contactId: number | null;\n contactName: string | null;\n todos: typeof todosToShow;\n }[]\n >((groups, todo) => {\n const existing = groups.find((g) => g.contactId === todo.contactId);\n if (existing) {\n existing.todos.push(todo);\n } else {\n groups.push({\n contactId: todo.contactId,\n contactName: todo.contactName,\n todos: [todo],\n });\n }\n return groups;\n }, []);\n\n const doneCount = completedTodos.length;\n\n const handleRowClick = (todo: Todo) => {\n if (isPreview) return;\n setEditingTodo(todo);\n };\n\n const handleDelete = (todo: Todo) => {\n if (isPreview) return;\n deleteTodo.mutate({ id: todo.id, contactId: todo.contactId });\n };\n\n return (\n <div\n className={`overflow-hidden rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} text-${textColor} p-${padding} ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {titleEnabled && titleText && (\n <h2\n className={`text-${titleFontSize} font-header font-bold text-${titleColor}`}\n >\n {titleText}\n </h2>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {!isEmpty && !isLoading && (\n <span className={`text-2xl font-bold text-${accentColor}`}>\n {activeTodos.length}\n </span>\n )}\n <div className={`flex size-10 shrink-0 items-center justify-center`}>\n <ListChecks className={`h-5 w-5 text-${accentColor}-foreground`} />\n </div>\n </div>\n </div>\n\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex min-h-[120px] items-center justify-center\">\n <div className=\"size-6 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n </div>\n ) : isError ? (\n /* Error state */\n <ErrorState />\n ) : isEmpty ? (\n /* Empty state */\n <div className=\"flex flex-col items-center justify-center gap-3 py-8\">\n <p className={`text-center text-${textColor}/60`}>\n {t(\"todo_empty\")}\n </p>\n {!isPreview && (\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n className={`inline-flex items-center gap-1.5 rounded-full bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 px-4 py-1.5 text-xs font-semibold transition-colors`}\n >\n <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n {t(\"add_todo\")}\n </button>\n )}\n </div>\n ) : (\n /* Todo List */\n <>\n <div className=\"flex flex-col gap-3\">\n {groupedTodos.map((group) => (\n <div\n key={group.contactId ?? \"__unassigned__\"}\n className=\"flex flex-col\"\n >\n {group.contactName && (\n <div\n className={`mb-1 text-xs font-semibold tracking-wide uppercase text-${textColor}/60`}\n >\n {group.contactName}\n </div>\n )}\n {group.todos.map((todo, index) => {\n const showBottomBorder = index !== group.todos.length - 1;\n return (\n <div\n key={todo.id}\n className={`group/row flex items-center gap-3 py-2 ${\n showBottomBorder\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked={!!todo.completedAt}\n disabled={isPreview || pendingIds.has(todo.id)}\n onChange={(event) =>\n toggleTodo(todo, event.target.checked)\n }\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"mark_as_completed\")}\n />\n <button\n type=\"button\"\n onClick={() => handleRowClick(todo)}\n disabled={isPreview}\n aria-label={t(\"edit_todo\")}\n className=\"flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left not-disabled:cursor-pointer\"\n >\n <span className=\"line-clamp-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n {todo.dueAt && (\n <span className={`text-xs text-${textColor}/60`}>\n {formatDueAt(todo.dueAt, locale)}\n </span>\n )}\n </button>\n {!isPreview && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"task_actions\")}\n className=\"opacity-60 transition-opacity group-hover/row:opacity-100 focus-visible:opacity-100\"\n >\n <EllipsisVertical className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={(event) => {\n event.stopPropagation();\n handleRowClick(todo);\n }}\n >\n {t(\"edit_todo\")}\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n handleDelete(todo);\n }}\n >\n {t(\"delete_todo\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n\n {/* Footer */}\n <div className=\"mt-2 flex items-center justify-between\">\n {remainingCount > 0 && (\n <span className={`text-sm text-${textColor}/50 underline`}>\n {usesSingularPluralForm(locale, remainingCount)\n ? t(\"todo_more_tasks_one\", { count: remainingCount })\n : t(\"todo_more_tasks_other\", { count: remainingCount })}\n </span>\n )}\n <div className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n disabled={isPreview}\n aria-label={t(\"add_todo\")}\n className={`flex h-8 w-8 items-center justify-center rounded-full transition-colors not-disabled:cursor-pointer hover:bg-${textColor}/10 disabled:opacity-60`}\n >\n <Plus className={`h-5 w-5 text-${textColor}/50`} />\n </button>\n </div>\n </div>\n </>\n )}\n\n {/* Done section */}\n {!isPreview &&\n !isLoading &&\n !isError &&\n !isCompletedLoading &&\n doneCount > 0 && (\n <div className={`mt-3 border-t border-${textColor}/10 pt-2`}>\n <button\n type=\"button\"\n onClick={() => setIsDoneExpanded((v) => !v)}\n className={`flex w-full items-center justify-between gap-2 rounded-md py-1 text-xs font-medium text-${textColor}/60 hover:bg-${textColor}/5`}\n aria-expanded={isDoneExpanded}\n >\n <span>\n {isDoneExpanded\n ? t(\"hide_done\")\n : t(\"view_done\", { count: doneCount })}\n </span>\n {isDoneExpanded ? (\n <ChevronUp className=\"size-4\" aria-hidden=\"true\" />\n ) : (\n <ChevronDown className=\"size-4\" aria-hidden=\"true\" />\n )}\n </button>\n {isDoneExpanded && (\n <div className=\"mt-1 flex flex-col\">\n {completedTodos.map((todo, index) => (\n <div\n key={todo.id}\n className={`group/row flex items-center gap-3 py-2 ${\n index !== completedTodos.length - 1\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked\n disabled={pendingIds.has(todo.id)}\n onChange={() => toggleTodo(todo, false)}\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"mark_as_open\")}\n />\n <button\n type=\"button\"\n onClick={() => handleRowClick(todo)}\n aria-label={t(\"edit_todo\")}\n className={`flex min-w-0 flex-1 cursor-pointer flex-col items-start gap-0.5 text-left text-${textColor}/60 line-through`}\n >\n <span className=\"line-clamp-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n {todo.dueAt && (\n <span className=\"text-xs\">\n {formatDueAt(todo.dueAt, locale)}\n </span>\n )}\n </button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"task_actions\")}\n className=\"opacity-60 transition-opacity group-hover/row:opacity-100 focus-visible:opacity-100\"\n >\n <EllipsisVertical className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={(event) => {\n event.stopPropagation();\n handleRowClick(todo);\n }}\n >\n {t(\"edit_todo\")}\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n handleDelete(todo);\n }}\n >\n {t(\"delete_todo\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {!isPreview && (\n <CreateTodoDialog\n open={isCreateDialogOpen}\n onOpenChange={setIsCreateDialogOpen}\n />\n )}\n {!isPreview && (\n <EditTodoDialog\n open={editingTodo !== null}\n onOpenChange={(open) => {\n if (!open) setEditingTodo(null);\n }}\n todo={editingTodo}\n />\n )}\n </div>\n );\n}\n\nexport const toDoWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ToDoWidget\",\n displayName: \"To-Do Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Styling Tab - Title Group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed above the todo list\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Title text displayed above the todo list\",\n defaultValue: \"To-Do\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleFontSize\",\n label: \"Title Font Size\",\n description: \"Font size for the widget title\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Styling Tab - Design Group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Default text color for todo items\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Color used for count badge and icon\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"maxItems\",\n label: \"Max Items\",\n type: \"number\",\n description: \"Maximum number of todo items to display\",\n min: 1,\n max: 20,\n step: 1,\n defaultValue: 5,\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding around the widget container\",\n defaultValue: 4,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the widget container\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;;;;AAEA,MAAM,sBAAM,IAAI,MAAM;AAEtB,SAAS,YAAY,MAAsB;CACzC,MAAM,IAAI,IAAI,KAAK,IAAI;AACvB,GAAE,QAAQ,EAAE,SAAS,GAAG,KAAK;AAC7B,QAAO,EAAE,aAAa;;AAGxB,MAAa,eAAuB;CAClC;EACE,IAAI;EACJ,MAAM;EACN,OAAO,YAAY,EAAE;EACrB,aAAa;EACb,WAAW,YAAY,GAAG;EAC1B,WAAW;EACX,aAAa;EACd;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO,YAAY,EAAE;EACrB,aAAa;EACb,WAAW,YAAY,GAAG;EAC1B,WAAW;EACX,aAAa;EACd;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO,YAAY,GAAG;EACtB,aAAa;EACb,WAAW,YAAY,GAAG;EAC1B,WAAW;EACX,aAAa;EACd;CACF;;;;;;;;;ACrBD,SAAgB,cAAc,MAI3B;AACD,QAAO;EACL;EACA;EACA,KAAK,YAAY,YAAY,KAAK;EAClC,KAAK,SAAS;EACf;;AAGH,SAAgB,oBAAoB,MAGjC;AACD,QAAO;EACL;EACA;EACA,KAAK,YAAY,YAAY,KAAK;EACnC;;AAOH,SAAgB,SACd,SAC+B;CAC/B,MAAM,aAAa,eAAe;CAClC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,EAAE,YAAY,6BAA6B;CACjD,MAAM,QAAQ,SAAS;AAEvB,QAAO,SAAS;EACd,UAAU,cACR,UAAU,KAAA,IACN;GAAE;GAAS;GAAW;GAAO,GAC7B;GAAE;GAAS;GAAW,CAC3B;EACD,UAAU,EAAE,aACV,WAAW,WACT,UAAU,KAAA,IAAY,EAAE,OAAO,GAAG,KAAA,GAClC,OACD;EACH,SAAS,CAAC;EACV,GAAI,cACD,UAAU,KAAA,KAAa,UAAU,iBAAiB,EACjD,iBAAiB,cAClB;EACH,GAAI,aACF,UAAU,KAAA,KACV,UAAU,gBAAgB,EACxB,iBAAiB,EAAE,EACpB;EACJ,CAAC;;;;ACrDJ,SAAgB,gBAAgB;CAC9B,MAAM,aAAa,eAAe;CAClC,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,EAAE,YAAY,6BAA6B;CAEjD,MAAM,WAAW,cAAc;EAAE;EAAS;EAAW,CAAC;AAEtD,QAAO,YAAY;EACjB,aAAa,EAAE,IAAI,MAAM,QAAQ,gBAAqC;AAIpE,OAAI,UACF,QAAO,QAAQ,uBACb,IAAI,MAAM,4CAA4C,CACvD;GAEH,MAAM,QAIF,EAAE;AACN,OAAI,SAAS,KAAA,EAAW,OAAM,OAAO;AACrC,OAAI,WAAW,KAAA,EAAW,OAAM,SAAS;AACzC,OAAI,cAAc,KAAA,EAAW,OAAM,YAAY;AAC/C,UAAO,WAAW,WAAW,IAAI,MAAM;;EAEzC,UAAU,OAAO,cAAc;AAQ7B,OAAI,EAHF,UAAU,cAAc,KAAA,KACxB,UAAU,SAAS,KAAA,KACnB,UAAU,WAAW,KAAA,GACE,QAAO,EAAE,UAAU,KAAA,GAAW;AAEvD,SAAM,YAAY,cAAc,EAAE,UAAU,CAAC;GAC7C,MAAM,WAAW,YAAY,aAAqB,SAAS;AAC3D,eAAY,aAAqB,WAAW,aACzC,WAAW,EAAE,EAAE,KAAK,SACnB,KAAK,OAAO,UAAU,KAClB;IACE,GAAG;IACH,aAAa,UAAU,6BACnB,IAAI,MAAM,EAAC,aAAa,GACxB;IACL,GACD,KACL,CACF;AACD,UAAO,EAAE,UAAU;;EAErB,YAAY,SAAS,cAAc;AACjC,eAAY,aAAqB,WAAW,aACzC,WAAW,EAAE,EAAE,KAAK,SACnB,KAAK,OAAO,QAAQ,KAAK,UAAU,KACpC,CACF;AAOD,OAHE,UAAU,cAAc,KAAA,KACxB,UAAU,SAAS,KAAA,KACnB,UAAU,WAAW,KAAA;QAEjB,UAAU,UACZ,YAAW;KAAE,OAAO;KAAkB,MAAM;KAAW,CAAC;SAG1D,YAAW;IAAE,OAAO;IAAgB,MAAM;IAAW,CAAC;AAIxD,OAAI,UAAU,aAAa,KACzB,aAAY,kBAAkB,EAC5B,UAAU,aAAa,MAAM,OAAO,UAAU,UAAU,CAAC,EAC1D,CAAC;;EAGN,UAAU,QAAQ,YAAY,YAAY;AACxC,OAAI,SAAS,SACX,aAAY,aAAa,UAAU,QAAQ,SAAS;AAEtD,cAAW;IAAE,OAAO;IAAyB,MAAM;IAAS,CAAC;;EAE/D,iBAAiB;AACf,eAAY,kBAAkB,EAC5B,UAAU,oBAAoB;IAAE;IAAS;IAAW,CAAC,EACtD,CAAC;;EAEL,CAAC;;;;AC/FJ,SAAgB,gBAAgB;CAC9B,MAAM,aAAa,eAAe;CAClC,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,EAAE,YAAY,6BAA6B;CAEjD,MAAM,WAAW,cAAc;EAAE;EAAS;EAAW,CAAC;AAEtD,QAAO,YAAY;EACjB,aAAa,EAAE,SAA8B;AAC3C,OAAI,UACF,QAAO,QAAQ,uBACb,IAAI,MAAM,4CAA4C,CACvD;AAEH,UAAO,WAAW,WAAW,GAAG;;EAElC,UAAU,OAAO,EAAE,SAAS;AAC1B,SAAM,YAAY,cAAc,EAAE,UAAU,CAAC;GAC7C,MAAM,WAAW,YAAY,aAAqB,SAAS;AAC3D,eAAY,aAAqB,WAAW,aACzC,WAAW,EAAE,EAAE,QAAQ,SAAS,KAAK,OAAO,GAAG,CACjD;AACD,UAAO,EAAE,UAAU;;EAErB,YAAY,SAAS,cAAc;AACjC,cAAW;IAAE,OAAO;IAAgB,MAAM;IAAW,CAAC;AACtD,OAAI,UAAU,aAAa,KACzB,aAAY,kBAAkB,EAC5B,UAAU,aAAa,MAAM,OAAO,UAAU,UAAU,CAAC,EAC1D,CAAC;;EAGN,UAAU,QAAQ,YAAY,YAAY;AACxC,OAAI,SAAS,SACX,aAAY,aAAa,UAAU,QAAQ,SAAS;AAEtD,cAAW;IAAE,OAAO;IAAyB,MAAM;IAAS,CAAC;;EAE/D,iBAAiB;AACf,eAAY,kBAAkB,EAC5B,UAAU,oBAAoB;IAAE;IAAS;IAAW,CAAC,EACtD,CAAC;;EAEL,CAAC;;;;AChDJ,SAAgB,gBAAgB;CAC9B,MAAM,aAAa,eAAe;CAClC,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,EAAE,YAAY,6BAA6B;AAEjD,QAAO,YAAY;EACjB,aAAa,cAAmC;AAC9C,OAAI,UACF,QAAO,QAAQ,uBACb,IAAI,MAAM,4CAA4C,CACvD;AAEH,UAAO,WAAW,WAAW,UAAU;;EAEzC,YAAY,UAAU,cAAc;AAClC,cAAW;IAAE,OAAO;IAAgB,MAAM;IAAW,CAAC;AACtD,eAAY,kBAAkB,EAC5B,UAAU,cAAc;IAAE;IAAS;IAAW,CAAC,EAChD,CAAC;AACF,OAAI,UAAU,cAAc,KAC1B,aAAY,kBAAkB,EAC5B,UAAU,aAAa,MAAM,OAAO,UAAU,WAAW,CAAC,EAC3D,CAAC;;EAGN,eAAe;AACb,cAAW;IAAE,OAAO;IAAyB,MAAM;IAAS,CAAC;;EAEhE,CAAC;;;;AClBJ,MAAM,qBAAqB;AAE3B,SAAS,mBAAmB,SAAsC;CAChE,MAAM,eAAe,QAAQ,YAAY,MAAM,CAAC,OAAO,EAAE;CACzD,MAAM,cAAc,QAAQ,WAAW,MAAM,CAAC,OAAO,EAAE;CACvD,MAAM,mBAAmB,GAAG,gBAAgB,KAAK,eAAe;AAEhE,KAAI,iBAAkB,QAAO,iBAAiB,aAAa;AAU3D,QARiB,QAAQ,UACtB,MAAM,CACN,MAAM,MAAM,CACZ,MAAM,GAAG,EAAE,CACX,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,CAC7B,KAAK,GAAG,CACR,aAAa,IAEG,KAAA;;AAGrB,SAAS,mBAAmB,EAC1B,WAGoB;CACpB,MAAM,WAAW,UAAU,mBAAmB,QAAQ,GAAG,KAAA;AAEzD,QACE,qBAAC,QAAD;EAAQ,WAAU;EAAsB,eAAY;YAApD,CACG,SAAS,aACR,oBAAC,aAAD;GAAa,KAAK,QAAQ;GAAY,KAAI;GAAK,CAAA,GAC7C,MACJ,oBAAC,gBAAD;GAAgB,WAAU;aACvB,YAAY,oBAAC,WAAD;IAAW,WAAU;IAAS,eAAY;IAAS,CAAA;GACjD,CAAA,CACV;;;AASb,SAAgB,iBAAiB,EAC/B,MACA,gBAC2C;CAC3C,MAAM,CAAC,iBAAiB,sBAAsB,SAAyB,KAAK;CAO5E,MAAM,CAAC,wBAAwB,6BAC7B,SAAgC,KAAK;CACvC,MAAM,EAAE,MAAM,wBAAwB;CAEtC,MAAM,aAAa,eAAe;AAGlC,iBAAgB;AACd,MAAI,CAAC,KAAM,oBAAmB,KAAK;IAClC,CAAC,KAAK,CAAC;CAEV,MAAM,gBAAgB,WAAoD;AACxE,aAAW,OACT;GACE,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,YAAY,kBAAkB,gBAAgB,KAAK;GACpD,EACD,EACE,iBAAiB,aAAa,MAAM,EACrC,CACF;;AAGH,QACE,oBAAC,QAAD;EAAc;EAAoB;YAChC,qBAAC,eAAD;GAAe,WAAU;aAAzB;IACE,oBAAC,cAAD,EAAA,UACE,oBAAC,aAAD,EAAA,UAAc,EAAE,wBAAwB,EAAe,CAAA,EAC1C,CAAA;IAEf,oBAAC,yBAAD;KAAyB,WAAW;eAClC,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,kBAAD;OACE,UAAU;OACV,cAAc,WAAW;OACzB,kBACE,oBAAC,eAAD;QACE,OAAO;QACP,UAAU;QACV,eAAe,mBAAmB,KAAK;QACvC,CAAA;OAEJ,CAAA;MACE,CAAA;KACkB,CAAA;IAU1B,oBAAC,OAAD;KACE,KAAK;KACL,WAAU;KACV,CAAA;IACY;;EACT,CAAA;;AAUb,SAAS,cAAc,EACrB,OACA,UACA,WACwC;CACxC,MAAM,EAAE,MAAM,wBAAwB;CACtC,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CACvC,MAAM,CAAC,aAAa,kBAAkB,SAAS,GAAG;CAClD,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,GAAG;CAC1D,MAAM,cAAc,OAAuB,KAAK;AAEhD,iBAAgB;EACd,MAAM,SAAS,OAAO,iBAAiB;AACrC,sBAAmB,YAAY,MAAM,CAAC;KACrC,mBAAmB;AACtB,eAAa,OAAO,aAAa,OAAO;IACvC,CAAC,YAAY,CAAC;CAYjB,MAAM,EACJ,MACA,WACA,SACA,aACA,oBACA,kBACE,oBAjBgB,eACX;EACL,GAAI,kBAAkB,EAAE,cAAc,iBAAiB,GAAG,EAAE;EAC5D,SAAS;EACT,gBAAgB;EAChB,UAAU;EACX,GACD,CAAC,gBAAgB,CAClB,CASmC;CAEpC,MAAM,WAAsB,cACpB,MAAM,MAAM,SAAS,SAAS,KAAK,YAAY,EAAE,CAAC,IAAI,EAAE,EAC9D,CAAC,KAAK,CACP;AAKD,iBAAgB;AACd,MAAI,CAAC,KAAM;EAEX,MAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,YAAY,CAAC,YAAa;EAE/B,MAAM,WAAW,IAAI,sBAAsB,YAAY;AAErD,OADc,QAAQ,IACX,kBAAkB,CAAC,mBAC5B,gBAAe;IAEjB;AAEF,WAAS,QAAQ,SAAS;AAC1B,eAAa,SAAS,YAAY;IACjC;EAAC;EAAM;EAAa;EAAoB;EAAc,CAAC;CAE1D,MAAM,uBAAuB,QAAQ,MAAM,YAAY,EAAE,iBAAiB;AAE1E,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,SAAD;GAAe;GAAM,cAAc;aAAnC,CACE,oBAAC,gBAAD;IAAgB,SAAA;cACd,qBAAC,UAAD;KACE,MAAK;KACL,cAAY,EAAE,+BAA+B,EAC3C,WAAW,sBACZ,CAAC;KACF,iBAAc;KACd,iBAAe;KACf,WAAW,GACT,0HACA,QACI,uCACA,mDACL;eAZH,CAcE,oBAAC,oBAAD,EAAoB,SAAS,OAAS,CAAA,EACtC,oBAAC,QAAD;MAAM,WAAU;gBAAoB;MAA4B,CAAA,CACzD;;IACM,CAAA,EACjB,qBAAC,gBAAD;IACE,OAAM;IACN,WAAU;cAFZ,CAIE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,QAAD;MACE,WAAU;MACV,eAAY;MACZ,CAAA,EACF,oBAAC,OAAD;MACE,OAAO;MACP,WAAW,MAAM,eAAe,EAAE,OAAO,MAAM;MAC/C,aAAa,EAAE,qBAAqB;MACpC,cAAY,EAAE,qBAAqB;MACnC,WAAU;MACV,CAAA,CACE;QACN,qBAAC,OAAD;KAAK,WAAU;KAAgC,MAAK;eAApD,CACE,qBAAC,UAAD;MACE,MAAK;MACL,MAAK;MACL,iBAAe,UAAU;MACzB,eAAe;AACb,gBAAS;AACT,eAAQ,MAAM;;MAEhB,WAAU;gBARZ,CAUE,oBAAC,QAAD;OAAM,WAAU;iBACb,EAAE,aAAa;OACX,CAAA,EACN,UAAU,QACT,oBAAC,OAAD;OACE,WAAU;OACV,eAAY;OACZ,CAAA,CAEG;SACR,YACC,oBAAC,OAAD;MAAK,WAAU;gBACZ,EAAE,UAAU;MACT,CAAA,GACJ,UACF,oBAAC,OAAD;MAAK,WAAU;gBACZ,EAAE,qBAAqB;MACpB,CAAA,GACJ,SAAS,WAAW,IACtB,oBAAC,OAAD;MAAK,WAAU;gBACZ,kBACG,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC,GAClD,EAAE,kBAAkB;MACpB,CAAA,GAEN,qBAAA,YAAA,EAAA,UAAA;MACG,SAAS,KAAK,YAAY;OACzB,MAAM,aAAa,OAAO,OAAO,QAAQ;AACzC,cACE,qBAAC,UAAD;QAEE,MAAK;QACL,MAAK;QACL,iBAAe;QACf,eAAe;AACb,kBAAS,QAAQ;AACjB,iBAAQ,MAAM;;QAEhB,WAAU;kBATZ,CAWE,oBAAC,QAAD;SAAM,WAAU;mBAAY,QAAQ;SAAiB,CAAA,EACpD,cACC,oBAAC,OAAD;SACE,WAAU;SACV,eAAY;SACZ,CAAA,CAEG;UAjBF,QAAQ,GAiBN;QAEX;MACD,eACC,oBAAC,OAAD;OAAK,KAAK;OAAa,eAAY;OAAO,WAAU;OAAQ,CAAA;MAE7D,sBACC,oBAAC,OAAD;OAAK,WAAU;iBACZ,EAAE,eAAe;OACd,CAAA;MAEP,EAAA,CAAA,CAED;OACS;MACT;;EACN,CAAA;;;;AClTV,SAAgB,eAAe,EAC7B,MACA,cACA,QACgD;CAChD,MAAM,EAAE,MAAM,wBAAwB;CACtC,MAAM,aAAa,eAAe;CAKlC,MAAM,CAAC,wBAAwB,6BAC7B,SAAgC,KAAK;AAEvC,KAAI,CAAC,KAAM,QAAO;CAElB,MAAM,gBAAgB,WAAoD;AACxE,aAAW,OACT;GACE,IAAI,KAAK;GACT,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,WAAW,KAAK;GACjB,EACD,EACE,iBAAiB,aAAa,MAAM,EACrC,CACF;;AAGH,QACE,oBAAC,QAAD;EAAc;EAAoB;YAChC,qBAAC,eAAD;GAAe,WAAU;aAAzB;IACE,oBAAC,cAAD,EAAA,UACE,oBAAC,aAAD,EAAA,UAAc,EAAE,YAAY,EAAe,CAAA,EAC9B,CAAA;IACf,oBAAC,yBAAD;KAAyB,WAAW;eAClC,oBAAC,kBAAD;MAEE,aAAa,KAAK;MAClB,cAAc,KAAK;MACnB,UAAU;MACV,cAAc,WAAW;MACzB,aAAa,EAAE,eAAe;MAC9B,iBAAiB,EAAE,SAAS;MAC5B,EAPK,KAAK,GAOV;KACsB,CAAA;IAC1B,oBAAC,OAAD;KACE,KAAK;KACL,WAAU;KACV,CAAA;IACY;;EACT,CAAA;;;;;;;;ACvBb,MAAM,mCAAmB,IAAI,KAA+B;AAE5D,SAAS,uBAAuB,QAAgB,OAAwB;CACtE,MAAM,MAAM,OAAO,QAAQ,MAAM,IAAI;CACrC,IAAI,QAAQ,iBAAiB,IAAI,IAAI;AACrC,KAAI,CAAC,OAAO;AACV,UAAQ,IAAI,KAAK,YAAY,IAAI;AACjC,mBAAiB,IAAI,KAAK,MAAM;;AAGlC,QAAO,MAAM,OAAO,MAAM,KAAK;;;;;;;;;;;;AAiCjC,SAAS,YAAY,SAAiB,QAAyB;CAC7D,MAAM,mBAAmB,QAAQ,QAAQ,MAAM,IAAI,IAAI;AAMvD,KACE,gBAAgB,KAAK,QAAQ,IAC7B,CAAC,2BAA2B,KAAK,QAAQ,EACzC;EACA,MAAM,QAAQ,2BAA2B,KAAK,QAAQ;AACtD,MAAI,QAAQ,MAAM,MAAM,MAAM,MAAM,GAIlC,QAHa,IAAI,KACf,KAAK,IAAI,OAAO,MAAM,GAAG,EAAE,OAAO,MAAM,GAAG,GAAG,GAAG,OAAO,MAAM,GAAG,CAAC,CACnE,CACW,mBAAmB,kBAAkB;GAC/C,OAAO;GACP,KAAK;GACL,UAAU;GACX,CAAC;;AAON,QADa,IAAI,KAAK,QAAQ,CAClB,eAAe,kBAAkB;EAC3C,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT,CAAC;;AAGJ,SAAgB,WAAW,EAEzB,eAAe,MACf,YAAY,SACZ,gBAAgB,MAChB,aAAa,cAGb,aAAa;CACX,MAAM;CACN,OAAO;CACR,EACD,YAAY,cACZ,cAAc,WACd,UAAU,GACV,eAAe,MACf,cAAc,QACd,cAAc,SAGd,WAAW,GAEX,WACA,GAAG,SACkC;CACrC,MAAM,EAAE,GAAG,WAAW,wBAAwB;CAC9C,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,mBACH,WAAW,UAAU,aAAa,WAAW,UAAU,aACxD,WAAW,SAAS,UAChB,OAAO,WAAW,SAAS,aAAa,WAAW,SAAS,SAAS,KACrE;CACN,MAAM,EAAE,MAAM,QAAQ,EAAE,EAAE,WAAW,YAAY,UAAU;CAC3D,MAAM,EAAE,MAAM,iBAAiB,EAAE,EAAE,WAAW,uBAAuB,SACnE,EAAE,OAAO,aAAa,CACvB;CACD,MAAM,aAAa,eAAe;CAClC,MAAM,aAAa,eAAe;CAClC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,CAAC,YAAY,iBAAiB,yBAAsB,IAAI,KAAK,CAAC;CACpE,MAAM,CAAC,oBAAoB,yBAAyB,SAAS,MAAM;CACnE,MAAM,CAAC,aAAa,kBAAkB,SAAsB,KAAK;CACjE,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAE3D,MAAM,cAAc,MAAY,cAAuB;AACrD,MAAI,aAAa,WAAW,IAAI,KAAK,GAAG,CAAE;AAC1C,iBAAe,SAAS,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;AACnD,aAAW,OACT;GAAE,IAAI,KAAK;GAAI;GAAW,WAAW,KAAK;GAAW,EACrD,EACE,iBACE,eAAe,SAAS;GACtB,MAAM,OAAO,IAAI,IAAI,KAAK;AAC1B,QAAK,OAAO,KAAK,GAAG;AACpB,UAAO;IACP,EACL,CACF;;CAGH,MAAM,cAAc,MAAM,QAAQ,SAAS,CAAC,KAAK,YAAY;CAC7D,MAAM,cAAc,YAAY,MAAM,GAAG,SAAS;CAClD,MAAM,iBAAiB,YAAY,SAAS,YAAY;CACxD,MAAM,UAAU,YAAY,WAAW;CAGvC,MAAM,eAAe,YAAY,QAM9B,QAAQ,SAAS;EAClB,MAAM,WAAW,OAAO,MAAM,MAAM,EAAE,cAAc,KAAK,UAAU;AACnE,MAAI,SACF,UAAS,MAAM,KAAK,KAAK;MAEzB,QAAO,KAAK;GACV,WAAW,KAAK;GAChB,aAAa,KAAK;GAClB,OAAO,CAAC,KAAK;GACd,CAAC;AAEJ,SAAO;IACN,EAAE,CAAC;CAEN,MAAM,YAAY,eAAe;CAEjC,MAAM,kBAAkB,SAAe;AACrC,MAAI,UAAW;AACf,iBAAe,KAAK;;CAGtB,MAAM,gBAAgB,SAAe;AACnC,MAAI,UAAW;AACf,aAAW,OAAO;GAAE,IAAI,KAAK;GAAI,WAAW,KAAK;GAAW,CAAC;;AAG/D,QACE,qBAAC,OAAD;EACE,WAAW,2BAA2B,aAAa,GAAG,mBAAmB,aAAa,GAAG,gBAAgB,SAAS,mBAAmB,eAAe,GAAG,MAAM,gBAAgB,QAAQ,UAAU,KAAK,QAAQ,GAAG,aAAa;EAC5N,OAAO,EAAE,iBAAiB;EAC1B,GAAI;YAHN;GAME,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eACZ,gBAAgB,aACf,oBAAC,MAAD;MACE,WAAW,QAAQ,cAAc,8BAA8B;gBAE9D;MACE,CAAA;KAEH,CAAA,EACN,qBAAC,OAAD;KAAK,WAAU;eAAf,CACG,CAAC,WAAW,CAAC,aACZ,oBAAC,QAAD;MAAM,WAAW,2BAA2B;gBACzC,YAAY;MACR,CAAA,EAET,oBAAC,OAAD;MAAK,WAAW;gBACd,oBAAC,YAAD,EAAY,WAAW,gBAAgB,YAAY,cAAgB,CAAA;MAC/D,CAAA,CACF;OACF;;GAGL,YACC,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,OAAD,EAAK,WAAU,iFAAkF,CAAA;IAC7F,CAAA,GACJ,UAEF,oBAAC,YAAD,EAAc,CAAA,GACZ,UAEF,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,KAAD;KAAG,WAAW,oBAAoB,UAAU;eACzC,EAAE,aAAa;KACd,CAAA,EACH,CAAC,aACA,qBAAC,UAAD;KACE,MAAK;KACL,eAAe,sBAAsB,KAAK;KAC1C,WAAW,oDAAoD,YAAY,QAAQ,YAAY,uBAAuB,YAAY;eAHpI,CAKE,oBAAC,MAAD;MAAM,WAAU;MAAW,eAAY;MAAS,CAAA,EAC/C,EAAE,WAAW,CACP;OAEP;QAGN,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,OAAD;IAAK,WAAU;cACZ,aAAa,KAAK,UACjB,qBAAC,OAAD;KAEE,WAAU;eAFZ,CAIG,MAAM,eACL,oBAAC,OAAD;MACE,WAAW,2DAA2D,UAAU;gBAE/E,MAAM;MACH,CAAA,EAEP,MAAM,MAAM,KAAK,MAAM,UAAU;AAEhC,aACE,qBAAC,OAAD;OAEE,WAAW,0CAJU,UAAU,MAAM,MAAM,SAAS,IAM9C,mBAAmB,UAAU,OAC7B;iBALR;QAQE,oBAAC,SAAD;SACE,MAAK;SACL,WAAW,wCAAwC,UAAU;SAC7D,SAAS,CAAC,CAAC,KAAK;SAChB,UAAU,aAAa,WAAW,IAAI,KAAK,GAAG;SAC9C,WAAW,UACT,WAAW,MAAM,MAAM,OAAO,QAAQ;SAExC,UAAU,UAAU,MAAM,iBAAiB;SAC3C,cAAY,EAAE,oBAAoB;SAClC,CAAA;QACF,qBAAC,UAAD;SACE,MAAK;SACL,eAAe,eAAe,KAAK;SACnC,UAAU;SACV,cAAY,EAAE,YAAY;SAC1B,WAAU;mBALZ,CAOE,oBAAC,QAAD;UAAM,WAAU;oBACb,cAAc,KAAK,KAAK,CAAC;UACrB,CAAA,EACN,KAAK,SACJ,oBAAC,QAAD;UAAM,WAAW,gBAAgB,UAAU;oBACxC,YAAY,KAAK,OAAO,OAAO;UAC3B,CAAA,CAEF;;QACR,CAAC,aACA,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;SAAqB,SAAA;mBACnB,oBAAC,QAAD;UACE,SAAQ;UACR,MAAK;UACL,UAAU,UAAU,MAAM,iBAAiB;UAC3C,cAAY,EAAE,eAAe;UAC7B,WAAU;oBAEV,oBAAC,kBAAD,EAAkB,WAAU,UAAW,CAAA;UAChC,CAAA;SACW,CAAA,EACtB,qBAAC,qBAAD;SAAqB,OAAM;mBAA3B,CACE,oBAAC,kBAAD;UACE,UAAU,UAAU;AAClB,iBAAM,iBAAiB;AACvB,0BAAe,KAAK;;oBAGrB,EAAE,YAAY;UACE,CAAA,EACnB,oBAAC,kBAAD;UACE,WAAU;UACV,UAAU,UAAU;AAClB,iBAAM,iBAAiB;AACvB,wBAAa,KAAK;;oBAGnB,EAAE,cAAc;UACA,CAAA,CACC;WACT,EAAA,CAAA;QAEb;SApEC,KAAK,GAoEN;OAER,CACE;OArFC,MAAM,aAAa,iBAqFpB,CACN;IACE,CAAA,EAGN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,iBAAiB,KAChB,oBAAC,QAAD;KAAM,WAAW,gBAAgB,UAAU;eACxC,uBAAuB,QAAQ,eAAe,GAC3C,EAAE,uBAAuB,EAAE,OAAO,gBAAgB,CAAC,GACnD,EAAE,yBAAyB,EAAE,OAAO,gBAAgB,CAAC;KACpD,CAAA,EAET,oBAAC,OAAD;KAAK,WAAU;eACb,oBAAC,UAAD;MACE,MAAK;MACL,eAAe,sBAAsB,KAAK;MAC1C,UAAU;MACV,cAAY,EAAE,WAAW;MACzB,WAAW,gHAAgH,UAAU;gBAErI,oBAAC,MAAD,EAAM,WAAW,gBAAgB,UAAU,MAAQ,CAAA;MAC5C,CAAA;KACL,CAAA,CACF;MACL,EAAA,CAAA;GAIJ,CAAC,aACA,CAAC,aACD,CAAC,WACD,CAAC,sBACD,YAAY,KACV,qBAAC,OAAD;IAAK,WAAW,wBAAwB,UAAU;cAAlD,CACE,qBAAC,UAAD;KACE,MAAK;KACL,eAAe,mBAAmB,MAAM,CAAC,EAAE;KAC3C,WAAW,2FAA2F,UAAU,eAAe,UAAU;KACzI,iBAAe;eAJjB,CAME,oBAAC,QAAD,EAAA,UACG,iBACG,EAAE,YAAY,GACd,EAAE,aAAa,EAAE,OAAO,WAAW,CAAC,EACnC,CAAA,EACN,iBACC,oBAAC,WAAD;MAAW,WAAU;MAAS,eAAY;MAAS,CAAA,GAEnD,oBAAC,aAAD;MAAa,WAAU;MAAS,eAAY;MAAS,CAAA,CAEhD;QACR,kBACC,oBAAC,OAAD;KAAK,WAAU;eACZ,eAAe,KAAK,MAAM,UACzB,qBAAC,OAAD;MAEE,WAAW,0CACT,UAAU,eAAe,SAAS,IAC9B,mBAAmB,UAAU,OAC7B;gBALR;OAQE,oBAAC,SAAD;QACE,MAAK;QACL,WAAW,wCAAwC,UAAU;QAC7D,SAAA;QACA,UAAU,WAAW,IAAI,KAAK,GAAG;QACjC,gBAAgB,WAAW,MAAM,MAAM;QACvC,UAAU,UAAU,MAAM,iBAAiB;QAC3C,cAAY,EAAE,eAAe;QAC7B,CAAA;OACF,qBAAC,UAAD;QACE,MAAK;QACL,eAAe,eAAe,KAAK;QACnC,cAAY,EAAE,YAAY;QAC1B,WAAW,kFAAkF,UAAU;kBAJzG,CAME,oBAAC,QAAD;SAAM,WAAU;mBACb,cAAc,KAAK,KAAK,CAAC;SACrB,CAAA,EACN,KAAK,SACJ,oBAAC,QAAD;SAAM,WAAU;mBACb,YAAY,KAAK,OAAO,OAAO;SAC3B,CAAA,CAEF;;OACT,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;QAAqB,SAAA;kBACnB,oBAAC,QAAD;SACE,SAAQ;SACR,MAAK;SACL,UAAU,UAAU,MAAM,iBAAiB;SAC3C,cAAY,EAAE,eAAe;SAC7B,WAAU;mBAEV,oBAAC,kBAAD,EAAkB,WAAU,UAAW,CAAA;SAChC,CAAA;QACW,CAAA,EACtB,qBAAC,qBAAD;QAAqB,OAAM;kBAA3B,CACE,oBAAC,kBAAD;SACE,UAAU,UAAU;AAClB,gBAAM,iBAAiB;AACvB,yBAAe,KAAK;;mBAGrB,EAAE,YAAY;SACE,CAAA,EACnB,oBAAC,kBAAD;SACE,WAAU;SACV,UAAU,UAAU;AAClB,gBAAM,iBAAiB;AACvB,uBAAa,KAAK;;mBAGnB,EAAE,cAAc;SACA,CAAA,CACC;UACT,EAAA,CAAA;OACX;QA/DC,KAAK,GA+DN,CACN;KACE,CAAA,CAEJ;;GAGT,CAAC,aACA,oBAAC,kBAAD;IACE,MAAM;IACN,cAAc;IACd,CAAA;GAEH,CAAC,aACA,oBAAC,gBAAD;IACE,MAAM,gBAAgB;IACtB,eAAe,SAAS;AACtB,SAAI,CAAC,KAAM,gBAAe,KAAK;;IAEjC,MAAM;IACN,CAAA;GAEA;;;AAIV,MAAa,2BAAiD;CAC5D,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD,iBAAiB;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EACF,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EAGF;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ToDoWidget-CgFDCQNX.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","contactsKeys","useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","contactsKeys","useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","contactsKeys","Avatar","AvatarImage","AvatarFallback","UserRound","useContactsTranslation","Dialog","DialogContent","DialogHeader","DialogTitle","PortalContainerProvider","TaskComposerForm","useInfiniteContacts","Popover","PopoverTrigger","cn","PopoverContent","Search","Input","Check","useContactsTranslation","Dialog","DialogContent","DialogHeader","DialogTitle","PortalContainerProvider","TaskComposerForm","ALL_DAY_PATTERN","LOCAL_TIMED_DUE_AT_PATTERN","useContactsTranslation","useWidgetPreviewContext","borderWidthClasses","borderColorClasses","ListChecks","ErrorState","Plus","parseTaskBody","DropdownMenu","DropdownMenuTrigger","Button","EllipsisVertical","DropdownMenuContent","DropdownMenuItem","ChevronUp","ChevronDown","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../widgets/src/hooks/use-todos.preview.ts","../../widgets/src/hooks/use-todos.ts","../../widgets/src/hooks/use-update-todo.ts","../../widgets/src/hooks/use-delete-todo.ts","../../widgets/src/hooks/use-create-todo.ts","../../widgets/src/widgets/CreateTodoDialog.tsx","../../widgets/src/widgets/EditTodoDialog.tsx","../../widgets/src/widgets/ToDoWidget.tsx"],"sourcesContent":["import type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nexport const PREVIEW_DATA: Todo[] = [\n {\n id: 1,\n body: \"Send follow-up email to new leads\",\n dueAt: daysFromNow(1),\n completedAt: null,\n createdAt: daysFromNow(-2),\n contactId: 101,\n contactName: \"Sarah Johnson\",\n },\n {\n id: 2,\n body: \"Prepare slides for team training\",\n dueAt: daysFromNow(3),\n completedAt: null,\n createdAt: daysFromNow(-1),\n contactId: null,\n contactName: null,\n },\n {\n id: 3,\n body: \"Review monthly sales report\",\n dueAt: daysFromNow(-1),\n completedAt: null,\n createdAt: daysFromNow(-5),\n contactId: 102,\n contactName: \"Mike Chen\",\n },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport type { TodosStateFilter } from \"@fluid-app/portal-core/widgets-api\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-todos.preview\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nexport type { TodosStateFilter } from \"@fluid-app/portal-core/widgets-api\";\n\n/**\n * Shared cache key for the todos list. Both useTodos (read) and\n * useUpdateTodo (write) use this — drift would silently break optimistic\n * updates. The `state` arg is included so the active/completed lists\n * cache independently.\n */\nexport function todosQueryKey(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n state?: TodosStateFilter;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n args.state ?? \"incomplete\",\n ] as const;\n}\n\nexport function todosQueryKeyPrefix(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n ] as const;\n}\n\nexport interface UseTodosOptions {\n state?: TodosStateFilter;\n}\n\nexport function useTodos(\n options?: UseTodosOptions,\n): UseQueryResult<Todo[], Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n const state = options?.state;\n\n return useQuery({\n queryKey: todosQueryKey(\n state !== undefined\n ? { baseUrl, isPreview, state }\n : { baseUrl, isPreview },\n ),\n queryFn: ({ signal }) =>\n widgetsApi.fetchTodos(\n state !== undefined ? { state } : undefined,\n signal,\n ),\n enabled: !isPreview,\n ...(isPreview &&\n (state === undefined || state === \"incomplete\") && {\n placeholderData: PREVIEW_DATA,\n }),\n ...(isPreview &&\n state !== undefined &&\n state !== \"incomplete\" && {\n placeholderData: [],\n }),\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey, todosQueryKeyPrefix } from \"./use-todos\";\n\nexport interface UpdateTodoVariables {\n id: number;\n body?: string;\n due_at?: string | null;\n completed?: boolean;\n /**\n * Used to invalidate `contactsKeys.tasks(contactId)` after a successful\n * update so the in-contact tasks view stays in sync.\n */\n contactId?: number | null;\n}\n\nexport function useUpdateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id, body, due_at, completed }: UpdateTodoVariables) => {\n // Defense in depth: ToDoWidget already disables the checkbox in\n // preview mode, but if any other caller fires this mutation while\n // previewing we'd PATCH demo data on the real backend. Fail closed.\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo updates are disabled in preview mode\"),\n );\n }\n const input: {\n body?: string;\n due_at?: string | null;\n completed?: boolean;\n } = {};\n if (body !== undefined) input.body = body;\n if (due_at !== undefined) input.due_at = due_at;\n if (completed !== undefined) input.completed = completed;\n return widgetsApi.updateTodo(id, input);\n },\n onMutate: async (variables) => {\n // Only apply the optimistic-completion shortcut when the caller is\n // toggling completion alone (the checkbox case). Body/due_at edits\n // come from the dialog and fall back to invalidate-on-success.\n const isCompletionToggle =\n variables.completed !== undefined &&\n variables.body === undefined &&\n variables.due_at === undefined;\n if (!isCompletionToggle) return { previous: undefined };\n\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === variables.id\n ? {\n ...todo,\n completedAt: variables.completed\n ? new Date().toISOString()\n : null,\n }\n : todo,\n ),\n );\n return { previous };\n },\n onSuccess: (updated, variables) => {\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === updated.id ? updated : todo,\n ),\n );\n // Match the documented test plan: completing toasts, un-completing\n // is silent. Body/due_at edits also toast as \"Todo updated\".\n const isCompletionToggle =\n variables.completed !== undefined &&\n variables.body === undefined &&\n variables.due_at === undefined;\n if (isCompletionToggle) {\n if (variables.completed) {\n fluidToast({ title: \"Todo completed\", type: \"success\" });\n }\n } else {\n fluidToast({ title: \"Todo updated\", type: \"success\" });\n }\n // Keep the contact-scoped tasks view in sync when the todo is\n // attached to a contact.\n if (variables.contactId != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contactId)),\n });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to update todo\", type: \"error\" });\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKeyPrefix({ baseUrl, isPreview }),\n });\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey, todosQueryKeyPrefix } from \"./use-todos\";\n\nexport interface DeleteTodoVariables {\n id: number;\n /**\n * Used to invalidate `contactsKeys.tasks(contactId)` after a successful\n * delete so the in-contact tasks view stays in sync.\n */\n contactId?: number | null;\n}\n\nexport function useDeleteTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id }: DeleteTodoVariables) => {\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo deletion is disabled in preview mode\"),\n );\n }\n return widgetsApi.deleteTodo(id);\n },\n onMutate: async ({ id }) => {\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).filter((todo) => todo.id !== id),\n );\n return { previous };\n },\n onSuccess: (_result, variables) => {\n fluidToast({ title: \"Todo deleted\", type: \"success\" });\n if (variables.contactId != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contactId)),\n });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to delete todo\", type: \"error\" });\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKeyPrefix({ baseUrl, isPreview }),\n });\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { contactsKeys } from \"@fluid-app/contacts-core/query-keys\";\nimport { todosQueryKey } from \"./use-todos\";\n\nexport interface CreateTodoVariables {\n body: string;\n due_at: string | null;\n contact_id: number | null;\n}\n\nexport function useCreateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useMutation({\n mutationFn: (variables: CreateTodoVariables) => {\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo creation is disabled in preview mode\"),\n );\n }\n return widgetsApi.createTodo(variables);\n },\n onSuccess: (_created, variables) => {\n fluidToast({ title: \"Todo created\", type: \"success\" });\n queryClient.invalidateQueries({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n });\n if (variables.contact_id != null) {\n queryClient.invalidateQueries({\n queryKey: contactsKeys.tasks(String(variables.contact_id)),\n });\n }\n },\n onError: () => {\n fluidToast({ title: \"Failed to create todo\", type: \"error\" });\n },\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Check, Search, UserRound } from \"lucide-react\";\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n cn,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport { useCreateTodo } from \"../hooks/use-create-todo\";\n\nconst SEARCH_DEBOUNCE_MS = 200;\n\nfunction getContactInitials(contact: Contact): string | undefined {\n const firstInitial = contact.first_name?.trim().charAt(0);\n const lastInitial = contact.last_name?.trim().charAt(0);\n const explicitInitials = `${firstInitial ?? \"\"}${lastInitial ?? \"\"}`;\n\n if (explicitInitials) return explicitInitials.toUpperCase();\n\n const initials = contact.full_name\n .trim()\n .split(/\\s+/)\n .slice(0, 2)\n .map((part) => part.charAt(0))\n .join(\"\")\n .toUpperCase();\n\n return initials || undefined;\n}\n\nfunction ContactBadgeAvatar({\n contact,\n}: {\n contact: Contact | null;\n}): React.JSX.Element {\n const initials = contact ? getContactInitials(contact) : undefined;\n\n return (\n <Avatar className=\"size-4 text-current\" aria-hidden=\"true\">\n {contact?.avatar_url ? (\n <AvatarImage src={contact.avatar_url} alt=\"\" />\n ) : null}\n <AvatarFallback className=\"bg-transparent text-[0.625rem] font-semibold text-current\">\n {initials ?? <UserRound className=\"size-3\" aria-hidden=\"true\" />}\n </AvatarFallback>\n </Avatar>\n );\n}\n\nexport interface CreateTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function CreateTodoDialog({\n open,\n onOpenChange,\n}: CreateTodoDialogProps): React.JSX.Element {\n const [selectedContact, setSelectedContact] = useState<Contact | null>(null);\n // Anchor nested popovers inside the dialog's themed portal subtree.\n // ui-primitives PopoverContent reads this via usePortalContainer(), so the\n // task date popover inherits portal theme variables instead of falling back\n // to document.body. Dialog also applies pointer-events: none to the body\n // while open, which kills clicks and scroll on a body-portaled popover in\n // WebKit. See edit-bill-date-dialog for the canonical pattern.\n const [themedPopoverContainer, setThemedPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n const { t } = useContactsTranslation();\n\n const createTodo = useCreateTodo();\n\n // Reset state when the dialog closes so the next open starts fresh.\n useEffect(() => {\n if (!open) setSelectedContact(null);\n }, [open]);\n\n const handleSubmit = (values: { body: string; due_at: string | null }) => {\n createTodo.mutate(\n {\n body: values.body,\n due_at: values.due_at,\n contact_id: selectedContact ? selectedContact.id : null,\n },\n {\n onSuccess: () => onOpenChange(false),\n },\n );\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-xl sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>{t(\"add_todo_dialog_title\")}</DialogTitle>\n </DialogHeader>\n\n <PortalContainerProvider container={themedPopoverContainer}>\n <div className=\"mt-2 flex flex-col gap-3\">\n <TaskComposerForm\n onSubmit={handleSubmit}\n isSubmitting={createTodo.isPending}\n metadataControls={\n <ContactPicker\n value={selectedContact}\n onSelect={setSelectedContact}\n onClear={() => setSelectedContact(null)}\n />\n }\n />\n </div>\n </PortalContainerProvider>\n {/* Portal target for the popover. Must live INSIDE DialogContent so\n it ends up in the dialog's body-level portal — otherwise it\n renders inline next to the widget, and any transformed ancestor\n (builder canvas zoom, etc.) would break `position: fixed`.\n Intentionally NOT aria-hidden — the popover content portaled\n into this container has its own listbox/option semantics that\n screen readers need to reach. `pointer-events-none` keeps the\n empty overlay from capturing clicks; the popover content sets\n `pointer-events-auto` so it remains interactive. */}\n <div\n ref={setThemedPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ContactPickerProps {\n value: Contact | null;\n onSelect: (contact: Contact) => void;\n onClear: () => void;\n}\n\nfunction ContactPicker({\n value,\n onSelect,\n onClear,\n}: ContactPickerProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, SEARCH_DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const queryParams = useMemo(\n () => ({\n ...(debouncedSearch ? { search_query: debouncedSearch } : {}),\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 25,\n }),\n [debouncedSearch],\n );\n\n const {\n data,\n isLoading,\n isError,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n // Auto-load the next page when the sentinel scrolls into view, so reps\n // with many contacts can reach all of them without typing a precise\n // search query.\n useEffect(() => {\n if (!open) return;\n\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 }, [open, hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n const selectedContactLabel = value ? value.full_name : t(\"select_contact\");\n\n return (\n <div className=\"flex min-w-0 items-center\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={t(\"contact_picker_trigger_aria\", {\n selection: selectedContactLabel,\n })}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n className={cn(\n \"flex max-w-40 min-w-0 shrink items-center gap-1 rounded-full px-3 py-1 text-left text-xs font-medium transition-colors\",\n value\n ? \"bg-primary text-primary-foreground\"\n : \"bg-muted text-muted-foreground hover:bg-muted/70\",\n )}\n >\n <ContactBadgeAvatar contact={value} />\n <span className=\"min-w-0 truncate\">{selectedContactLabel}</span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"bg-popover text-popover-foreground pointer-events-auto z-[9999] w-72 max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border p-0 shadow-md\"\n >\n <div className=\"border-border flex items-center gap-2 border-b px-3 py-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 aria-label={t(\"search_placeholder\")}\n className=\"h-7 border-0 px-0 shadow-none focus-visible:ring-0\"\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto py-1\" role=\"listbox\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={value === null}\n onClick={() => {\n onClear();\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"text-muted-foreground truncate italic\">\n {t(\"no_contact\")}\n </span>\n {value === null && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n {isLoading ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {t(\"loading\")}\n </div>\n ) : isError ? (\n <div className=\"text-destructive px-3 py-6 text-center text-xs\">\n {t(\"error_loading_list\")}\n </div>\n ) : contacts.length === 0 ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : t(\"no_contacts_yet\")}\n </div>\n ) : (\n <>\n {contacts.map((contact) => {\n const isSelected = value?.id === contact.id;\n return (\n <button\n key={contact.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n onSelect(contact);\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"truncate\">{contact.full_name}</span>\n {isSelected && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground px-3 py-2 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\n\nexport interface EditTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n todo: Todo | null;\n}\n\nexport function EditTodoDialog({\n open,\n onOpenChange,\n todo,\n}: EditTodoDialogProps): React.JSX.Element | null {\n const { t } = useContactsTranslation();\n const updateTodo = useUpdateTodo();\n // Anchor nested popovers inside the dialog's themed portal subtree.\n // ui-primitives PopoverContent reads this via usePortalContainer(), so the\n // task date popover inherits portal theme variables instead of falling back\n // to document.body.\n const [themedPopoverContainer, setThemedPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n\n if (!todo) return null;\n\n const handleSubmit = (values: { body: string; due_at: string | null }) => {\n updateTodo.mutate(\n {\n id: todo.id,\n body: values.body,\n due_at: values.due_at,\n contactId: todo.contactId,\n },\n {\n onSuccess: () => onOpenChange(false),\n },\n );\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-md sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>{t(\"edit_todo\")}</DialogTitle>\n </DialogHeader>\n <PortalContainerProvider container={themedPopoverContainer}>\n <TaskComposerForm\n key={todo.id}\n initialBody={todo.body}\n initialDueAt={todo.dueAt}\n onSubmit={handleSubmit}\n isSubmitting={updateTodo.isPending}\n submitLabel={t(\"save_changes\")}\n submittingLabel={t(\"saving\")}\n />\n </PortalContainerProvider>\n <div\n ref={setThemedPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n","import { useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport {\n Button,\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 {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport {\n ChevronDown,\n ChevronUp,\n EllipsisVertical,\n ListChecks,\n Plus,\n} from \"lucide-react\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport {\n ALL_DAY_PATTERN,\n LOCAL_TIMED_DUE_AT_PATTERN,\n} from \"@fluid-app/contacts-ui/portal/utils/format-date\";\nimport { useTodos } from \"../hooks/use-todos\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\nimport { useDeleteTodo } from \"../hooks/use-delete-todo\";\nimport { ErrorState } from \"../components/error-state\";\nimport { CreateTodoDialog } from \"./CreateTodoDialog\";\nimport { EditTodoDialog } from \"./EditTodoDialog\";\n\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nfunction usesSingularPluralForm(locale: string, count: number): boolean {\n const tag = locale.replace(/_/g, \"-\");\n let rules = pluralRulesCache.get(tag);\n if (!rules) {\n rules = new Intl.PluralRules(tag);\n pluralRulesCache.set(tag, rules);\n }\n\n return rules.select(count) === \"one\";\n}\n\ntype ToDoWidgetProps = ComponentProps<\"div\"> & {\n // Title\n titleEnabled?: boolean;\n titleText?: string;\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content\n maxItems?: number;\n};\n\n/**\n * Format a todo due_at ISO string as a short date + time (e.g. \"Jun 1, 9:00 AM\").\n * Mirrors the mobile widget formatting.\n *\n * All-day / date-only values (bare YYYY-MM-DD or timezone-qualified ISO strings\n * whose time component is 00:00) are formatted in UTC so the displayed calendar\n * date matches the source prefix without shifting. Local timed values produced\n * by the task composer, including explicit 00:00, use a single locale-native\n * formatter with both date and time parts.\n */\nfunction formatDueAt(dateStr: string, locale?: string): string {\n const normalizedLocale = locale?.replace(/_/g, \"-\") ?? \"en-US\";\n\n // Detect date-only / all-day: bare YYYY-MM-DD or timezone-qualified ISO whose\n // time is exactly 00:00 (including fractional seconds and offset variants like\n // 2024-06-01T00:00:00.000+02:00). Local timed strings from the task composer\n // remain timed, so 2024-06-01T00:00:00 displays 12:00 AM instead of all-day.\n if (\n ALL_DAY_PATTERN.test(dateStr) &&\n !LOCAL_TIMED_DUE_AT_PATTERN.test(dateStr)\n ) {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(dateStr);\n if (match?.[1] && match[2] && match[3]) {\n const date = new Date(\n Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])),\n );\n return date.toLocaleDateString(normalizedLocale, {\n month: \"short\",\n day: \"numeric\",\n timeZone: \"UTC\",\n });\n }\n }\n\n // Genuinely timed value — use a single formatter so ordering and\n // separators are locale-native.\n const date = new Date(dateStr);\n return date.toLocaleString(normalizedLocale, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n}\n\nexport function ToDoWidget({\n // Title defaults\n titleEnabled = true,\n titleText = \"To-Do\",\n titleFontSize = \"lg\",\n titleColor = \"foreground\",\n\n // Styling defaults\n background = {\n type: \"solid\",\n color: \"background\",\n },\n textColor = \"foreground\",\n accentColor = \"primary\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n\n // Content defaults\n maxItems = 5,\n\n className,\n ...props\n}: ToDoWidgetProps): React.JSX.Element {\n const { t, locale } = useContactsTranslation();\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n const { data: todos = [], isLoading, isError } = useTodos();\n const { data: completedTodos = [], isLoading: isCompletedLoading } = useTodos(\n { state: \"completed\" },\n );\n const updateTodo = useUpdateTodo();\n const deleteTodo = useDeleteTodo();\n const { isPreview } = useWidgetPreviewContext();\n const [pendingIds, setPendingIds] = useState<Set<number>>(new Set());\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n const [editingTodo, setEditingTodo] = useState<Todo | null>(null);\n const [isDoneExpanded, setIsDoneExpanded] = useState(false);\n\n const toggleTodo = (todo: Todo, completed: boolean) => {\n if (isPreview || pendingIds.has(todo.id)) return;\n setPendingIds((prev) => new Set(prev).add(todo.id));\n updateTodo.mutate(\n { id: todo.id, completed, contactId: todo.contactId },\n {\n onSettled: () =>\n setPendingIds((prev) => {\n const next = new Set(prev);\n next.delete(todo.id);\n return next;\n }),\n },\n );\n };\n\n const activeTodos = todos.filter((todo) => !todo.completedAt);\n const todosToShow = activeTodos.slice(0, maxItems);\n const remainingCount = activeTodos.length - todosToShow.length;\n const isEmpty = activeTodos.length === 0;\n\n // Group todos by contactId so same-named contacts stay separate.\n const groupedTodos = todosToShow.reduce<\n {\n contactId: number | null;\n contactName: string | null;\n todos: typeof todosToShow;\n }[]\n >((groups, todo) => {\n const existing = groups.find((g) => g.contactId === todo.contactId);\n if (existing) {\n existing.todos.push(todo);\n } else {\n groups.push({\n contactId: todo.contactId,\n contactName: todo.contactName,\n todos: [todo],\n });\n }\n return groups;\n }, []);\n\n const doneCount = completedTodos.length;\n\n const handleRowClick = (todo: Todo) => {\n if (isPreview) return;\n setEditingTodo(todo);\n };\n\n const handleDelete = (todo: Todo) => {\n if (isPreview) return;\n deleteTodo.mutate({ id: todo.id, contactId: todo.contactId });\n };\n\n return (\n <div\n className={`overflow-hidden rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} text-${textColor} p-${padding} ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {titleEnabled && titleText && (\n <h2\n className={`text-${titleFontSize} font-header font-bold text-${titleColor}`}\n >\n {titleText}\n </h2>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {!isEmpty && !isLoading && (\n <span className={`text-2xl font-bold text-${accentColor}`}>\n {activeTodos.length}\n </span>\n )}\n <div className={`flex size-10 shrink-0 items-center justify-center`}>\n <ListChecks className={`h-5 w-5 text-${accentColor}-foreground`} />\n </div>\n </div>\n </div>\n\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex min-h-[120px] items-center justify-center\">\n <div className=\"size-6 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n </div>\n ) : isError ? (\n /* Error state */\n <ErrorState />\n ) : isEmpty ? (\n /* Empty state */\n <div className=\"flex flex-col items-center justify-center gap-3 py-8\">\n <p className={`text-center text-${textColor}/60`}>\n {t(\"todo_empty\")}\n </p>\n {!isPreview && (\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n className={`inline-flex items-center gap-1.5 rounded-full bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 px-4 py-1.5 text-xs font-semibold transition-colors`}\n >\n <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n {t(\"add_todo\")}\n </button>\n )}\n </div>\n ) : (\n /* Todo List */\n <>\n <div className=\"flex flex-col gap-3\">\n {groupedTodos.map((group) => (\n <div\n key={group.contactId ?? \"__unassigned__\"}\n className=\"flex flex-col\"\n >\n {group.contactName && (\n <div\n className={`mb-1 text-xs font-semibold tracking-wide uppercase text-${textColor}/60`}\n >\n {group.contactName}\n </div>\n )}\n {group.todos.map((todo, index) => {\n const showBottomBorder = index !== group.todos.length - 1;\n return (\n <div\n key={todo.id}\n className={`group/row flex items-center gap-3 py-2 ${\n showBottomBorder\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked={!!todo.completedAt}\n disabled={isPreview || pendingIds.has(todo.id)}\n onChange={(event) =>\n toggleTodo(todo, event.target.checked)\n }\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"mark_as_completed\")}\n />\n <button\n type=\"button\"\n onClick={() => handleRowClick(todo)}\n disabled={isPreview}\n aria-label={t(\"edit_todo\")}\n className=\"flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left not-disabled:cursor-pointer\"\n >\n <span className=\"line-clamp-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n {todo.dueAt && (\n <span className={`text-xs text-${textColor}/60`}>\n {formatDueAt(todo.dueAt, locale)}\n </span>\n )}\n </button>\n {!isPreview && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"task_actions\")}\n className=\"opacity-60 transition-opacity group-hover/row:opacity-100 focus-visible:opacity-100\"\n >\n <EllipsisVertical className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={(event) => {\n event.stopPropagation();\n handleRowClick(todo);\n }}\n >\n {t(\"edit_todo\")}\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n handleDelete(todo);\n }}\n >\n {t(\"delete_todo\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n\n {/* Footer */}\n <div className=\"mt-2 flex items-center justify-between\">\n {remainingCount > 0 && (\n <span className={`text-sm text-${textColor}/50 underline`}>\n {usesSingularPluralForm(locale, remainingCount)\n ? t(\"todo_more_tasks_one\", { count: remainingCount })\n : t(\"todo_more_tasks_other\", { count: remainingCount })}\n </span>\n )}\n <div className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n disabled={isPreview}\n aria-label={t(\"add_todo\")}\n className={`flex h-8 w-8 items-center justify-center rounded-full transition-colors not-disabled:cursor-pointer hover:bg-${textColor}/10 disabled:opacity-60`}\n >\n <Plus className={`h-5 w-5 text-${textColor}/50`} />\n </button>\n </div>\n </div>\n </>\n )}\n\n {/* Done section */}\n {!isPreview &&\n !isLoading &&\n !isError &&\n !isCompletedLoading &&\n doneCount > 0 && (\n <div className={`mt-3 border-t border-${textColor}/10 pt-2`}>\n <button\n type=\"button\"\n onClick={() => setIsDoneExpanded((v) => !v)}\n className={`flex w-full items-center justify-between gap-2 rounded-md py-1 text-xs font-medium text-${textColor}/60 hover:bg-${textColor}/5`}\n aria-expanded={isDoneExpanded}\n >\n <span>\n {isDoneExpanded\n ? t(\"hide_done\")\n : t(\"view_done\", { count: doneCount })}\n </span>\n {isDoneExpanded ? (\n <ChevronUp className=\"size-4\" aria-hidden=\"true\" />\n ) : (\n <ChevronDown className=\"size-4\" aria-hidden=\"true\" />\n )}\n </button>\n {isDoneExpanded && (\n <div className=\"mt-1 flex flex-col\">\n {completedTodos.map((todo, index) => (\n <div\n key={todo.id}\n className={`group/row flex items-center gap-3 py-2 ${\n index !== completedTodos.length - 1\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked\n disabled={pendingIds.has(todo.id)}\n onChange={() => toggleTodo(todo, false)}\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"mark_as_open\")}\n />\n <button\n type=\"button\"\n onClick={() => handleRowClick(todo)}\n aria-label={t(\"edit_todo\")}\n className={`flex min-w-0 flex-1 cursor-pointer flex-col items-start gap-0.5 text-left text-${textColor}/60 line-through`}\n >\n <span className=\"line-clamp-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n {todo.dueAt && (\n <span className=\"text-xs\">\n {formatDueAt(todo.dueAt, locale)}\n </span>\n )}\n </button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={(event) => event.stopPropagation()}\n aria-label={t(\"task_actions\")}\n className=\"opacity-60 transition-opacity group-hover/row:opacity-100 focus-visible:opacity-100\"\n >\n <EllipsisVertical className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={(event) => {\n event.stopPropagation();\n handleRowClick(todo);\n }}\n >\n {t(\"edit_todo\")}\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n handleDelete(todo);\n }}\n >\n {t(\"delete_todo\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {!isPreview && (\n <CreateTodoDialog\n open={isCreateDialogOpen}\n onOpenChange={setIsCreateDialogOpen}\n />\n )}\n {!isPreview && (\n <EditTodoDialog\n open={editingTodo !== null}\n onOpenChange={(open) => {\n if (!open) setEditingTodo(null);\n }}\n todo={editingTodo}\n />\n )}\n </div>\n );\n}\n\nexport const toDoWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ToDoWidget\",\n displayName: \"To-Do Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Styling Tab - Title Group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed above the todo list\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Title text displayed above the todo list\",\n defaultValue: \"To-Do\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleFontSize\",\n label: \"Title Font Size\",\n description: \"Font size for the widget title\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Styling Tab - Design Group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Default text color for todo items\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Color used for count badge and icon\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"maxItems\",\n label: \"Max Items\",\n type: \"number\",\n description: \"Maximum number of todo items to display\",\n min: 1,\n max: 20,\n step: 1,\n defaultValue: 5,\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding around the widget container\",\n defaultValue: 4,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the widget container\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-package-descriptor-ByCz_FNh.d.cts","names":[],"sources":["../../core/src/data-sources/types.ts","../../core/src/types/widget-schema.ts","../../../platform/theme-engine/src/types.ts","../../core/src/types/navigation.ts","../../core/src/types/shareable-item.ts","../../core/src/types/field-types.ts","../../core/src/types/index.ts","../../core/src/registries/property-schema-types.ts","../../core/src/registries/field-helpers.ts","../../core/src/registries/container-types.ts","../../core/src/registries/widget-manifest.ts","../../../platform/widget-runtime/src/errors.ts","../../../platform/widget-runtime/src/types.ts","../src/types/widget-package-descriptor.ts"],"mappings":"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"}