@open-mercato/core 0.5.1-develop.2987.9f8c1e0f68 → 0.5.1-develop.3032.01699048cb

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 (143) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/sidebar_variant/index.js +25 -0
  3. package/dist/generated/entities/sidebar_variant/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +1 -0
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +13 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/authUi.js +1 -1
  9. package/dist/helpers/integration/authUi.js.map +2 -2
  10. package/dist/modules/audit_logs/services/actionLogService.js +4 -5
  11. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  12. package/dist/modules/auth/api/sidebar/preferences/route.js +224 -35
  13. package/dist/modules/auth/api/sidebar/preferences/route.js.map +3 -3
  14. package/dist/modules/auth/api/sidebar/variants/[id]/route.js +161 -0
  15. package/dist/modules/auth/api/sidebar/variants/[id]/route.js.map +7 -0
  16. package/dist/modules/auth/api/sidebar/variants/route.js +142 -0
  17. package/dist/modules/auth/api/sidebar/variants/route.js.map +7 -0
  18. package/dist/modules/auth/backend/sidebar-customization/page.js +16 -0
  19. package/dist/modules/auth/backend/sidebar-customization/page.js.map +7 -0
  20. package/dist/modules/auth/backend/sidebar-customization/page.meta.js +28 -0
  21. package/dist/modules/auth/backend/sidebar-customization/page.meta.js.map +7 -0
  22. package/dist/modules/auth/data/entities.js +45 -4
  23. package/dist/modules/auth/data/entities.js.map +2 -2
  24. package/dist/modules/auth/data/validators.js +63 -1
  25. package/dist/modules/auth/data/validators.js.map +2 -2
  26. package/dist/modules/auth/migrations/Migration20260427081815.js +15 -0
  27. package/dist/modules/auth/migrations/Migration20260427081815.js.map +7 -0
  28. package/dist/modules/auth/migrations/Migration20260427124900.js +15 -0
  29. package/dist/modules/auth/migrations/Migration20260427124900.js.map +7 -0
  30. package/dist/modules/auth/migrations/Migration20260427143311.js +72 -0
  31. package/dist/modules/auth/migrations/Migration20260427143311.js.map +7 -0
  32. package/dist/modules/auth/services/sidebarPreferencesService.js +176 -16
  33. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  34. package/dist/modules/customers/api/companies/[id]/route.js +30 -20
  35. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  36. package/dist/modules/customers/api/companies/route.js +12 -7
  37. package/dist/modules/customers/api/companies/route.js.map +2 -2
  38. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +12 -7
  39. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  40. package/dist/modules/customers/api/people/route.js +12 -7
  41. package/dist/modules/customers/api/people/route.js.map +2 -2
  42. package/dist/modules/customers/backend/customers/companies/[id]/page.js +3 -1
  43. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  44. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +25 -2
  45. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  46. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +35 -33
  47. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  48. package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js +56 -0
  49. package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js.map +7 -0
  50. package/dist/modules/customers/components/detail/ActivitiesCard.js +175 -0
  51. package/dist/modules/customers/components/detail/ActivitiesCard.js.map +7 -0
  52. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +324 -0
  53. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +7 -0
  54. package/dist/modules/customers/components/detail/ActivitiesSection.js +62 -13
  55. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +2 -2
  56. package/dist/modules/customers/components/detail/ActivityLogTab.js +14 -23
  57. package/dist/modules/customers/components/detail/ActivityLogTab.js.map +2 -2
  58. package/dist/modules/customers/components/detail/ActivityTimeline.js +13 -13
  59. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
  60. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +35 -22
  61. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +2 -2
  62. package/dist/modules/customers/components/detail/AiActionChips.js +15 -22
  63. package/dist/modules/customers/components/detail/AiActionChips.js.map +2 -2
  64. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -2
  65. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  66. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +196 -28
  67. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  68. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +2 -2
  69. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +2 -2
  70. package/dist/modules/customers/components/detail/schedule/FooterFields.js +14 -2
  71. package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +2 -2
  72. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +9 -2
  73. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +2 -2
  74. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +9 -2
  75. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  76. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +25 -4
  77. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +2 -2
  78. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +20 -3
  79. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  80. package/dist/modules/customers/components/formConfig.js +3 -3
  81. package/dist/modules/customers/components/formConfig.js.map +2 -2
  82. package/dist/modules/customers/lib/displayName.js +12 -0
  83. package/dist/modules/customers/lib/displayName.js.map +2 -2
  84. package/dist/modules/entities/cli.js +5 -6
  85. package/dist/modules/entities/cli.js.map +2 -2
  86. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +124 -0
  87. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +7 -0
  88. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js +11 -0
  89. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js.map +7 -0
  90. package/generated/entities/sidebar_variant/index.ts +11 -0
  91. package/generated/entities.ids.generated.ts +1 -0
  92. package/generated/entity-fields-registry.ts +13 -0
  93. package/package.json +6 -6
  94. package/src/helpers/integration/authUi.ts +1 -1
  95. package/src/modules/audit_logs/services/actionLogService.ts +5 -6
  96. package/src/modules/auth/api/sidebar/preferences/route.ts +266 -34
  97. package/src/modules/auth/api/sidebar/variants/[id]/route.ts +183 -0
  98. package/src/modules/auth/api/sidebar/variants/route.ts +157 -0
  99. package/src/modules/auth/backend/sidebar-customization/page.meta.ts +34 -0
  100. package/src/modules/auth/backend/sidebar-customization/page.tsx +17 -0
  101. package/src/modules/auth/data/entities.ts +48 -2
  102. package/src/modules/auth/data/validators.ts +70 -0
  103. package/src/modules/auth/migrations/.snapshot-open-mercato.json +790 -71
  104. package/src/modules/auth/migrations/Migration20260427081815.ts +16 -0
  105. package/src/modules/auth/migrations/Migration20260427124900.ts +19 -0
  106. package/src/modules/auth/migrations/Migration20260427143311.ts +83 -0
  107. package/src/modules/auth/services/sidebarPreferencesService.ts +243 -18
  108. package/src/modules/customers/api/companies/[id]/route.ts +30 -20
  109. package/src/modules/customers/api/companies/route.ts +12 -7
  110. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +12 -7
  111. package/src/modules/customers/api/people/route.ts +12 -7
  112. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +5 -4
  113. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +28 -5
  114. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +41 -30
  115. package/src/modules/customers/components/detail/ActivitiesAddNewMenu.tsx +67 -0
  116. package/src/modules/customers/components/detail/ActivitiesCard.tsx +231 -0
  117. package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +390 -0
  118. package/src/modules/customers/components/detail/ActivitiesSection.tsx +91 -40
  119. package/src/modules/customers/components/detail/ActivityLogTab.tsx +25 -23
  120. package/src/modules/customers/components/detail/ActivityTimeline.tsx +15 -19
  121. package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +36 -29
  122. package/src/modules/customers/components/detail/AiActionChips.tsx +17 -23
  123. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +3 -2
  124. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +233 -41
  125. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +6 -2
  126. package/src/modules/customers/components/detail/schedule/FooterFields.tsx +22 -2
  127. package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +10 -2
  128. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +10 -2
  129. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +26 -6
  130. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +32 -3
  131. package/src/modules/customers/components/formConfig.tsx +3 -3
  132. package/src/modules/customers/i18n/de.json +69 -2
  133. package/src/modules/customers/i18n/en.json +69 -2
  134. package/src/modules/customers/i18n/es.json +69 -2
  135. package/src/modules/customers/i18n/pl.json +68 -1
  136. package/src/modules/customers/lib/displayName.ts +21 -0
  137. package/src/modules/entities/cli.ts +5 -6
  138. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.ts +9 -0
  139. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +168 -0
  140. package/src/modules/portal/i18n/de.json +20 -0
  141. package/src/modules/portal/i18n/en.json +20 -0
  142. package/src/modules/portal/i18n/es.json +20 -0
  143. package/src/modules/portal/i18n/pl.json +20 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/components/detail/schedule/ParticipantsField.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Users, Search, X, Clock, CheckCircle2, XCircle } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport { fetchAssignableStaffMembersPage } from '../assignableStaff'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible } from './fieldConfig'\nimport type { Participant, RsvpStatus } from './useScheduleFormState'\nimport { PARTICIPANT_COLORS } from './useScheduleFormState'\n\nfunction ParticipantSearchPopover({\n existingIds,\n onAdd,\n onAddMany,\n t,\n}: {\n existingIds: Set<string>\n onAdd: (p: Participant) => void\n onAddMany: (participants: Participant[]) => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<Array<{ userId: string; name: string; email: string }>>([])\n const [page, setPage] = React.useState(1)\n const [totalPages, setTotalPages] = React.useState(1)\n const [loading, setLoading] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const selectableResults = React.useMemo(\n () => results.filter((result) => !existingIds.has(result.userId)),\n [existingIds, results],\n )\n\n React.useEffect(() => {\n if (!open) return\n const controller = new AbortController()\n setLoading(true)\n fetchAssignableStaffMembersPage(query, { page, pageSize: 20, signal: controller.signal })\n .then((result) => {\n const members = result.items\n const nextResults = members.map((member) => ({\n userId: member.userId,\n name: member.displayName,\n email: member.email ?? '',\n }))\n setResults((current) => {\n if (page <= 1) return nextResults\n const merged = new Map(current.map((entry) => [entry.userId, entry]))\n nextResults.forEach((entry) => merged.set(entry.userId, entry))\n return Array.from(merged.values())\n })\n setTotalPages(result.total > 0 ? Math.max(1, Math.ceil(result.total / result.pageSize)) : 1)\n setLoadError(null)\n })\n .catch(() => {\n setResults([])\n setLoadError(\n t(\n 'customers.assignableStaff.loadError',\n 'Unable to load team members. Check your permissions and try again.',\n ),\n )\n })\n .finally(() => setLoading(false))\n return () => controller.abort()\n }, [open, page, query, t])\n\n React.useEffect(() => {\n if (!open) return\n setPage(1)\n }, [open, query])\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto inline-flex items-center gap-1.5 rounded-full border border-status-success-border bg-status-success-bg px-2.5 py-1.5 text-xs font-semibold text-foreground\">\n <Users className=\"size-3\" />\n {t('customers.schedule.addParticipant', 'Add participant')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <div className=\"flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2\">\n <Search className=\"size-3.5 text-muted-foreground shrink-0\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t('customers.schedule.searchParticipant', 'Search team members...')}\n className=\"flex-1 bg-transparent text-sm focus:outline-none\"\n autoFocus\n />\n </div>\n {selectableResults.length ? (\n <div className=\"mb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => {\n onAddMany(\n selectableResults.map((participant, index) => ({\n userId: participant.userId,\n name: participant.name,\n email: participant.email,\n color: PARTICIPANT_COLORS[(existingIds.size + index) % PARTICIPANT_COLORS.length],\n })),\n )\n setOpen(false)\n setQuery('')\n }}\n >\n {t('customers.schedule.addVisibleParticipants', 'Add all visible')}\n </Button>\n </div>\n ) : null}\n <div className=\"max-h-48 overflow-y-auto space-y-0.5\">\n {loading && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.searching', 'Searching...')}</p>}\n {!loading && loadError && <p className=\"px-2 py-3 text-xs text-destructive text-center\">{loadError}</p>}\n {!loading && !loadError && results.length === 0 && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.noResults', 'No results')}</p>}\n {results.map((r) => {\n const alreadyAdded = existingIds.has(r.userId)\n return (\n <Button\n key={r.userId}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={alreadyAdded}\n onClick={() => {\n onAdd({ userId: r.userId, name: r.name, email: r.email, color: PARTICIPANT_COLORS[existingIds.size % PARTICIPANT_COLORS.length] })\n setOpen(false)\n setQuery('')\n }}\n className={cn(\n 'h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors',\n alreadyAdded ? 'opacity-40 cursor-default' : 'hover:bg-accent cursor-pointer',\n )}\n >\n <span className=\"inline-flex size-6 items-center justify-center rounded-full bg-muted text-xs font-bold shrink-0\">\n {r.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{r.name}</span>\n {r.email && <span className=\"text-xs text-muted-foreground truncate\">{r.email}</span>}\n </Button>\n )\n })}\n {!loading && !loadError && page < totalPages ? (\n <div className=\"px-2 py-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => setPage((current) => current + 1)}>\n {t('customers.schedule.loadMore', 'Load more')}\n </Button>\n </div>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n\ninterface ParticipantsFieldProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n participants: Participant[]\n setParticipants: React.Dispatch<React.SetStateAction<Participant[]>>\n removeParticipant: (userId: string) => void\n guestPermissions: { canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }\n setGuestPermissions: React.Dispatch<React.SetStateAction<{ canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }>>\n}\n\nexport function ParticipantsField({\n visible,\n activityType,\n participants,\n setParticipants,\n removeParticipant,\n guestPermissions,\n setGuestPermissions,\n}: ParticipantsFieldProps) {\n const t = useT()\n\n if (!isVisible(activityType, 'participants')) return null\n\n return (\n <div>\n <label className=\"text-overline font-semibold uppercase text-muted-foreground tracking-wider\">\n {t('customers.schedule.participants', 'Participants')}\n </label>\n <div className=\"mt-2.5 flex flex-wrap content-center items-center gap-2 rounded-lg border border-border bg-background px-3 py-2.5\">\n {participants.map((p) => (\n <div key={p.userId} className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-2.5 py-1.5\">\n <span className={cn('inline-flex size-5 items-center justify-center rounded-full text-xs font-bold text-white', p.color ?? 'bg-primary')}>\n {p.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"text-xs text-foreground\">{p.name}</span>\n <IconButton type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => removeParticipant(p.userId)} className=\"h-auto text-muted-foreground hover:text-foreground p-0\" aria-label={t('customers.schedule.removeParticipant', 'Remove participant')}>\n <X className=\"size-3\" />\n </IconButton>\n </div>\n ))}\n <ParticipantSearchPopover\n existingIds={new Set(participants.map((p) => p.userId))}\n onAdd={(p) => setParticipants((prev) => [...prev, { ...p, status: 'pending' as RsvpStatus }])}\n onAddMany={(nextParticipants) => {\n setParticipants((prev) => [\n ...prev,\n ...nextParticipants.map((participant) => ({ ...participant, status: 'pending' as RsvpStatus })),\n ])\n }}\n t={t}\n />\n </div>\n\n {/* Guest permissions -- shown when participants exist */}\n {participants.length > 0 && (\n <div className=\"mt-3 flex flex-wrap items-center gap-x-[16px] gap-y-[6px] text-xs\">\n <span className=\"font-medium text-muted-foreground\">{t('customers.schedule.guestPermissions', 'Guest permissions:')}</span>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canInviteOthers} onChange={(e) => setGuestPermissions((p) => ({ ...p, canInviteOthers: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.invite', 'Invite others')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canModify} onChange={(e) => setGuestPermissions((p) => ({ ...p, canModify: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.modify', 'Modify')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canSeeList} onChange={(e) => setGuestPermissions((p) => ({ ...p, canSeeList: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.seeList', 'See list')}\n </label>\n </div>\n )}\n\n {/* RSVP summary -- shown when participants exist */}\n {participants.length > 0 && (() => {\n const accepted = participants.filter((p) => p.status === 'accepted').length\n const pending = participants.filter((p) => !p.status || p.status === 'pending').length\n const declined = participants.filter((p) => p.status === 'declined').length\n if (accepted === 0 && pending === 0 && declined === 0) return null\n return (\n <div className=\"mt-2 flex items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{t('customers.schedule.rsvp.label', 'Responses:')}</span>\n {accepted > 0 && <span className=\"flex items-center gap-1 font-medium text-status-success-text\"><CheckCircle2 className=\"size-3.5\" /> {accepted} {t('customers.schedule.rsvp.accepted', 'tak')}</span>}\n {pending > 0 && <span className=\"flex items-center gap-1 font-medium text-status-warning-text\"><Clock className=\"size-3.5\" /> {pending} {t('customers.schedule.rsvp.pending', 'czeka')}</span>}\n {declined > 0 && <span className=\"flex items-center gap-1 font-medium text-status-error-text\"><XCircle className=\"size-3.5\" /> {declined} {t('customers.schedule.rsvp.declined', 'nie')}</span>}\n </div>\n )\n })()}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Users, Search, X, Clock, CheckCircle2, XCircle } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport { fetchAssignableStaffMembersPage } from '../assignableStaff'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible, getFieldLabel } from './fieldConfig'\nimport type { Participant, RsvpStatus } from './useScheduleFormState'\nimport { PARTICIPANT_COLORS } from './useScheduleFormState'\n\nfunction ParticipantSearchPopover({\n existingIds,\n onAdd,\n onAddMany,\n t,\n}: {\n existingIds: Set<string>\n onAdd: (p: Participant) => void\n onAddMany: (participants: Participant[]) => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<Array<{ userId: string; name: string; email: string }>>([])\n const [page, setPage] = React.useState(1)\n const [totalPages, setTotalPages] = React.useState(1)\n const [loading, setLoading] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const selectableResults = React.useMemo(\n () => results.filter((result) => !existingIds.has(result.userId)),\n [existingIds, results],\n )\n\n React.useEffect(() => {\n if (!open) return\n const controller = new AbortController()\n setLoading(true)\n fetchAssignableStaffMembersPage(query, { page, pageSize: 20, signal: controller.signal })\n .then((result) => {\n const members = result.items\n const nextResults = members.map((member) => ({\n userId: member.userId,\n name: member.displayName,\n email: member.email ?? '',\n }))\n setResults((current) => {\n if (page <= 1) return nextResults\n const merged = new Map(current.map((entry) => [entry.userId, entry]))\n nextResults.forEach((entry) => merged.set(entry.userId, entry))\n return Array.from(merged.values())\n })\n setTotalPages(result.total > 0 ? Math.max(1, Math.ceil(result.total / result.pageSize)) : 1)\n setLoadError(null)\n })\n .catch(() => {\n setResults([])\n setLoadError(\n t(\n 'customers.assignableStaff.loadError',\n 'Unable to load team members. Check your permissions and try again.',\n ),\n )\n })\n .finally(() => setLoading(false))\n return () => controller.abort()\n }, [open, page, query, t])\n\n React.useEffect(() => {\n if (!open) return\n setPage(1)\n }, [open, query])\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto inline-flex items-center gap-1.5 rounded-full border border-status-success-border bg-status-success-bg px-2.5 py-1.5 text-xs font-semibold text-foreground\">\n <Users className=\"size-3\" />\n {t('customers.schedule.addParticipant', 'Add participant')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <div className=\"flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2\">\n <Search className=\"size-3.5 text-muted-foreground shrink-0\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t('customers.schedule.searchParticipant', 'Search team members...')}\n className=\"flex-1 bg-transparent text-sm focus:outline-none\"\n autoFocus\n />\n </div>\n {selectableResults.length ? (\n <div className=\"mb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => {\n onAddMany(\n selectableResults.map((participant, index) => ({\n userId: participant.userId,\n name: participant.name,\n email: participant.email,\n color: PARTICIPANT_COLORS[(existingIds.size + index) % PARTICIPANT_COLORS.length],\n })),\n )\n setOpen(false)\n setQuery('')\n }}\n >\n {t('customers.schedule.addVisibleParticipants', 'Add all visible')}\n </Button>\n </div>\n ) : null}\n <div className=\"max-h-48 overflow-y-auto space-y-0.5\">\n {loading && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.searching', 'Searching...')}</p>}\n {!loading && loadError && <p className=\"px-2 py-3 text-xs text-destructive text-center\">{loadError}</p>}\n {!loading && !loadError && results.length === 0 && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.noResults', 'No results')}</p>}\n {results.map((r) => {\n const alreadyAdded = existingIds.has(r.userId)\n return (\n <Button\n key={r.userId}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={alreadyAdded}\n onClick={() => {\n onAdd({ userId: r.userId, name: r.name, email: r.email, color: PARTICIPANT_COLORS[existingIds.size % PARTICIPANT_COLORS.length] })\n setOpen(false)\n setQuery('')\n }}\n className={cn(\n 'h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors',\n alreadyAdded ? 'opacity-40 cursor-default' : 'hover:bg-accent cursor-pointer',\n )}\n >\n <span className=\"inline-flex size-6 items-center justify-center rounded-full bg-muted text-xs font-bold shrink-0\">\n {r.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{r.name}</span>\n {r.email && <span className=\"text-xs text-muted-foreground truncate\">{r.email}</span>}\n </Button>\n )\n })}\n {!loading && !loadError && page < totalPages ? (\n <div className=\"px-2 py-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => setPage((current) => current + 1)}>\n {t('customers.schedule.loadMore', 'Load more')}\n </Button>\n </div>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n\ninterface ParticipantsFieldProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n participants: Participant[]\n setParticipants: React.Dispatch<React.SetStateAction<Participant[]>>\n removeParticipant: (userId: string) => void\n guestPermissions: { canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }\n setGuestPermissions: React.Dispatch<React.SetStateAction<{ canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }>>\n}\n\nexport function ParticipantsField({\n visible,\n activityType,\n participants,\n setParticipants,\n removeParticipant,\n guestPermissions,\n setGuestPermissions,\n}: ParticipantsFieldProps) {\n const t = useT()\n\n if (!isVisible(activityType, 'participants')) return null\n\n const sectionLabel = getFieldLabel(\n activityType,\n 'participants',\n t,\n 'customers.schedule.participants',\n 'Participants',\n )\n\n return (\n <div>\n <label className=\"text-overline font-semibold uppercase text-muted-foreground tracking-wider\">\n {sectionLabel}\n </label>\n <div className=\"mt-2.5 flex flex-wrap content-center items-center gap-2 rounded-lg border border-border bg-background px-3 py-2.5\">\n {participants.map((p) => (\n <div key={p.userId} className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-2.5 py-1.5\">\n <span className={cn('inline-flex size-5 items-center justify-center rounded-full text-xs font-bold text-white', p.color ?? 'bg-primary')}>\n {p.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"text-xs text-foreground\">{p.name}</span>\n <IconButton type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => removeParticipant(p.userId)} className=\"h-auto text-muted-foreground hover:text-foreground p-0\" aria-label={t('customers.schedule.removeParticipant', 'Remove participant')}>\n <X className=\"size-3\" />\n </IconButton>\n </div>\n ))}\n <ParticipantSearchPopover\n existingIds={new Set(participants.map((p) => p.userId))}\n onAdd={(p) => setParticipants((prev) => [...prev, { ...p, status: 'pending' as RsvpStatus }])}\n onAddMany={(nextParticipants) => {\n setParticipants((prev) => [\n ...prev,\n ...nextParticipants.map((participant) => ({ ...participant, status: 'pending' as RsvpStatus })),\n ])\n }}\n t={t}\n />\n </div>\n\n {/* Guest permissions -- shown when participants exist */}\n {participants.length > 0 && (\n <div className=\"mt-3 flex flex-wrap items-center gap-x-[16px] gap-y-[6px] text-xs\">\n <span className=\"font-medium text-muted-foreground\">{t('customers.schedule.guestPermissions', 'Guest permissions:')}</span>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canInviteOthers} onChange={(e) => setGuestPermissions((p) => ({ ...p, canInviteOthers: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.invite', 'Invite others')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canModify} onChange={(e) => setGuestPermissions((p) => ({ ...p, canModify: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.modify', 'Modify')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canSeeList} onChange={(e) => setGuestPermissions((p) => ({ ...p, canSeeList: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.seeList', 'See list')}\n </label>\n </div>\n )}\n\n {/* RSVP summary -- shown when participants exist */}\n {participants.length > 0 && (() => {\n const accepted = participants.filter((p) => p.status === 'accepted').length\n const pending = participants.filter((p) => !p.status || p.status === 'pending').length\n const declined = participants.filter((p) => p.status === 'declined').length\n if (accepted === 0 && pending === 0 && declined === 0) return null\n return (\n <div className=\"mt-2 flex items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{t('customers.schedule.rsvp.label', 'Responses:')}</span>\n {accepted > 0 && <span className=\"flex items-center gap-1 font-medium text-status-success-text\"><CheckCircle2 className=\"size-3.5\" /> {accepted} {t('customers.schedule.rsvp.accepted', 'tak')}</span>}\n {pending > 0 && <span className=\"flex items-center gap-1 font-medium text-status-warning-text\"><Clock className=\"size-3.5\" /> {pending} {t('customers.schedule.rsvp.pending', 'czeka')}</span>}\n {declined > 0 && <span className=\"flex items-center gap-1 font-medium text-status-error-text\"><XCircle className=\"size-3.5\" /> {declined} {t('customers.schedule.rsvp.declined', 'nie')}</span>}\n </div>\n )\n })()}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -26,30 +26,51 @@ const FIELD_VISIBILITY = {
26
26
  "reminder",
27
27
  "visibility"
28
28
  ]),
29
+ // Task: now also surfaces Due time (startTime) + Estimate (duration) per Figma 790:280.
29
30
  task: /* @__PURE__ */ new Set([
30
31
  "title",
31
32
  "date",
33
+ "startTime",
34
+ "duration",
32
35
  "linkedEntities",
33
36
  "description",
34
37
  "reminder",
35
38
  "visibility"
36
39
  ]),
40
+ // Email: surface participants as TO recipients per Figma 790:510.
37
41
  email: /* @__PURE__ */ new Set([
38
42
  "title",
39
43
  "date",
40
44
  "startTime",
45
+ "participants",
41
46
  "linkedEntities",
42
47
  "description",
48
+ "reminder",
43
49
  "visibility"
44
50
  ])
45
51
  };
46
52
  const FIELD_LABEL_OVERRIDES = {
47
- email: {
48
- title: { key: "customers.schedule.subject", fallback: "Subject" },
49
- description: { key: "customers.schedule.body", fallback: "Body" }
53
+ meeting: {
54
+ participants: { key: "customers.schedule.attendees", fallback: "Attendees" },
55
+ linkedEntities: { key: "customers.schedule.connections", fallback: "Connections" }
56
+ },
57
+ call: {
58
+ participants: { key: "customers.schedule.contact", fallback: "Contact" },
59
+ linkedEntities: { key: "customers.schedule.connections", fallback: "Connections" },
60
+ description: { key: "customers.schedule.callNotes", fallback: "Call notes" }
50
61
  },
51
62
  task: {
52
- date: { key: "customers.schedule.dueDate", fallback: "Due date" }
63
+ date: { key: "customers.schedule.dueDate", fallback: "Due date" },
64
+ startTime: { key: "customers.schedule.dueTime", fallback: "Due time" },
65
+ duration: { key: "customers.schedule.estimate", fallback: "Estimate" },
66
+ linkedEntities: { key: "customers.schedule.connections", fallback: "Connections" },
67
+ description: { key: "customers.schedule.details", fallback: "Details" }
68
+ },
69
+ email: {
70
+ title: { key: "customers.schedule.subject", fallback: "Subject" },
71
+ participants: { key: "customers.schedule.to", fallback: "To" },
72
+ linkedEntities: { key: "customers.schedule.connections", fallback: "Connections" },
73
+ description: { key: "customers.schedule.message", fallback: "Message" }
53
74
  }
54
75
  };
55
76
  function isVisible(type, fieldId) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/components/detail/schedule/fieldConfig.ts"],
4
- "sourcesContent": ["export type ActivityType = 'meeting' | 'call' | 'task' | 'email'\n\nexport type ScheduleFieldId =\n | 'title'\n | 'date'\n | 'startTime'\n | 'duration'\n | 'allDay'\n | 'timezone'\n | 'recurrence'\n | 'participants'\n | 'guestPermissions'\n | 'location'\n | 'linkedEntities'\n | 'description'\n | 'reminder'\n | 'visibility'\n\nexport const FIELD_VISIBILITY: Record<ActivityType, Set<ScheduleFieldId>> = {\n meeting: new Set([\n 'title', 'date', 'startTime', 'duration', 'allDay', 'timezone', 'recurrence',\n 'participants', 'guestPermissions', 'location', 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n call: new Set([\n 'title', 'date', 'startTime', 'duration',\n 'participants', 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n task: new Set([\n 'title', 'date',\n 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n email: new Set([\n 'title', 'date', 'startTime',\n 'linkedEntities', 'description',\n 'visibility',\n ]),\n}\n\ntype LabelOverride = { key: string; fallback: string }\n\nexport const FIELD_LABEL_OVERRIDES: Partial<\n Record<ActivityType, Partial<Record<ScheduleFieldId, LabelOverride>>>\n> = {\n email: {\n title: { key: 'customers.schedule.subject', fallback: 'Subject' },\n description: { key: 'customers.schedule.body', fallback: 'Body' },\n },\n task: {\n date: { key: 'customers.schedule.dueDate', fallback: 'Due date' },\n },\n}\n\nexport function isVisible(type: ActivityType, fieldId: ScheduleFieldId): boolean {\n return FIELD_VISIBILITY[type].has(fieldId)\n}\n\nexport function getFieldLabel(\n type: ActivityType,\n fieldId: ScheduleFieldId,\n t: (key: string, fallback: string) => string,\n defaultKey: string,\n defaultFallback: string,\n): string {\n const override = FIELD_LABEL_OVERRIDES[type]?.[fieldId]\n if (override) return t(override.key, override.fallback)\n return t(defaultKey, defaultFallback)\n}\n"],
5
- "mappings": "AAkBO,MAAM,mBAA+D;AAAA,EAC1E,SAAS,oBAAI,IAAI;AAAA,IACf;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAa;AAAA,IAAY;AAAA,IAAU;AAAA,IAAY;AAAA,IAChE;AAAA,IAAgB;AAAA,IAAoB;AAAA,IAAY;AAAA,IAAkB;AAAA,IAClE;AAAA,IAAY;AAAA,EACd,CAAC;AAAA,EACD,MAAM,oBAAI,IAAI;AAAA,IACZ;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAa;AAAA,IAC9B;AAAA,IAAgB;AAAA,IAAkB;AAAA,IAClC;AAAA,IAAY;AAAA,EACd,CAAC;AAAA,EACD,MAAM,oBAAI,IAAI;AAAA,IACZ;AAAA,IAAS;AAAA,IACT;AAAA,IAAkB;AAAA,IAClB;AAAA,IAAY;AAAA,EACd,CAAC;AAAA,EACD,OAAO,oBAAI,IAAI;AAAA,IACb;AAAA,IAAS;AAAA,IAAQ;AAAA,IACjB;AAAA,IAAkB;AAAA,IAClB;AAAA,EACF,CAAC;AACH;AAIO,MAAM,wBAET;AAAA,EACF,OAAO;AAAA,IACL,OAAO,EAAE,KAAK,8BAA8B,UAAU,UAAU;AAAA,IAChE,aAAa,EAAE,KAAK,2BAA2B,UAAU,OAAO;AAAA,EAClE;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAE,KAAK,8BAA8B,UAAU,WAAW;AAAA,EAClE;AACF;AAEO,SAAS,UAAU,MAAoB,SAAmC;AAC/E,SAAO,iBAAiB,IAAI,EAAE,IAAI,OAAO;AAC3C;AAEO,SAAS,cACd,MACA,SACA,GACA,YACA,iBACQ;AACR,QAAM,WAAW,sBAAsB,IAAI,IAAI,OAAO;AACtD,MAAI,SAAU,QAAO,EAAE,SAAS,KAAK,SAAS,QAAQ;AACtD,SAAO,EAAE,YAAY,eAAe;AACtC;",
4
+ "sourcesContent": ["export type ActivityType = 'meeting' | 'call' | 'task' | 'email'\n\nexport type ScheduleFieldId =\n | 'title'\n | 'date'\n | 'startTime'\n | 'duration'\n | 'allDay'\n | 'timezone'\n | 'recurrence'\n | 'participants'\n | 'guestPermissions'\n | 'location'\n | 'linkedEntities'\n | 'description'\n | 'reminder'\n | 'visibility'\n\nexport const FIELD_VISIBILITY: Record<ActivityType, Set<ScheduleFieldId>> = {\n meeting: new Set([\n 'title', 'date', 'startTime', 'duration', 'allDay', 'timezone', 'recurrence',\n 'participants', 'guestPermissions', 'location', 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n call: new Set([\n 'title', 'date', 'startTime', 'duration',\n 'participants', 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n // Task: now also surfaces Due time (startTime) + Estimate (duration) per Figma 790:280.\n task: new Set([\n 'title', 'date', 'startTime', 'duration',\n 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n // Email: surface participants as TO recipients per Figma 790:510.\n email: new Set([\n 'title', 'date', 'startTime',\n 'participants', 'linkedEntities', 'description',\n 'reminder', 'visibility',\n ]),\n}\n\ntype LabelOverride = { key: string; fallback: string }\n\n// Per-type section labels (Figma 784:1255 / 829:50 / 790:280 / 790:510).\n// `participants` / `linkedEntities` / `description` resolve via these overrides\n// when present; otherwise the field components fall back to their generic key.\nexport const FIELD_LABEL_OVERRIDES: Partial<\n Record<ActivityType, Partial<Record<ScheduleFieldId, LabelOverride>>>\n> = {\n meeting: {\n participants: { key: 'customers.schedule.attendees', fallback: 'Attendees' },\n linkedEntities: { key: 'customers.schedule.connections', fallback: 'Connections' },\n },\n call: {\n participants: { key: 'customers.schedule.contact', fallback: 'Contact' },\n linkedEntities: { key: 'customers.schedule.connections', fallback: 'Connections' },\n description: { key: 'customers.schedule.callNotes', fallback: 'Call notes' },\n },\n task: {\n date: { key: 'customers.schedule.dueDate', fallback: 'Due date' },\n startTime: { key: 'customers.schedule.dueTime', fallback: 'Due time' },\n duration: { key: 'customers.schedule.estimate', fallback: 'Estimate' },\n linkedEntities: { key: 'customers.schedule.connections', fallback: 'Connections' },\n description: { key: 'customers.schedule.details', fallback: 'Details' },\n },\n email: {\n title: { key: 'customers.schedule.subject', fallback: 'Subject' },\n participants: { key: 'customers.schedule.to', fallback: 'To' },\n linkedEntities: { key: 'customers.schedule.connections', fallback: 'Connections' },\n description: { key: 'customers.schedule.message', fallback: 'Message' },\n },\n}\n\nexport function isVisible(type: ActivityType, fieldId: ScheduleFieldId): boolean {\n return FIELD_VISIBILITY[type].has(fieldId)\n}\n\nexport function getFieldLabel(\n type: ActivityType,\n fieldId: ScheduleFieldId,\n t: (key: string, fallback: string) => string,\n defaultKey: string,\n defaultFallback: string,\n): string {\n const override = FIELD_LABEL_OVERRIDES[type]?.[fieldId]\n if (override) return t(override.key, override.fallback)\n return t(defaultKey, defaultFallback)\n}\n"],
5
+ "mappings": "AAkBO,MAAM,mBAA+D;AAAA,EAC1E,SAAS,oBAAI,IAAI;AAAA,IACf;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAa;AAAA,IAAY;AAAA,IAAU;AAAA,IAAY;AAAA,IAChE;AAAA,IAAgB;AAAA,IAAoB;AAAA,IAAY;AAAA,IAAkB;AAAA,IAClE;AAAA,IAAY;AAAA,EACd,CAAC;AAAA,EACD,MAAM,oBAAI,IAAI;AAAA,IACZ;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAa;AAAA,IAC9B;AAAA,IAAgB;AAAA,IAAkB;AAAA,IAClC;AAAA,IAAY;AAAA,EACd,CAAC;AAAA;AAAA,EAED,MAAM,oBAAI,IAAI;AAAA,IACZ;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAa;AAAA,IAC9B;AAAA,IAAkB;AAAA,IAClB;AAAA,IAAY;AAAA,EACd,CAAC;AAAA;AAAA,EAED,OAAO,oBAAI,IAAI;AAAA,IACb;AAAA,IAAS;AAAA,IAAQ;AAAA,IACjB;AAAA,IAAgB;AAAA,IAAkB;AAAA,IAClC;AAAA,IAAY;AAAA,EACd,CAAC;AACH;AAOO,MAAM,wBAET;AAAA,EACF,SAAS;AAAA,IACP,cAAc,EAAE,KAAK,gCAAgC,UAAU,YAAY;AAAA,IAC3E,gBAAgB,EAAE,KAAK,kCAAkC,UAAU,cAAc;AAAA,EACnF;AAAA,EACA,MAAM;AAAA,IACJ,cAAc,EAAE,KAAK,8BAA8B,UAAU,UAAU;AAAA,IACvE,gBAAgB,EAAE,KAAK,kCAAkC,UAAU,cAAc;AAAA,IACjF,aAAa,EAAE,KAAK,gCAAgC,UAAU,aAAa;AAAA,EAC7E;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAE,KAAK,8BAA8B,UAAU,WAAW;AAAA,IAChE,WAAW,EAAE,KAAK,8BAA8B,UAAU,WAAW;AAAA,IACrE,UAAU,EAAE,KAAK,+BAA+B,UAAU,WAAW;AAAA,IACrE,gBAAgB,EAAE,KAAK,kCAAkC,UAAU,cAAc;AAAA,IACjF,aAAa,EAAE,KAAK,8BAA8B,UAAU,UAAU;AAAA,EACxE;AAAA,EACA,OAAO;AAAA,IACL,OAAO,EAAE,KAAK,8BAA8B,UAAU,UAAU;AAAA,IAChE,cAAc,EAAE,KAAK,yBAAyB,UAAU,KAAK;AAAA,IAC7D,gBAAgB,EAAE,KAAK,kCAAkC,UAAU,cAAc;AAAA,IACjF,aAAa,EAAE,KAAK,8BAA8B,UAAU,UAAU;AAAA,EACxE;AACF;AAEO,SAAS,UAAU,MAAoB,SAAmC;AAC/E,SAAO,iBAAiB,IAAI,EAAE,IAAI,OAAO;AAC3C;AAEO,SAAS,cACd,MACA,SACA,GACA,YACA,iBACQ;AACR,QAAM,WAAW,sBAAsB,IAAI,IAAI,OAAO;AACtD,MAAI,SAAU,QAAO,EAAE,SAAS,KAAK,SAAS,QAAQ;AACtD,SAAO,EAAE,YAAY,eAAe;AACtC;",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,12 @@ const PARTICIPANT_COLORS = [
7
7
  "bg-chart-pink",
8
8
  "bg-chart-teal"
9
9
  ];
10
+ const DEFAULT_REMINDER_MINUTES = {
11
+ meeting: 15,
12
+ call: 5,
13
+ task: 1440,
14
+ email: 15
15
+ };
10
16
  function useScheduleFormState({ open, editData }) {
11
17
  const [activityType, setActivityType] = React.useState("meeting");
12
18
  const [title, setTitle] = React.useState("");
@@ -32,7 +38,8 @@ function useScheduleFormState({ open, editData }) {
32
38
  React.useEffect(() => {
33
39
  if (open) {
34
40
  if (editData) {
35
- setActivityType(editData.interactionType ?? "meeting");
41
+ const resolvedType = editData.interactionType ?? "meeting";
42
+ setActivityType(resolvedType);
36
43
  setTitle(editData.title ?? "");
37
44
  const scheduledDate = editData.scheduledAt ? new Date(editData.scheduledAt) : /* @__PURE__ */ new Date();
38
45
  setDate(scheduledDate.toISOString().slice(0, 10));
@@ -41,7 +48,7 @@ function useScheduleFormState({ open, editData }) {
41
48
  setAllDay(editData.allDay ?? false);
42
49
  setDescription(editData.body ?? "");
43
50
  setLocation(editData.location ?? "");
44
- setReminderMinutes(editData.reminderMinutes ?? 15);
51
+ setReminderMinutes(editData.reminderMinutes ?? DEFAULT_REMINDER_MINUTES[resolvedType]);
45
52
  setVisibility(editData.visibility ?? "team");
46
53
  setParticipants(
47
54
  Array.isArray(editData.participants) ? editData.participants.map((p, i) => ({
@@ -95,7 +102,7 @@ function useScheduleFormState({ open, editData }) {
95
102
  setAllDay(false);
96
103
  setDescription("");
97
104
  setLocation("");
98
- setReminderMinutes(15);
105
+ setReminderMinutes(DEFAULT_REMINDER_MINUTES.meeting);
99
106
  setVisibility("team");
100
107
  setParticipants([]);
101
108
  setLinkedEntities([]);
@@ -108,6 +115,16 @@ function useScheduleFormState({ open, editData }) {
108
115
  document.body.style.removeProperty("pointer-events");
109
116
  };
110
117
  }, [open, editData]);
118
+ const lastReminderTypeRef = React.useRef("meeting");
119
+ React.useEffect(() => {
120
+ if (!open || editData) {
121
+ lastReminderTypeRef.current = activityType;
122
+ return;
123
+ }
124
+ if (lastReminderTypeRef.current === activityType) return;
125
+ lastReminderTypeRef.current = activityType;
126
+ setReminderMinutes(DEFAULT_REMINDER_MINUTES[activityType]);
127
+ }, [activityType, editData, open]);
111
128
  const removeParticipant = React.useCallback((userId) => {
112
129
  setParticipants((prev) => prev.filter((p) => p.userId !== userId));
113
130
  }, []);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/components/detail/schedule/useScheduleFormState.ts"],
4
- "sourcesContent": ["import * as React from 'react'\nimport type { ActivityType } from './fieldConfig'\n\nexport type RsvpStatus = 'pending' | 'accepted' | 'declined' | 'tentative'\n\nexport type Participant = {\n userId: string\n name: string\n email?: string\n color?: string\n status?: RsvpStatus\n}\n\nexport type LinkedEntity = {\n id: string\n type: 'company' | 'deal' | 'offer'\n label: string\n}\n\nexport type ScheduleActivityEditData = {\n id: string\n interactionType?: string\n title?: string | null\n body?: string | null\n scheduledAt?: string | null\n durationMinutes?: number | null\n location?: string | null\n allDay?: boolean | null\n recurrenceRule?: string | null\n recurrenceEnd?: string | null\n participants?: Array<{ userId: string; name?: string; email?: string; status?: string }> | null\n reminderMinutes?: number | null\n visibility?: string | null\n linkedEntities?: Array<{ id: string; type: string; label: string }> | null\n guestPermissions?: { canInviteOthers?: boolean; canModify?: boolean; canSeeList?: boolean } | null\n}\n\nexport const PARTICIPANT_COLORS = [\n 'bg-chart-emerald',\n 'bg-chart-blue',\n 'bg-chart-orange',\n 'bg-chart-violet',\n 'bg-chart-pink',\n 'bg-chart-teal',\n]\n\ninterface UseScheduleFormStateParams {\n open: boolean\n editData: ScheduleActivityEditData | null | undefined\n}\n\nexport function useScheduleFormState({ open, editData }: UseScheduleFormStateParams) {\n const [activityType, setActivityType] = React.useState<ActivityType>('meeting')\n const [title, setTitle] = React.useState('')\n const [date, setDate] = React.useState(() => new Date().toISOString().slice(0, 10))\n const [startTime, setStartTime] = React.useState('10:00')\n const [duration, setDuration] = React.useState(30)\n const [allDay, setAllDay] = React.useState(false)\n const [description, setDescription] = React.useState('')\n const [markdownEnabled, setMarkdownEnabled] = React.useState(true)\n const [location, setLocation] = React.useState('')\n const [reminderMinutes, setReminderMinutes] = React.useState(15)\n const [visibility, setVisibility] = React.useState('team')\n const [participants, setParticipants] = React.useState<Participant[]>([])\n const [linkedEntities, setLinkedEntities] = React.useState<LinkedEntity[]>([])\n const [recurrenceEnabled, setRecurrenceEnabled] = React.useState(false)\n const [recurrenceDays, setRecurrenceDays] = React.useState<boolean[]>([true, false, true, false, false, false, false])\n const [recurrenceEndType, setRecurrenceEndType] = React.useState<'never' | 'count' | 'date'>('never')\n const [recurrenceCount, setRecurrenceCount] = React.useState(8)\n const [recurrenceEndDate, setRecurrenceEndDate] = React.useState('')\n const [conflict, setConflict] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [guestPermissions, setGuestPermissions] = React.useState({ canInviteOthers: true, canModify: false, canSeeList: true })\n\n React.useEffect(() => {\n if (open) {\n if (editData) {\n // Edit mode: populate from existing interaction\n setActivityType((editData.interactionType as ActivityType) ?? 'meeting')\n setTitle(editData.title ?? '')\n const scheduledDate = editData.scheduledAt ? new Date(editData.scheduledAt) : new Date()\n setDate(scheduledDate.toISOString().slice(0, 10))\n setStartTime(scheduledDate.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' }))\n setDuration(editData.durationMinutes ?? 30)\n setAllDay(editData.allDay ?? false)\n setDescription(editData.body ?? '')\n setLocation(editData.location ?? '')\n setReminderMinutes(editData.reminderMinutes ?? 15)\n setVisibility(editData.visibility ?? 'team')\n setParticipants(\n Array.isArray(editData.participants)\n ? editData.participants.map((p, i) => ({\n userId: p.userId,\n name: p.name ?? p.userId,\n email: p.email,\n color: PARTICIPANT_COLORS[i % PARTICIPANT_COLORS.length],\n status: (p.status ?? 'pending') as RsvpStatus,\n }))\n : [],\n )\n setLinkedEntities(\n Array.isArray(editData.linkedEntities)\n ? editData.linkedEntities.map((e) => ({ id: e.id, type: e.type as LinkedEntity['type'], label: e.label }))\n : [],\n )\n if (editData.recurrenceRule) {\n setRecurrenceEnabled(true)\n // Parse RRULE to set days and end type\n const rule = editData.recurrenceRule\n const byDayMatch = rule.match(/BYDAY=([A-Z,]+)/)\n if (byDayMatch) {\n const dayNames = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']\n const activeDays = byDayMatch[1].split(',')\n setRecurrenceDays(dayNames.map((d) => activeDays.includes(d)))\n }\n const countMatch = rule.match(/COUNT=(\\d+)/)\n const untilMatch = rule.match(/UNTIL=(\\d{8})/)\n if (countMatch) {\n setRecurrenceEndType('count')\n setRecurrenceCount(Number(countMatch[1]))\n } else if (untilMatch) {\n setRecurrenceEndType('date')\n const raw = untilMatch[1]\n setRecurrenceEndDate(`${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6, 8)}`)\n } else {\n setRecurrenceEndType('never')\n }\n } else {\n setRecurrenceEnabled(false)\n }\n if (editData.guestPermissions) {\n setGuestPermissions({\n canInviteOthers: editData.guestPermissions.canInviteOthers ?? true,\n canModify: editData.guestPermissions.canModify ?? false,\n canSeeList: editData.guestPermissions.canSeeList ?? true,\n })\n }\n } else {\n // Create mode: reset all fields\n setActivityType('meeting')\n setTitle('')\n setDate(new Date().toISOString().slice(0, 10))\n setStartTime('10:00')\n setDuration(30)\n setAllDay(false)\n setDescription('')\n setLocation('')\n setReminderMinutes(15)\n setVisibility('team')\n setParticipants([])\n setLinkedEntities([])\n setRecurrenceEnabled(false)\n }\n setConflict(null)\n }\n return () => {\n // Safety net: restore body scroll if Radix Dialog fails to clean up\n document.body.style.removeProperty('overflow')\n document.body.style.removeProperty('pointer-events')\n }\n }, [open, editData])\n\n const removeParticipant = React.useCallback((userId: string) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== userId))\n }, [])\n\n const toggleRecurrenceDay = React.useCallback((index: number) => {\n setRecurrenceDays((prev) => {\n const next = [...prev]\n next[index] = !next[index]\n return next\n })\n }, [])\n\n return {\n activityType,\n setActivityType,\n title,\n setTitle,\n date,\n setDate,\n startTime,\n setStartTime,\n duration,\n setDuration,\n allDay,\n setAllDay,\n description,\n setDescription,\n markdownEnabled,\n setMarkdownEnabled,\n location,\n setLocation,\n reminderMinutes,\n setReminderMinutes,\n visibility,\n setVisibility,\n participants,\n setParticipants,\n linkedEntities,\n setLinkedEntities,\n recurrenceEnabled,\n setRecurrenceEnabled,\n recurrenceDays,\n setRecurrenceDays,\n recurrenceEndType,\n setRecurrenceEndType,\n recurrenceCount,\n setRecurrenceCount,\n recurrenceEndDate,\n setRecurrenceEndDate,\n conflict,\n setConflict,\n saving,\n setSaving,\n guestPermissions,\n setGuestPermissions,\n removeParticipant,\n toggleRecurrenceDay,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react'\nimport type { ActivityType } from './fieldConfig'\n\nexport type RsvpStatus = 'pending' | 'accepted' | 'declined' | 'tentative'\n\nexport type Participant = {\n userId: string\n name: string\n email?: string\n color?: string\n status?: RsvpStatus\n}\n\nexport type LinkedEntity = {\n id: string\n type: 'company' | 'deal' | 'offer'\n label: string\n}\n\nexport type ScheduleActivityEditData = {\n id: string\n interactionType?: string\n title?: string | null\n body?: string | null\n scheduledAt?: string | null\n durationMinutes?: number | null\n location?: string | null\n allDay?: boolean | null\n recurrenceRule?: string | null\n recurrenceEnd?: string | null\n participants?: Array<{ userId: string; name?: string; email?: string; status?: string }> | null\n reminderMinutes?: number | null\n visibility?: string | null\n linkedEntities?: Array<{ id: string; type: string; label: string }> | null\n guestPermissions?: { canInviteOthers?: boolean; canModify?: boolean; canSeeList?: boolean } | null\n}\n\nexport const PARTICIPANT_COLORS = [\n 'bg-chart-emerald',\n 'bg-chart-blue',\n 'bg-chart-orange',\n 'bg-chart-violet',\n 'bg-chart-pink',\n 'bg-chart-teal',\n]\n\n// Per-Figma defaults for the Reminder dropdown when the user picks an activity\n// type. Meeting/email keep the standard 15 min; tasks default to 1 day (1440 min)\n// because they're plan-ahead artefacts; calls default to 5 min as a stand-in for\n// the Figma \"After call ends\" treatment (which would need a non-numeric sentinel\n// in the API contract \u2014 tracked as a follow-up).\nconst DEFAULT_REMINDER_MINUTES: Record<ActivityType, number> = {\n meeting: 15,\n call: 5,\n task: 1440,\n email: 15,\n}\n\ninterface UseScheduleFormStateParams {\n open: boolean\n editData: ScheduleActivityEditData | null | undefined\n}\n\nexport function useScheduleFormState({ open, editData }: UseScheduleFormStateParams) {\n const [activityType, setActivityType] = React.useState<ActivityType>('meeting')\n const [title, setTitle] = React.useState('')\n const [date, setDate] = React.useState(() => new Date().toISOString().slice(0, 10))\n const [startTime, setStartTime] = React.useState('10:00')\n const [duration, setDuration] = React.useState(30)\n const [allDay, setAllDay] = React.useState(false)\n const [description, setDescription] = React.useState('')\n const [markdownEnabled, setMarkdownEnabled] = React.useState(true)\n const [location, setLocation] = React.useState('')\n const [reminderMinutes, setReminderMinutes] = React.useState(15)\n const [visibility, setVisibility] = React.useState('team')\n const [participants, setParticipants] = React.useState<Participant[]>([])\n const [linkedEntities, setLinkedEntities] = React.useState<LinkedEntity[]>([])\n const [recurrenceEnabled, setRecurrenceEnabled] = React.useState(false)\n const [recurrenceDays, setRecurrenceDays] = React.useState<boolean[]>([true, false, true, false, false, false, false])\n const [recurrenceEndType, setRecurrenceEndType] = React.useState<'never' | 'count' | 'date'>('never')\n const [recurrenceCount, setRecurrenceCount] = React.useState(8)\n const [recurrenceEndDate, setRecurrenceEndDate] = React.useState('')\n const [conflict, setConflict] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [guestPermissions, setGuestPermissions] = React.useState({ canInviteOthers: true, canModify: false, canSeeList: true })\n\n React.useEffect(() => {\n if (open) {\n if (editData) {\n // Edit mode: populate from existing interaction\n const resolvedType = (editData.interactionType as ActivityType) ?? 'meeting'\n setActivityType(resolvedType)\n setTitle(editData.title ?? '')\n const scheduledDate = editData.scheduledAt ? new Date(editData.scheduledAt) : new Date()\n setDate(scheduledDate.toISOString().slice(0, 10))\n setStartTime(scheduledDate.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' }))\n setDuration(editData.durationMinutes ?? 30)\n setAllDay(editData.allDay ?? false)\n setDescription(editData.body ?? '')\n setLocation(editData.location ?? '')\n // Use per-type default when the editData omits an explicit reminder\n // (the menu-driven \"New X\" flow opens the dialog with `reminderMinutes: null`).\n setReminderMinutes(editData.reminderMinutes ?? DEFAULT_REMINDER_MINUTES[resolvedType])\n setVisibility(editData.visibility ?? 'team')\n setParticipants(\n Array.isArray(editData.participants)\n ? editData.participants.map((p, i) => ({\n userId: p.userId,\n name: p.name ?? p.userId,\n email: p.email,\n color: PARTICIPANT_COLORS[i % PARTICIPANT_COLORS.length],\n status: (p.status ?? 'pending') as RsvpStatus,\n }))\n : [],\n )\n setLinkedEntities(\n Array.isArray(editData.linkedEntities)\n ? editData.linkedEntities.map((e) => ({ id: e.id, type: e.type as LinkedEntity['type'], label: e.label }))\n : [],\n )\n if (editData.recurrenceRule) {\n setRecurrenceEnabled(true)\n // Parse RRULE to set days and end type\n const rule = editData.recurrenceRule\n const byDayMatch = rule.match(/BYDAY=([A-Z,]+)/)\n if (byDayMatch) {\n const dayNames = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']\n const activeDays = byDayMatch[1].split(',')\n setRecurrenceDays(dayNames.map((d) => activeDays.includes(d)))\n }\n const countMatch = rule.match(/COUNT=(\\d+)/)\n const untilMatch = rule.match(/UNTIL=(\\d{8})/)\n if (countMatch) {\n setRecurrenceEndType('count')\n setRecurrenceCount(Number(countMatch[1]))\n } else if (untilMatch) {\n setRecurrenceEndType('date')\n const raw = untilMatch[1]\n setRecurrenceEndDate(`${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6, 8)}`)\n } else {\n setRecurrenceEndType('never')\n }\n } else {\n setRecurrenceEnabled(false)\n }\n if (editData.guestPermissions) {\n setGuestPermissions({\n canInviteOthers: editData.guestPermissions.canInviteOthers ?? true,\n canModify: editData.guestPermissions.canModify ?? false,\n canSeeList: editData.guestPermissions.canSeeList ?? true,\n })\n }\n } else {\n // Create mode: reset all fields\n setActivityType('meeting')\n setTitle('')\n setDate(new Date().toISOString().slice(0, 10))\n setStartTime('10:00')\n setDuration(30)\n setAllDay(false)\n setDescription('')\n setLocation('')\n setReminderMinutes(DEFAULT_REMINDER_MINUTES.meeting)\n setVisibility('team')\n setParticipants([])\n setLinkedEntities([])\n setRecurrenceEnabled(false)\n }\n setConflict(null)\n }\n return () => {\n // Safety net: restore body scroll if Radix Dialog fails to clean up\n document.body.style.removeProperty('overflow')\n document.body.style.removeProperty('pointer-events')\n }\n }, [open, editData])\n\n // Update the Reminder default when the activity type changes in create mode.\n // Skipped in edit mode (the persisted value wins), and gated by `open` to\n // avoid flipping the default in a closed-but-mounted dialog.\n const lastReminderTypeRef = React.useRef<ActivityType>('meeting')\n React.useEffect(() => {\n if (!open || editData) {\n lastReminderTypeRef.current = activityType\n return\n }\n if (lastReminderTypeRef.current === activityType) return\n lastReminderTypeRef.current = activityType\n setReminderMinutes(DEFAULT_REMINDER_MINUTES[activityType])\n }, [activityType, editData, open])\n\n const removeParticipant = React.useCallback((userId: string) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== userId))\n }, [])\n\n const toggleRecurrenceDay = React.useCallback((index: number) => {\n setRecurrenceDays((prev) => {\n const next = [...prev]\n next[index] = !next[index]\n return next\n })\n }, [])\n\n return {\n activityType,\n setActivityType,\n title,\n setTitle,\n date,\n setDate,\n startTime,\n setStartTime,\n duration,\n setDuration,\n allDay,\n setAllDay,\n description,\n setDescription,\n markdownEnabled,\n setMarkdownEnabled,\n location,\n setLocation,\n reminderMinutes,\n setReminderMinutes,\n visibility,\n setVisibility,\n participants,\n setParticipants,\n linkedEntities,\n setLinkedEntities,\n recurrenceEnabled,\n setRecurrenceEnabled,\n recurrenceDays,\n setRecurrenceDays,\n recurrenceEndType,\n setRecurrenceEndType,\n recurrenceCount,\n setRecurrenceCount,\n recurrenceEndDate,\n setRecurrenceEndDate,\n conflict,\n setConflict,\n saving,\n setSaving,\n guestPermissions,\n setGuestPermissions,\n removeParticipant,\n toggleRecurrenceDay,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -15,7 +15,7 @@ import {
15
15
  SelectTrigger,
16
16
  SelectValue
17
17
  } from "@open-mercato/ui/primitives/select";
18
- import { deriveDisplayName, isDerivedDisplayName } from "../lib/displayName.js";
18
+ import { coerceDisplayName, deriveDisplayName, isDerivedDisplayName } from "../lib/displayName.js";
19
19
  import {
20
20
  Dialog,
21
21
  DialogContent,
@@ -1344,7 +1344,7 @@ function mapCompanyOverviewToFormValues(overview) {
1344
1344
  const phoneValue = rawPhone == null ? "" : String(rawPhone);
1345
1345
  return {
1346
1346
  id: overview.company.id,
1347
- displayName: overview.company.displayName,
1347
+ displayName: coerceDisplayName(overview.company.displayName),
1348
1348
  primaryEmail: overview.company.primaryEmail ?? "",
1349
1349
  primaryPhone: phoneValue,
1350
1350
  status: overview.company.status ?? "",
@@ -1366,7 +1366,7 @@ function mapPersonOverviewToFormValues(overview) {
1366
1366
  const phoneValue = rawPhone == null ? "" : String(rawPhone);
1367
1367
  return {
1368
1368
  id: overview.person.id,
1369
- displayName: overview.person.displayName,
1369
+ displayName: coerceDisplayName(overview.person.displayName),
1370
1370
  firstName: overview.profile?.firstName ?? "",
1371
1371
  lastName: overview.profile?.lastName ?? "",
1372
1372
  primaryEmail: overview.person.primaryEmail ?? "",