@open-mercato/core 0.6.6-develop.6338.1.c32cd17821 → 0.6.6-develop.6343.1.8120f84f30

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 (25) hide show
  1. package/dist/modules/catalog/components/products/ProductComplianceSection.js +1 -1
  2. package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +2 -2
  3. package/dist/modules/catalog/data/validators.js +1 -1
  4. package/dist/modules/catalog/data/validators.js.map +2 -2
  5. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +1 -1
  6. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +2 -2
  7. package/dist/modules/communication_channels/lib/route-mutation-guard.js +19 -29
  8. package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +2 -2
  9. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +4 -4
  10. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  11. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  12. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  13. package/dist/modules/notifications/lib/routeHelpers.js +18 -25
  14. package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
  15. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -1
  16. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  17. package/package.json +7 -7
  18. package/src/modules/catalog/components/products/ProductComplianceSection.tsx +1 -1
  19. package/src/modules/catalog/data/validators.ts +1 -1
  20. package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +1 -1
  21. package/src/modules/communication_channels/lib/route-mutation-guard.ts +32 -32
  22. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +4 -4
  23. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  24. package/src/modules/notifications/lib/routeHelpers.ts +18 -26
  25. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -1
@@ -175,7 +175,7 @@ function CalendarScreen() {
175
175
  const typeOptions = React.useMemo(() => {
176
176
  const values = new Set(Object.keys(typeLabels));
177
177
  for (const item of items) values.add(item.interactionType);
178
- return [...values].sort().map((value) => ({ value, label: typeLabels[value] ?? value }));
178
+ return [...values].sort((a, b) => a.localeCompare(b)).map((value) => ({ value, label: typeLabels[value] ?? value }));
179
179
  }, [items, typeLabels]);
180
180
  const ownerOptions = React.useMemo(() => {
181
181
  const participantNames = /* @__PURE__ */ new Map();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/customers/components/calendar/CalendarScreen.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport dynamic from 'next/dynamic'\nimport { addDays } from 'date-fns/addDays'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall, apiCallOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { matchFeature } from '@open-mercato/shared/lib/auth/featureMatch'\nimport {\n buildOptimisticLockHeader,\n extractOptimisticLockConflict,\n} from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { ErrorMessage, LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { countByCategory } from '../../lib/calendar/categories'\nimport { findConflicts } from '../../lib/calendar/conflicts'\nimport { getVisibleRange } from '../../lib/calendar/range'\nimport { AgendaList } from './AgendaList'\nimport { CalendarFooter } from './CalendarFooter'\nimport { CalendarHeader } from './CalendarHeader'\nimport { CalendarTabs } from './CalendarTabs'\nimport { CalendarToolbar } from './CalendarToolbar'\nimport { MonthGrid } from './MonthGrid'\nimport { ShortcutsDialog } from './ShortcutsDialog'\nimport { TimeGrid } from './TimeGrid'\nimport { UpcomingCards } from './UpcomingCards'\nimport { CalendarSettingsModal } from './CalendarSettingsModal'\nimport { useCalendarPreferences } from './useCalendarPreferences'\nimport { MAX_WINDOW_ITEMS, useCalendarItems } from './useCalendarItems'\nimport type {\n CalendarFiltersValue,\n CalendarItem,\n CalendarRangePreset,\n CalendarTab,\n CalendarView,\n UpcomingCard,\n} from './types'\n\nconst CalendarEventEditor = dynamic(\n () => import('./CalendarEventEditor').then((mod) => mod.CalendarEventEditor),\n { ssr: false },\n)\n\nconst SEARCH_DEBOUNCE_MS = 200\nconst PHONE_BREAKPOINT_PX = 640\nconst HIGHLIGHT_CLEAR_MS = 3000\nconst DEFAULT_AGENDA_HORIZON_DAYS = 7\nconst UPCOMING_CARDS_COUNT = 4\nconst EMPTY_FILTERS: CalendarFiltersValue = { types: [], status: null, ownerUserId: null }\n\ntype EditorState = { open: boolean; mode: 'create' | 'edit'; item: CalendarItem | null }\n\nconst MANAGE_FEATURE = 'customers.interactions.manage'\n\nfunction useCanManageInteractions(): boolean {\n const [canManage, setCanManage] = React.useState(false)\n React.useEffect(() => {\n const controller = new AbortController()\n let cancelled = false\n apiCall<{ granted?: unknown[] }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n body: JSON.stringify({ features: [MANAGE_FEATURE] }),\n })\n .then((call) => {\n if (cancelled || !call.ok) return\n const granted = Array.isArray(call.result?.granted)\n ? call.result.granted.map((feature) => String(feature))\n : []\n setCanManage(granted.some((grantedFeature) => matchFeature(MANAGE_FEATURE, grantedFeature)))\n })\n .catch(() => {\n if (!cancelled && !controller.signal.aborted) setCanManage(false)\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [])\n return canManage\n}\n\nfunction buildTimezoneLabel(): string {\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone\n const offsetMinutes = -new Date().getTimezoneOffset()\n const sign = offsetMinutes >= 0 ? '+' : '-'\n const absolute = Math.abs(offsetMinutes)\n const hours = Math.floor(absolute / 60)\n const minutes = absolute % 60\n const offset = minutes > 0 ? `${sign}${hours}:${String(minutes).padStart(2, '0')}` : `${sign}${hours}`\n return `${timeZone} (GMT${offset})`\n}\n\nfunction resolveJoinUrl(location: string | null): string | null {\n const trimmed = location?.trim() ?? ''\n if (!trimmed) return null\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed\n if (/^www\\./i.test(trimmed)) return `https://${trimmed}`\n return null\n}\n\nfunction asEditableItem(item: CalendarItem): CalendarItem {\n return item.isRecurringOccurrence ? { ...item, id: item.raw.id } : item\n}\n\nexport function CalendarScreen() {\n const t = useT()\n const [view, setView] = React.useState<CalendarView>('week')\n const [anchor, setAnchor] = React.useState<Date>(() => new Date())\n const [agendaHorizonDays, setAgendaHorizonDays] = React.useState(DEFAULT_AGENDA_HORIZON_DAYS)\n const [preset, setPreset] = React.useState<CalendarRangePreset | null>('thisWeek')\n\n React.useEffect(() => {\n if (window.innerWidth >= PHONE_BREAKPOINT_PX) return\n setView('day')\n setPreset(null)\n }, [])\n const [tab, setTab] = React.useState<CalendarTab>('all')\n const [searchText, setSearchText] = React.useState('')\n const [debouncedSearch, setDebouncedSearch] = React.useState('')\n const [filters, setFilters] = React.useState<CalendarFiltersValue>(EMPTY_FILTERS)\n const [editor, setEditor] = React.useState<EditorState>({ open: false, mode: 'create', item: null })\n const [editorMounted, setEditorMounted] = React.useState(false)\n const [createRange, setCreateRange] = React.useState<{ start: Date; end: Date } | null>(null)\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false)\n const [settingsOpen, setSettingsOpen] = React.useState(false)\n const [highlightItemId, setHighlightItemId] = React.useState<string | null>(null)\n const [hasLoadedOnce, setHasLoadedOnce] = React.useState(false)\n const { preferences, setPreferences, hydrated: preferencesHydrated, userId: currentUserId } = useCalendarPreferences()\n\n const range = React.useMemo(\n () => getVisibleRange(view, anchor, agendaHorizonDays),\n [view, anchor, agendaHorizonDays],\n )\n const { items, isLoading, error, truncated, typeLabels, typeColors, refetch } = useCalendarItems(range)\n\n React.useEffect(() => {\n if (!isLoading) setHasLoadedOnce(true)\n }, [isLoading])\n\n React.useEffect(() => {\n const timer = window.setTimeout(() => setDebouncedSearch(searchText), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [searchText])\n\n React.useEffect(() => {\n if (!highlightItemId) return\n const timer = window.setTimeout(() => setHighlightItemId(null), HIGHLIGHT_CLEAR_MS)\n return () => window.clearTimeout(timer)\n }, [highlightItemId])\n\n const visibleItems = React.useMemo(\n () => items.filter((item) => item.end > range.from && item.start < range.to),\n [items, range],\n )\n\n const searchedItems = React.useMemo(() => {\n const query = debouncedSearch.trim().toLowerCase()\n if (!query) return visibleItems\n return visibleItems.filter((item) => {\n if (item.title.toLowerCase().includes(query)) return true\n if (item.location && item.location.toLowerCase().includes(query)) return true\n const rawBody = (item.raw as { body?: unknown }).body\n if (typeof rawBody === 'string' && rawBody.toLowerCase().includes(query)) return true\n return item.participants.some((participant) =>\n (participant.name ?? '').toLowerCase().includes(query),\n )\n })\n }, [visibleItems, debouncedSearch])\n\n const baseItems = React.useMemo(\n () =>\n searchedItems.filter((item) => {\n if (filters.types.length > 0 && !filters.types.includes(item.interactionType)) return false\n if (filters.status && item.status !== filters.status) return false\n if (filters.ownerUserId && item.ownerUserId !== filters.ownerUserId) return false\n if (!preferences.showCrmActivities && item.category !== 'meeting' && item.category !== 'event') return false\n return true\n }),\n [searchedItems, filters, preferences.showCrmActivities],\n )\n\n const tabCounts = React.useMemo(() => countByCategory(baseItems), [baseItems])\n\n const viewItems = React.useMemo(() => {\n if (tab === 'meetings') return baseItems.filter((item) => item.category === 'meeting')\n if (tab === 'events') return baseItems.filter((item) => item.category === 'event')\n return baseItems\n }, [baseItems, tab])\n\n const conflictMap = React.useMemo(\n () => findConflicts(baseItems, { scope: preferences.conflictScope, currentUserId }),\n [baseItems, preferences.conflictScope, currentUserId],\n )\n const conflictIds = React.useMemo(() => new Set(conflictMap.keys()), [conflictMap])\n\n const upcomingCards = React.useMemo<UpcomingCard[]>(() => {\n const now = new Date()\n const nowMs = now.getTime()\n return baseItems\n .filter((item) => item.start.getTime() >= nowMs)\n .sort((first, second) => first.start.getTime() - second.start.getTime())\n .slice(0, UPCOMING_CARDS_COUNT)\n .map((item) => {\n const conflictCount = preferences.conflictWarnings ? (conflictMap.get(item.id)?.length ?? 0) : 0\n const kind: UpcomingCard['kind'] =\n item.status === 'canceled'\n ? 'cancelled'\n : conflictCount > 0\n ? 'conflicted'\n : isSameDay(item.start, now)\n ? 'today'\n : 'future'\n return { item, kind, conflictCount }\n })\n }, [baseItems, conflictMap, preferences.conflictWarnings])\n\n const typeOptions = React.useMemo(() => {\n const values = new Set<string>(Object.keys(typeLabels))\n for (const item of items) values.add(item.interactionType)\n return [...values]\n .sort()\n .map((value) => ({ value, label: typeLabels[value] ?? value }))\n }, [items, typeLabels])\n\n const ownerOptions = React.useMemo(() => {\n const participantNames = new Map<string, string>()\n for (const item of items) {\n for (const participant of item.participants) {\n if (participant.name && !participantNames.has(participant.userId)) {\n participantNames.set(participant.userId, participant.name)\n }\n }\n }\n const owners = new Map<string, string>()\n for (const item of items) {\n if (!item.ownerUserId || owners.has(item.ownerUserId)) continue\n owners.set(item.ownerUserId, participantNames.get(item.ownerUserId) ?? item.ownerUserId)\n }\n return [...owners.entries()]\n .map(([value, label]) => ({ value, label }))\n .sort((first, second) => first.label.localeCompare(second.label))\n }, [items])\n\n const timezoneLabel = React.useMemo(() => buildTimezoneLabel(), [])\n\n const canManage = useCanManageInteractions()\n\n const openCreateEditor = React.useCallback(() => {\n if (!canManage) return\n setCreateRange(null)\n setEditorMounted(true)\n setEditor({ open: true, mode: 'create', item: null })\n }, [canManage])\n\n const openEditEditor = React.useCallback(\n (item: CalendarItem) => {\n if (!canManage) return\n setCreateRange(null)\n setEditorMounted(true)\n setEditor({ open: true, mode: 'edit', item: asEditableItem(item) })\n },\n [canManage],\n )\n\n const handleCreateRange = React.useCallback(\n (start: Date, end: Date) => {\n if (!canManage) return\n setCreateRange({ start, end })\n setEditorMounted(true)\n setEditor({ open: true, mode: 'create', item: null })\n },\n [canManage],\n )\n\n const seedActivityTypes = React.useMemo(() => {\n const seen = new Set<string>()\n const labels: string[] = []\n for (const value of Object.keys(typeLabels)) {\n const label = typeLabels[value] ?? value\n if (seen.has(label)) continue\n seen.add(label)\n labels.push(label)\n }\n return labels\n }, [typeLabels])\n\n const handleToday = React.useCallback(() => {\n setAnchor(new Date())\n setPreset(null)\n }, [])\n\n const handlePresetChange = React.useCallback((next: CalendarRangePreset) => {\n setPreset(next)\n setAnchor(new Date())\n if (next === 'thisWeek') {\n setView('week')\n } else if (next === 'thisMonth') {\n setView('month')\n } else {\n setView('agenda')\n setAgendaHorizonDays(next === 'next30' ? 30 : DEFAULT_AGENDA_HORIZON_DAYS)\n }\n }, [])\n\n const handleAnchorChange = React.useCallback((date: Date) => {\n setAnchor(date)\n setPreset(null)\n }, [])\n\n const handleViewChange = React.useCallback((next: CalendarView) => {\n setView(next)\n setPreset(null)\n }, [])\n\n const handleTimeGridNavigate = React.useCallback((deltaDays: number) => {\n setAnchor((current) => addDays(current, deltaDays))\n setPreset(null)\n }, [])\n\n const handleDayOpen = React.useCallback((date: Date) => {\n setView('day')\n setAnchor(date)\n setPreset(null)\n }, [])\n\n const handleSeeConflict = React.useCallback((item: CalendarItem) => {\n setView('week')\n setAnchor(item.start)\n setPreset(null)\n setHighlightItemId(item.id)\n }, [])\n\n const handleJoin = React.useCallback((item: CalendarItem) => {\n const url = resolveJoinUrl(item.location)\n if (url) window.open(url, '_blank', 'noopener')\n }, [])\n\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: 'customers-calendar-cancel',\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const handleCancelItem = React.useCallback(\n async (item: CalendarItem) => {\n const interactionId = item.raw.id\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(buildOptimisticLockHeader(item.updatedAt), () =>\n apiCallOrThrow('/api/customers/interactions', {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: interactionId, status: 'canceled' }),\n }),\n ),\n mutationPayload: {\n operation: 'cancelCalendarEvent',\n interactionId,\n interactionType: item.interactionType,\n },\n context: {\n formId: 'customers-calendar-cancel',\n resourceKind: 'customers.interaction',\n resourceId: interactionId,\n retryLastMutation,\n },\n })\n flash(t('customers.calendar.cards.cancelSuccess', 'Event cancelled'), 'success')\n refetch()\n } catch (err) {\n // An optimistic-lock 409 is surfaced as the persistent conflict bar by\n // useGuardedMutation (surfaceRecordConflict) \u2014 don't re-flash.\n if (extractOptimisticLockConflict(err)) return\n flash(t('customers.calendar.cards.cancelError', 'Failed to cancel event'), 'error')\n }\n },\n [refetch, retryLastMutation, runMutation, t],\n )\n\n const focusSearch = React.useCallback(() => {\n const node = document.querySelector('[data-calendar-search]')\n if (node instanceof HTMLInputElement) node.focus()\n else if (node instanceof HTMLElement) node.querySelector('input')?.focus()\n }, [])\n\n const editorOpen = editor.open\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented) return\n if (event.metaKey || event.ctrlKey || event.altKey) return\n const target = event.target\n if (target instanceof HTMLElement) {\n const tag = target.tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable) return\n }\n if (editorOpen) return\n switch (event.key) {\n case 't':\n case 'T':\n event.preventDefault()\n setAnchor(new Date())\n setPreset(null)\n break\n case 'd':\n case 'D':\n event.preventDefault()\n setView('day')\n setPreset(null)\n break\n case 'w':\n case 'W':\n event.preventDefault()\n setView('week')\n setPreset(null)\n break\n case 'm':\n case 'M':\n event.preventDefault()\n setView('month')\n setPreset(null)\n break\n case 'a':\n case 'A':\n event.preventDefault()\n setView('agenda')\n setPreset(null)\n break\n case 'n':\n case 'N':\n event.preventDefault()\n openCreateEditor()\n break\n case '/':\n event.preventDefault()\n focusSearch()\n break\n case '?':\n event.preventDefault()\n setShortcutsOpen((open) => !open)\n break\n case 'Escape':\n setHighlightItemId(null)\n break\n default:\n break\n }\n }\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [editorOpen, focusSearch, openCreateEditor])\n\n const showInitialLoading = (isLoading && !hasLoadedOnce) || !preferencesHydrated\n\n let viewArea: React.ReactNode\n if (error) {\n viewArea = (\n <ErrorMessage\n label={t('customers.calendar.errors.loadFailed', 'Failed to load calendar events.')}\n action={\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={refetch}>\n {t('customers.calendar.errors.retry', 'Retry')}\n </Button>\n }\n />\n )\n } else if (showInitialLoading) {\n viewArea = <LoadingMessage label={t('customers.calendar.loading', 'Loading calendar\u2026')} />\n } else if (view === 'month') {\n viewArea = (\n <MonthGrid anchor={anchor} items={viewItems} onItemClick={openEditEditor} onDayOpen={handleDayOpen} />\n )\n } else if (view === 'agenda') {\n viewArea = (\n <AgendaList\n anchor={anchor}\n horizonDays={agendaHorizonDays}\n items={viewItems}\n typeLabels={typeLabels}\n onItemClick={openEditEditor}\n />\n )\n } else {\n viewArea = (\n <TimeGrid\n days={view === 'day' ? 1 : 7}\n anchor={anchor}\n items={viewItems}\n conflictIds={conflictIds}\n showWeekends={preferences.showWeekends}\n showConflicts={preferences.conflictWarnings}\n aiSummaries={preferences.aiSummaries}\n canManage={canManage}\n highlightItemId={highlightItemId}\n onItemClick={openEditEditor}\n onJoin={handleJoin}\n onNavigate={handleTimeGridNavigate}\n onCreate={canManage ? openCreateEditor : undefined}\n onCreateRange={canManage ? handleCreateRange : undefined}\n />\n )\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4\">\n <CalendarHeader view={view} anchor={anchor} onNewEvent={canManage ? openCreateEditor : undefined} />\n <CalendarToolbar\n view={view}\n anchor={anchor}\n range={range}\n preset={preset}\n search={searchText}\n filters={filters}\n typeOptions={typeOptions}\n ownerOptions={ownerOptions}\n onToday={handleToday}\n onPresetChange={handlePresetChange}\n onAnchorChange={handleAnchorChange}\n onSearchChange={setSearchText}\n onFiltersChange={setFilters}\n onOpenSettings={() => setSettingsOpen(true)}\n />\n <UpcomingCards\n cards={upcomingCards}\n canManage={canManage}\n onJoin={handleJoin}\n onSeeConflict={handleSeeConflict}\n onOpen={openEditEditor}\n onEdit={openEditEditor}\n onCancel={handleCancelItem}\n />\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n <CalendarTabs\n tab={tab}\n counts={tabCounts}\n view={view}\n onTabChange={setTab}\n onViewChange={handleViewChange}\n />\n {truncated ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {t('customers.calendar.notice.truncated', 'Showing first {count} items for this range.', {\n count: MAX_WINDOW_ITEMS,\n })}\n </p>\n ) : null}\n <div className=\"flex min-h-[560px] flex-1 flex-col [&>*]:flex-1\">{viewArea}</div>\n </div>\n <div className=\"hidden md:block\">\n <CalendarFooter timezoneLabel={timezoneLabel} onOpenShortcuts={() => setShortcutsOpen(true)} />\n </div>\n <ShortcutsDialog open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n <CalendarSettingsModal\n open={settingsOpen}\n preferences={preferences}\n seedActivityTypes={seedActivityTypes}\n onOpenChange={setSettingsOpen}\n onSave={(next) => {\n setPreferences(next)\n flash(t('customers.calendar.settings.saved', 'Calendar settings saved'), 'success')\n }}\n />\n {editorMounted ? (\n <CalendarEventEditor\n open={editor.open}\n mode={editor.mode}\n item={editor.item}\n defaultDate={anchor}\n defaultRange={createRange}\n typeLabels={typeLabels}\n typeColors={typeColors}\n surfacedTypes={preferences.activityTypes}\n eventCategories={preferences.eventCategories}\n conflictScope={preferences.conflictScope}\n currentUserId={currentUserId}\n onOpenChange={(open) => setEditor((current) => ({ ...current, open }))}\n onSaved={refetch}\n />\n ) : null}\n </div>\n )\n}\n"],
5
- "mappings": ";AAqdU,cAuEJ,YAvEI;AAndV,YAAY,WAAW;AACvB,OAAO,aAAa;AACpB,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AACrB,SAAS,SAAS,gBAAgB,mCAAmC;AACrE,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,aAAa;AACtB,SAAS,0BAA0B;AACnC,SAAS,cAAc,sBAAsB;AAC7C,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,kBAAkB,wBAAwB;AAUnD,MAAM,sBAAsB;AAAA,EAC1B,MAAM,OAAO,uBAAuB,EAAE,KAAK,CAAC,QAAQ,IAAI,mBAAmB;AAAA,EAC3E,EAAE,KAAK,MAAM;AACf;AAEA,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AAC3B,MAAM,8BAA8B;AACpC,MAAM,uBAAuB;AAC7B,MAAM,gBAAsC,EAAE,OAAO,CAAC,GAAG,QAAQ,MAAM,aAAa,KAAK;AAIzF,MAAM,iBAAiB;AAEvB,SAAS,2BAAoC;AAC3C,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AACtD,QAAM,UAAU,MAAM;AACpB,UAAM,aAAa,IAAI,gBAAgB;AACvC,QAAI,YAAY;AAChB,YAAiC,2BAA2B;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,QAAQ,WAAW;AAAA,MACnB,MAAM,KAAK,UAAU,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC;AAAA,IACrD,CAAC,EACE,KAAK,CAAC,SAAS;AACd,UAAI,aAAa,CAAC,KAAK,GAAI;AAC3B,YAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ,OAAO,IAC9C,KAAK,OAAO,QAAQ,IAAI,CAAC,YAAY,OAAO,OAAO,CAAC,IACpD,CAAC;AACL,mBAAa,QAAQ,KAAK,CAAC,mBAAmB,aAAa,gBAAgB,cAAc,CAAC,CAAC;AAAA,IAC7F,CAAC,EACA,MAAM,MAAM;AACX,UAAI,CAAC,aAAa,CAAC,WAAW,OAAO,QAAS,cAAa,KAAK;AAAA,IAClE,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AACZ,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAEA,SAAS,qBAA6B;AACpC,QAAM,WAAW,KAAK,eAAe,EAAE,gBAAgB,EAAE;AACzD,QAAM,gBAAgB,EAAC,oBAAI,KAAK,GAAE,kBAAkB;AACpD,QAAM,OAAO,iBAAiB,IAAI,MAAM;AACxC,QAAM,WAAW,KAAK,IAAI,aAAa;AACvC,QAAM,QAAQ,KAAK,MAAM,WAAW,EAAE;AACtC,QAAM,UAAU,WAAW;AAC3B,QAAM,SAAS,UAAU,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,KAAK;AACpG,SAAO,GAAG,QAAQ,QAAQ,MAAM;AAClC;AAEA,SAAS,eAAe,UAAwC;AAC9D,QAAM,UAAU,UAAU,KAAK,KAAK;AACpC,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,gBAAgB,KAAK,OAAO,EAAG,QAAO;AAC1C,MAAI,UAAU,KAAK,OAAO,EAAG,QAAO,WAAW,OAAO;AACtD,SAAO;AACT;AAEA,SAAS,eAAe,MAAkC;AACxD,SAAO,KAAK,wBAAwB,EAAE,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,IAAI;AACrE;AAEO,SAAS,iBAAiB;AAC/B,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAuB,MAAM;AAC3D,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAe,MAAM,oBAAI,KAAK,CAAC;AACjE,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAS,2BAA2B;AAC5F,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAqC,UAAU;AAEjF,QAAM,UAAU,MAAM;AACpB,QAAI,OAAO,cAAc,oBAAqB;AAC9C,YAAQ,KAAK;AACb,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AACL,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAsB,KAAK;AACvD,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,EAAE;AACrD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,EAAE;AAC/D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA+B,aAAa;AAChF,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAsB,EAAE,MAAM,OAAO,MAAM,UAAU,MAAM,KAAK,CAAC;AACnG,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAA4C,IAAI;AAC5F,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAS,KAAK;AAC5D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAwB,IAAI;AAChF,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,EAAE,aAAa,gBAAgB,UAAU,qBAAqB,QAAQ,cAAc,IAAI,uBAAuB;AAErH,QAAM,QAAQ,MAAM;AAAA,IAClB,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB;AAAA,IACrD,CAAC,MAAM,QAAQ,iBAAiB;AAAA,EAClC;AACA,QAAM,EAAE,OAAO,WAAW,OAAO,WAAW,YAAY,YAAY,QAAQ,IAAI,iBAAiB,KAAK;AAEtG,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,UAAW,kBAAiB,IAAI;AAAA,EACvC,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,UAAU,MAAM;AACpB,UAAM,QAAQ,OAAO,WAAW,MAAM,mBAAmB,UAAU,GAAG,kBAAkB;AACxF,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,gBAAiB;AACtB,UAAM,QAAQ,OAAO,WAAW,MAAM,mBAAmB,IAAI,GAAG,kBAAkB;AAClF,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,eAAe,MAAM;AAAA,IACzB,MAAM,MAAM,OAAO,CAAC,SAAS,KAAK,MAAM,MAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE;AAAA,IAC3E,CAAC,OAAO,KAAK;AAAA,EACf;AAEA,QAAM,gBAAgB,MAAM,QAAQ,MAAM;AACxC,UAAM,QAAQ,gBAAgB,KAAK,EAAE,YAAY;AACjD,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,aAAa,OAAO,CAAC,SAAS;AACnC,UAAI,KAAK,MAAM,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACrD,UAAI,KAAK,YAAY,KAAK,SAAS,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACzE,YAAM,UAAW,KAAK,IAA2B;AACjD,UAAI,OAAO,YAAY,YAAY,QAAQ,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACjF,aAAO,KAAK,aAAa;AAAA,QAAK,CAAC,iBAC5B,YAAY,QAAQ,IAAI,YAAY,EAAE,SAAS,KAAK;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,eAAe,CAAC;AAElC,QAAM,YAAY,MAAM;AAAA,IACtB,MACE,cAAc,OAAO,CAAC,SAAS;AAC7B,UAAI,QAAQ,MAAM,SAAS,KAAK,CAAC,QAAQ,MAAM,SAAS,KAAK,eAAe,EAAG,QAAO;AACtF,UAAI,QAAQ,UAAU,KAAK,WAAW,QAAQ,OAAQ,QAAO;AAC7D,UAAI,QAAQ,eAAe,KAAK,gBAAgB,QAAQ,YAAa,QAAO;AAC5E,UAAI,CAAC,YAAY,qBAAqB,KAAK,aAAa,aAAa,KAAK,aAAa,QAAS,QAAO;AACvG,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,eAAe,SAAS,YAAY,iBAAiB;AAAA,EACxD;AAEA,QAAM,YAAY,MAAM,QAAQ,MAAM,gBAAgB,SAAS,GAAG,CAAC,SAAS,CAAC;AAE7E,QAAM,YAAY,MAAM,QAAQ,MAAM;AACpC,QAAI,QAAQ,WAAY,QAAO,UAAU,OAAO,CAAC,SAAS,KAAK,aAAa,SAAS;AACrF,QAAI,QAAQ,SAAU,QAAO,UAAU,OAAO,CAAC,SAAS,KAAK,aAAa,OAAO;AACjF,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,GAAG,CAAC;AAEnB,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,cAAc,WAAW,EAAE,OAAO,YAAY,eAAe,cAAc,CAAC;AAAA,IAClF,CAAC,WAAW,YAAY,eAAe,aAAa;AAAA,EACtD;AACA,QAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,IAAI,YAAY,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;AAElF,QAAM,gBAAgB,MAAM,QAAwB,MAAM;AACxD,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,QAAQ;AAC1B,WAAO,UACJ,OAAO,CAAC,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,EAC9C,KAAK,CAAC,OAAO,WAAW,MAAM,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ,CAAC,EACtE,MAAM,GAAG,oBAAoB,EAC7B,IAAI,CAAC,SAAS;AACb,YAAM,gBAAgB,YAAY,mBAAoB,YAAY,IAAI,KAAK,EAAE,GAAG,UAAU,IAAK;AAC/F,YAAM,OACJ,KAAK,WAAW,aACZ,cACA,gBAAgB,IACd,eACA,UAAU,KAAK,OAAO,GAAG,IACvB,UACA;AACV,aAAO,EAAE,MAAM,MAAM,cAAc;AAAA,IACrC,CAAC;AAAA,EACL,GAAG,CAAC,WAAW,aAAa,YAAY,gBAAgB,CAAC;AAEzD,QAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAM,SAAS,IAAI,IAAY,OAAO,KAAK,UAAU,CAAC;AACtD,eAAW,QAAQ,MAAO,QAAO,IAAI,KAAK,eAAe;AACzD,WAAO,CAAC,GAAG,MAAM,EACd,KAAK,EACL,IAAI,CAAC,WAAW,EAAE,OAAO,OAAO,WAAW,KAAK,KAAK,MAAM,EAAE;AAAA,EAClE,GAAG,CAAC,OAAO,UAAU,CAAC;AAEtB,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,mBAAmB,oBAAI,IAAoB;AACjD,eAAW,QAAQ,OAAO;AACxB,iBAAW,eAAe,KAAK,cAAc;AAC3C,YAAI,YAAY,QAAQ,CAAC,iBAAiB,IAAI,YAAY,MAAM,GAAG;AACjE,2BAAiB,IAAI,YAAY,QAAQ,YAAY,IAAI;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,KAAK,eAAe,OAAO,IAAI,KAAK,WAAW,EAAG;AACvD,aAAO,IAAI,KAAK,aAAa,iBAAiB,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW;AAAA,IACzF;AACA,WAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,EACxB,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,EAC1C,KAAK,CAAC,OAAO,WAAW,MAAM,MAAM,cAAc,OAAO,KAAK,CAAC;AAAA,EACpE,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,gBAAgB,MAAM,QAAQ,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAElE,QAAM,YAAY,yBAAyB;AAE3C,QAAM,mBAAmB,MAAM,YAAY,MAAM;AAC/C,QAAI,CAAC,UAAW;AAChB,mBAAe,IAAI;AACnB,qBAAiB,IAAI;AACrB,cAAU,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,CAAC;AAAA,EACtD,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,SAAuB;AACtB,UAAI,CAAC,UAAW;AAChB,qBAAe,IAAI;AACnB,uBAAiB,IAAI;AACrB,gBAAU,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,eAAe,IAAI,EAAE,CAAC;AAAA,IACpE;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,oBAAoB,MAAM;AAAA,IAC9B,CAAC,OAAa,QAAc;AAC1B,UAAI,CAAC,UAAW;AAChB,qBAAe,EAAE,OAAO,IAAI,CAAC;AAC7B,uBAAiB,IAAI;AACrB,gBAAU,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,CAAC;AAAA,IACtD;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,oBAAoB,MAAM,QAAQ,MAAM;AAC5C,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,OAAO,KAAK,UAAU,GAAG;AAC3C,YAAM,QAAQ,WAAW,KAAK,KAAK;AACnC,UAAI,KAAK,IAAI,KAAK,EAAG;AACrB,WAAK,IAAI,KAAK;AACd,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,cAAU,oBAAI,KAAK,CAAC;AACpB,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,CAAC,SAA8B;AAC1E,cAAU,IAAI;AACd,cAAU,oBAAI,KAAK,CAAC;AACpB,QAAI,SAAS,YAAY;AACvB,cAAQ,MAAM;AAAA,IAChB,WAAW,SAAS,aAAa;AAC/B,cAAQ,OAAO;AAAA,IACjB,OAAO;AACL,cAAQ,QAAQ;AAChB,2BAAqB,SAAS,WAAW,KAAK,2BAA2B;AAAA,IAC3E;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,CAAC,SAAe;AAC3D,cAAU,IAAI;AACd,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAmB,MAAM,YAAY,CAAC,SAAuB;AACjE,YAAQ,IAAI;AACZ,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAyB,MAAM,YAAY,CAAC,cAAsB;AACtE,cAAU,CAAC,YAAY,QAAQ,SAAS,SAAS,CAAC;AAClD,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,MAAM,YAAY,CAAC,SAAe;AACtD,YAAQ,KAAK;AACb,cAAU,IAAI;AACd,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,MAAM,YAAY,CAAC,SAAuB;AAClE,YAAQ,MAAM;AACd,cAAU,KAAK,KAAK;AACpB,cAAU,IAAI;AACd,uBAAmB,KAAK,EAAE;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM,YAAY,CAAC,SAAuB;AAC3D,UAAM,MAAM,eAAe,KAAK,QAAQ;AACxC,QAAI,IAAK,QAAO,KAAK,KAAK,UAAU,UAAU;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,aAAa,kBAAkB,IAAI,mBAKxC;AAAA,IACD,WAAW;AAAA,IACX,gBAAgB,EAAE,8BAA8B,4BAA4B;AAAA,EAC9E,CAAC;AAED,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,SAAuB;AAC5B,YAAM,gBAAgB,KAAK,IAAI;AAC/B,UAAI;AACF,cAAM,YAAY;AAAA,UAChB,WAAW,MACT;AAAA,YAA4B,0BAA0B,KAAK,SAAS;AAAA,YAAG,MACrE,eAAe,+BAA+B;AAAA,cAC5C,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU,EAAE,IAAI,eAAe,QAAQ,WAAW,CAAC;AAAA,YAChE,CAAC;AAAA,UACH;AAAA,UACF,iBAAiB;AAAA,YACf,WAAW;AAAA,YACX;AAAA,YACA,iBAAiB,KAAK;AAAA,UACxB;AAAA,UACA,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,YAAY;AAAA,YACZ;AAAA,UACF;AAAA,QACF,CAAC;AACD,cAAM,EAAE,0CAA0C,iBAAiB,GAAG,SAAS;AAC/E,gBAAQ;AAAA,MACV,SAAS,KAAK;AAGZ,YAAI,8BAA8B,GAAG,EAAG;AACxC,cAAM,EAAE,wCAAwC,wBAAwB,GAAG,OAAO;AAAA,MACpF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,mBAAmB,aAAa,CAAC;AAAA,EAC7C;AAEA,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,UAAM,OAAO,SAAS,cAAc,wBAAwB;AAC5D,QAAI,gBAAgB,iBAAkB,MAAK,MAAM;AAAA,aACxC,gBAAgB,YAAa,MAAK,cAAc,OAAO,GAAG,MAAM;AAAA,EAC3E,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,OAAO;AAC1B,QAAM,UAAU,MAAM;AACpB,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,UAAI,MAAM,iBAAkB;AAC5B,UAAI,MAAM,WAAW,MAAM,WAAW,MAAM,OAAQ;AACpD,YAAM,SAAS,MAAM;AACrB,UAAI,kBAAkB,aAAa;AACjC,cAAM,MAAM,OAAO;AACnB,YAAI,QAAQ,WAAW,QAAQ,cAAc,QAAQ,YAAY,OAAO,kBAAmB;AAAA,MAC7F;AACA,UAAI,WAAY;AAChB,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,oBAAU,oBAAI,KAAK,CAAC;AACpB,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,KAAK;AACb,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,MAAM;AACd,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,OAAO;AACf,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,QAAQ;AAChB,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,2BAAiB;AACjB;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,sBAAY;AACZ;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,2BAAiB,CAAC,SAAS,CAAC,IAAI;AAChC;AAAA,QACF,KAAK;AACH,6BAAmB,IAAI;AACvB;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAChD,WAAO,MAAM,OAAO,oBAAoB,WAAW,aAAa;AAAA,EAClE,GAAG,CAAC,YAAY,aAAa,gBAAgB,CAAC;AAE9C,QAAM,qBAAsB,aAAa,CAAC,iBAAkB,CAAC;AAE7D,MAAI;AACJ,MAAI,OAAO;AACT,eACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,wCAAwC,iCAAiC;AAAA,QAClF,QACE,oBAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,MAAK,MAAK,SAAS,SACxD,YAAE,mCAAmC,OAAO,GAC/C;AAAA;AAAA,IAEJ;AAAA,EAEJ,WAAW,oBAAoB;AAC7B,eAAW,oBAAC,kBAAe,OAAO,EAAE,8BAA8B,wBAAmB,GAAG;AAAA,EAC1F,WAAW,SAAS,SAAS;AAC3B,eACE,oBAAC,aAAU,QAAgB,OAAO,WAAW,aAAa,gBAAgB,WAAW,eAAe;AAAA,EAExG,WAAW,SAAS,UAAU;AAC5B,eACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,aAAa;AAAA,QACb,OAAO;AAAA,QACP;AAAA,QACA,aAAa;AAAA;AAAA,IACf;AAAA,EAEJ,OAAO;AACL,eACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,SAAS,QAAQ,IAAI;AAAA,QAC3B;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,cAAc,YAAY;AAAA,QAC1B,eAAe,YAAY;AAAA,QAC3B,aAAa,YAAY;AAAA,QACzB;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,UAAU,YAAY,mBAAmB;AAAA,QACzC,eAAe,YAAY,oBAAoB;AAAA;AAAA,IACjD;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,sCACb;AAAA,wBAAC,kBAAe,MAAY,QAAgB,YAAY,YAAY,mBAAmB,QAAW;AAAA,IAClG;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,gBAAgB,MAAM,gBAAgB,IAAI;AAAA;AAAA,IAC5C;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU;AAAA;AAAA,IACZ;AAAA,IACA,qBAAC,SAAI,WAAU,sCACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,UACA,aAAa;AAAA,UACb,cAAc;AAAA;AAAA,MAChB;AAAA,MACC,YACC,oBAAC,OAAE,WAAU,iCAAgC,MAAK,UAC/C,YAAE,uCAAuC,+CAA+C;AAAA,QACvF,OAAO;AAAA,MACT,CAAC,GACH,IACE;AAAA,MACJ,oBAAC,SAAI,WAAU,mDAAmD,oBAAS;AAAA,OAC7E;AAAA,IACA,oBAAC,SAAI,WAAU,mBACb,8BAAC,kBAAe,eAA8B,iBAAiB,MAAM,iBAAiB,IAAI,GAAG,GAC/F;AAAA,IACA,oBAAC,mBAAgB,MAAM,eAAe,cAAc,kBAAkB;AAAA,IACtE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,QAAQ,CAAC,SAAS;AAChB,yBAAe,IAAI;AACnB,gBAAM,EAAE,qCAAqC,yBAAyB,GAAG,SAAS;AAAA,QACpF;AAAA;AAAA,IACF;AAAA,IACC,gBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,aAAa;AAAA,QACb,cAAc;AAAA,QACd;AAAA,QACA;AAAA,QACA,eAAe,YAAY;AAAA,QAC3B,iBAAiB,YAAY;AAAA,QAC7B,eAAe,YAAY;AAAA,QAC3B;AAAA,QACA,cAAc,CAAC,SAAS,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,KAAK,EAAE;AAAA,QACrE,SAAS;AAAA;AAAA,IACX,IACE;AAAA,KACN;AAEJ;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport dynamic from 'next/dynamic'\nimport { addDays } from 'date-fns/addDays'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall, apiCallOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { matchFeature } from '@open-mercato/shared/lib/auth/featureMatch'\nimport {\n buildOptimisticLockHeader,\n extractOptimisticLockConflict,\n} from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { ErrorMessage, LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { countByCategory } from '../../lib/calendar/categories'\nimport { findConflicts } from '../../lib/calendar/conflicts'\nimport { getVisibleRange } from '../../lib/calendar/range'\nimport { AgendaList } from './AgendaList'\nimport { CalendarFooter } from './CalendarFooter'\nimport { CalendarHeader } from './CalendarHeader'\nimport { CalendarTabs } from './CalendarTabs'\nimport { CalendarToolbar } from './CalendarToolbar'\nimport { MonthGrid } from './MonthGrid'\nimport { ShortcutsDialog } from './ShortcutsDialog'\nimport { TimeGrid } from './TimeGrid'\nimport { UpcomingCards } from './UpcomingCards'\nimport { CalendarSettingsModal } from './CalendarSettingsModal'\nimport { useCalendarPreferences } from './useCalendarPreferences'\nimport { MAX_WINDOW_ITEMS, useCalendarItems } from './useCalendarItems'\nimport type {\n CalendarFiltersValue,\n CalendarItem,\n CalendarRangePreset,\n CalendarTab,\n CalendarView,\n UpcomingCard,\n} from './types'\n\nconst CalendarEventEditor = dynamic(\n () => import('./CalendarEventEditor').then((mod) => mod.CalendarEventEditor),\n { ssr: false },\n)\n\nconst SEARCH_DEBOUNCE_MS = 200\nconst PHONE_BREAKPOINT_PX = 640\nconst HIGHLIGHT_CLEAR_MS = 3000\nconst DEFAULT_AGENDA_HORIZON_DAYS = 7\nconst UPCOMING_CARDS_COUNT = 4\nconst EMPTY_FILTERS: CalendarFiltersValue = { types: [], status: null, ownerUserId: null }\n\ntype EditorState = { open: boolean; mode: 'create' | 'edit'; item: CalendarItem | null }\n\nconst MANAGE_FEATURE = 'customers.interactions.manage'\n\nfunction useCanManageInteractions(): boolean {\n const [canManage, setCanManage] = React.useState(false)\n React.useEffect(() => {\n const controller = new AbortController()\n let cancelled = false\n apiCall<{ granted?: unknown[] }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n body: JSON.stringify({ features: [MANAGE_FEATURE] }),\n })\n .then((call) => {\n if (cancelled || !call.ok) return\n const granted = Array.isArray(call.result?.granted)\n ? call.result.granted.map((feature) => String(feature))\n : []\n setCanManage(granted.some((grantedFeature) => matchFeature(MANAGE_FEATURE, grantedFeature)))\n })\n .catch(() => {\n if (!cancelled && !controller.signal.aborted) setCanManage(false)\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [])\n return canManage\n}\n\nfunction buildTimezoneLabel(): string {\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone\n const offsetMinutes = -new Date().getTimezoneOffset()\n const sign = offsetMinutes >= 0 ? '+' : '-'\n const absolute = Math.abs(offsetMinutes)\n const hours = Math.floor(absolute / 60)\n const minutes = absolute % 60\n const offset = minutes > 0 ? `${sign}${hours}:${String(minutes).padStart(2, '0')}` : `${sign}${hours}`\n return `${timeZone} (GMT${offset})`\n}\n\nfunction resolveJoinUrl(location: string | null): string | null {\n const trimmed = location?.trim() ?? ''\n if (!trimmed) return null\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed\n if (/^www\\./i.test(trimmed)) return `https://${trimmed}`\n return null\n}\n\nfunction asEditableItem(item: CalendarItem): CalendarItem {\n return item.isRecurringOccurrence ? { ...item, id: item.raw.id } : item\n}\n\nexport function CalendarScreen() {\n const t = useT()\n const [view, setView] = React.useState<CalendarView>('week')\n const [anchor, setAnchor] = React.useState<Date>(() => new Date())\n const [agendaHorizonDays, setAgendaHorizonDays] = React.useState(DEFAULT_AGENDA_HORIZON_DAYS)\n const [preset, setPreset] = React.useState<CalendarRangePreset | null>('thisWeek')\n\n React.useEffect(() => {\n if (window.innerWidth >= PHONE_BREAKPOINT_PX) return\n setView('day')\n setPreset(null)\n }, [])\n const [tab, setTab] = React.useState<CalendarTab>('all')\n const [searchText, setSearchText] = React.useState('')\n const [debouncedSearch, setDebouncedSearch] = React.useState('')\n const [filters, setFilters] = React.useState<CalendarFiltersValue>(EMPTY_FILTERS)\n const [editor, setEditor] = React.useState<EditorState>({ open: false, mode: 'create', item: null })\n const [editorMounted, setEditorMounted] = React.useState(false)\n const [createRange, setCreateRange] = React.useState<{ start: Date; end: Date } | null>(null)\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false)\n const [settingsOpen, setSettingsOpen] = React.useState(false)\n const [highlightItemId, setHighlightItemId] = React.useState<string | null>(null)\n const [hasLoadedOnce, setHasLoadedOnce] = React.useState(false)\n const { preferences, setPreferences, hydrated: preferencesHydrated, userId: currentUserId } = useCalendarPreferences()\n\n const range = React.useMemo(\n () => getVisibleRange(view, anchor, agendaHorizonDays),\n [view, anchor, agendaHorizonDays],\n )\n const { items, isLoading, error, truncated, typeLabels, typeColors, refetch } = useCalendarItems(range)\n\n React.useEffect(() => {\n if (!isLoading) setHasLoadedOnce(true)\n }, [isLoading])\n\n React.useEffect(() => {\n const timer = window.setTimeout(() => setDebouncedSearch(searchText), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [searchText])\n\n React.useEffect(() => {\n if (!highlightItemId) return\n const timer = window.setTimeout(() => setHighlightItemId(null), HIGHLIGHT_CLEAR_MS)\n return () => window.clearTimeout(timer)\n }, [highlightItemId])\n\n const visibleItems = React.useMemo(\n () => items.filter((item) => item.end > range.from && item.start < range.to),\n [items, range],\n )\n\n const searchedItems = React.useMemo(() => {\n const query = debouncedSearch.trim().toLowerCase()\n if (!query) return visibleItems\n return visibleItems.filter((item) => {\n if (item.title.toLowerCase().includes(query)) return true\n if (item.location && item.location.toLowerCase().includes(query)) return true\n const rawBody = (item.raw as { body?: unknown }).body\n if (typeof rawBody === 'string' && rawBody.toLowerCase().includes(query)) return true\n return item.participants.some((participant) =>\n (participant.name ?? '').toLowerCase().includes(query),\n )\n })\n }, [visibleItems, debouncedSearch])\n\n const baseItems = React.useMemo(\n () =>\n searchedItems.filter((item) => {\n if (filters.types.length > 0 && !filters.types.includes(item.interactionType)) return false\n if (filters.status && item.status !== filters.status) return false\n if (filters.ownerUserId && item.ownerUserId !== filters.ownerUserId) return false\n if (!preferences.showCrmActivities && item.category !== 'meeting' && item.category !== 'event') return false\n return true\n }),\n [searchedItems, filters, preferences.showCrmActivities],\n )\n\n const tabCounts = React.useMemo(() => countByCategory(baseItems), [baseItems])\n\n const viewItems = React.useMemo(() => {\n if (tab === 'meetings') return baseItems.filter((item) => item.category === 'meeting')\n if (tab === 'events') return baseItems.filter((item) => item.category === 'event')\n return baseItems\n }, [baseItems, tab])\n\n const conflictMap = React.useMemo(\n () => findConflicts(baseItems, { scope: preferences.conflictScope, currentUserId }),\n [baseItems, preferences.conflictScope, currentUserId],\n )\n const conflictIds = React.useMemo(() => new Set(conflictMap.keys()), [conflictMap])\n\n const upcomingCards = React.useMemo<UpcomingCard[]>(() => {\n const now = new Date()\n const nowMs = now.getTime()\n return baseItems\n .filter((item) => item.start.getTime() >= nowMs)\n .sort((first, second) => first.start.getTime() - second.start.getTime())\n .slice(0, UPCOMING_CARDS_COUNT)\n .map((item) => {\n const conflictCount = preferences.conflictWarnings ? (conflictMap.get(item.id)?.length ?? 0) : 0\n const kind: UpcomingCard['kind'] =\n item.status === 'canceled'\n ? 'cancelled'\n : conflictCount > 0\n ? 'conflicted'\n : isSameDay(item.start, now)\n ? 'today'\n : 'future'\n return { item, kind, conflictCount }\n })\n }, [baseItems, conflictMap, preferences.conflictWarnings])\n\n const typeOptions = React.useMemo(() => {\n const values = new Set<string>(Object.keys(typeLabels))\n for (const item of items) values.add(item.interactionType)\n return [...values]\n .sort((a, b) => a.localeCompare(b))\n .map((value) => ({ value, label: typeLabels[value] ?? value }))\n }, [items, typeLabels])\n\n const ownerOptions = React.useMemo(() => {\n const participantNames = new Map<string, string>()\n for (const item of items) {\n for (const participant of item.participants) {\n if (participant.name && !participantNames.has(participant.userId)) {\n participantNames.set(participant.userId, participant.name)\n }\n }\n }\n const owners = new Map<string, string>()\n for (const item of items) {\n if (!item.ownerUserId || owners.has(item.ownerUserId)) continue\n owners.set(item.ownerUserId, participantNames.get(item.ownerUserId) ?? item.ownerUserId)\n }\n return [...owners.entries()]\n .map(([value, label]) => ({ value, label }))\n .sort((first, second) => first.label.localeCompare(second.label))\n }, [items])\n\n const timezoneLabel = React.useMemo(() => buildTimezoneLabel(), [])\n\n const canManage = useCanManageInteractions()\n\n const openCreateEditor = React.useCallback(() => {\n if (!canManage) return\n setCreateRange(null)\n setEditorMounted(true)\n setEditor({ open: true, mode: 'create', item: null })\n }, [canManage])\n\n const openEditEditor = React.useCallback(\n (item: CalendarItem) => {\n if (!canManage) return\n setCreateRange(null)\n setEditorMounted(true)\n setEditor({ open: true, mode: 'edit', item: asEditableItem(item) })\n },\n [canManage],\n )\n\n const handleCreateRange = React.useCallback(\n (start: Date, end: Date) => {\n if (!canManage) return\n setCreateRange({ start, end })\n setEditorMounted(true)\n setEditor({ open: true, mode: 'create', item: null })\n },\n [canManage],\n )\n\n const seedActivityTypes = React.useMemo(() => {\n const seen = new Set<string>()\n const labels: string[] = []\n for (const value of Object.keys(typeLabels)) {\n const label = typeLabels[value] ?? value\n if (seen.has(label)) continue\n seen.add(label)\n labels.push(label)\n }\n return labels\n }, [typeLabels])\n\n const handleToday = React.useCallback(() => {\n setAnchor(new Date())\n setPreset(null)\n }, [])\n\n const handlePresetChange = React.useCallback((next: CalendarRangePreset) => {\n setPreset(next)\n setAnchor(new Date())\n if (next === 'thisWeek') {\n setView('week')\n } else if (next === 'thisMonth') {\n setView('month')\n } else {\n setView('agenda')\n setAgendaHorizonDays(next === 'next30' ? 30 : DEFAULT_AGENDA_HORIZON_DAYS)\n }\n }, [])\n\n const handleAnchorChange = React.useCallback((date: Date) => {\n setAnchor(date)\n setPreset(null)\n }, [])\n\n const handleViewChange = React.useCallback((next: CalendarView) => {\n setView(next)\n setPreset(null)\n }, [])\n\n const handleTimeGridNavigate = React.useCallback((deltaDays: number) => {\n setAnchor((current) => addDays(current, deltaDays))\n setPreset(null)\n }, [])\n\n const handleDayOpen = React.useCallback((date: Date) => {\n setView('day')\n setAnchor(date)\n setPreset(null)\n }, [])\n\n const handleSeeConflict = React.useCallback((item: CalendarItem) => {\n setView('week')\n setAnchor(item.start)\n setPreset(null)\n setHighlightItemId(item.id)\n }, [])\n\n const handleJoin = React.useCallback((item: CalendarItem) => {\n const url = resolveJoinUrl(item.location)\n if (url) window.open(url, '_blank', 'noopener')\n }, [])\n\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: 'customers-calendar-cancel',\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const handleCancelItem = React.useCallback(\n async (item: CalendarItem) => {\n const interactionId = item.raw.id\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(buildOptimisticLockHeader(item.updatedAt), () =>\n apiCallOrThrow('/api/customers/interactions', {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: interactionId, status: 'canceled' }),\n }),\n ),\n mutationPayload: {\n operation: 'cancelCalendarEvent',\n interactionId,\n interactionType: item.interactionType,\n },\n context: {\n formId: 'customers-calendar-cancel',\n resourceKind: 'customers.interaction',\n resourceId: interactionId,\n retryLastMutation,\n },\n })\n flash(t('customers.calendar.cards.cancelSuccess', 'Event cancelled'), 'success')\n refetch()\n } catch (err) {\n // An optimistic-lock 409 is surfaced as the persistent conflict bar by\n // useGuardedMutation (surfaceRecordConflict) \u2014 don't re-flash.\n if (extractOptimisticLockConflict(err)) return\n flash(t('customers.calendar.cards.cancelError', 'Failed to cancel event'), 'error')\n }\n },\n [refetch, retryLastMutation, runMutation, t],\n )\n\n const focusSearch = React.useCallback(() => {\n const node = document.querySelector('[data-calendar-search]')\n if (node instanceof HTMLInputElement) node.focus()\n else if (node instanceof HTMLElement) node.querySelector('input')?.focus()\n }, [])\n\n const editorOpen = editor.open\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented) return\n if (event.metaKey || event.ctrlKey || event.altKey) return\n const target = event.target\n if (target instanceof HTMLElement) {\n const tag = target.tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable) return\n }\n if (editorOpen) return\n switch (event.key) {\n case 't':\n case 'T':\n event.preventDefault()\n setAnchor(new Date())\n setPreset(null)\n break\n case 'd':\n case 'D':\n event.preventDefault()\n setView('day')\n setPreset(null)\n break\n case 'w':\n case 'W':\n event.preventDefault()\n setView('week')\n setPreset(null)\n break\n case 'm':\n case 'M':\n event.preventDefault()\n setView('month')\n setPreset(null)\n break\n case 'a':\n case 'A':\n event.preventDefault()\n setView('agenda')\n setPreset(null)\n break\n case 'n':\n case 'N':\n event.preventDefault()\n openCreateEditor()\n break\n case '/':\n event.preventDefault()\n focusSearch()\n break\n case '?':\n event.preventDefault()\n setShortcutsOpen((open) => !open)\n break\n case 'Escape':\n setHighlightItemId(null)\n break\n default:\n break\n }\n }\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [editorOpen, focusSearch, openCreateEditor])\n\n const showInitialLoading = (isLoading && !hasLoadedOnce) || !preferencesHydrated\n\n let viewArea: React.ReactNode\n if (error) {\n viewArea = (\n <ErrorMessage\n label={t('customers.calendar.errors.loadFailed', 'Failed to load calendar events.')}\n action={\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={refetch}>\n {t('customers.calendar.errors.retry', 'Retry')}\n </Button>\n }\n />\n )\n } else if (showInitialLoading) {\n viewArea = <LoadingMessage label={t('customers.calendar.loading', 'Loading calendar\u2026')} />\n } else if (view === 'month') {\n viewArea = (\n <MonthGrid anchor={anchor} items={viewItems} onItemClick={openEditEditor} onDayOpen={handleDayOpen} />\n )\n } else if (view === 'agenda') {\n viewArea = (\n <AgendaList\n anchor={anchor}\n horizonDays={agendaHorizonDays}\n items={viewItems}\n typeLabels={typeLabels}\n onItemClick={openEditEditor}\n />\n )\n } else {\n viewArea = (\n <TimeGrid\n days={view === 'day' ? 1 : 7}\n anchor={anchor}\n items={viewItems}\n conflictIds={conflictIds}\n showWeekends={preferences.showWeekends}\n showConflicts={preferences.conflictWarnings}\n aiSummaries={preferences.aiSummaries}\n canManage={canManage}\n highlightItemId={highlightItemId}\n onItemClick={openEditEditor}\n onJoin={handleJoin}\n onNavigate={handleTimeGridNavigate}\n onCreate={canManage ? openCreateEditor : undefined}\n onCreateRange={canManage ? handleCreateRange : undefined}\n />\n )\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4\">\n <CalendarHeader view={view} anchor={anchor} onNewEvent={canManage ? openCreateEditor : undefined} />\n <CalendarToolbar\n view={view}\n anchor={anchor}\n range={range}\n preset={preset}\n search={searchText}\n filters={filters}\n typeOptions={typeOptions}\n ownerOptions={ownerOptions}\n onToday={handleToday}\n onPresetChange={handlePresetChange}\n onAnchorChange={handleAnchorChange}\n onSearchChange={setSearchText}\n onFiltersChange={setFilters}\n onOpenSettings={() => setSettingsOpen(true)}\n />\n <UpcomingCards\n cards={upcomingCards}\n canManage={canManage}\n onJoin={handleJoin}\n onSeeConflict={handleSeeConflict}\n onOpen={openEditEditor}\n onEdit={openEditEditor}\n onCancel={handleCancelItem}\n />\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n <CalendarTabs\n tab={tab}\n counts={tabCounts}\n view={view}\n onTabChange={setTab}\n onViewChange={handleViewChange}\n />\n {truncated ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {t('customers.calendar.notice.truncated', 'Showing first {count} items for this range.', {\n count: MAX_WINDOW_ITEMS,\n })}\n </p>\n ) : null}\n <div className=\"flex min-h-[560px] flex-1 flex-col [&>*]:flex-1\">{viewArea}</div>\n </div>\n <div className=\"hidden md:block\">\n <CalendarFooter timezoneLabel={timezoneLabel} onOpenShortcuts={() => setShortcutsOpen(true)} />\n </div>\n <ShortcutsDialog open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n <CalendarSettingsModal\n open={settingsOpen}\n preferences={preferences}\n seedActivityTypes={seedActivityTypes}\n onOpenChange={setSettingsOpen}\n onSave={(next) => {\n setPreferences(next)\n flash(t('customers.calendar.settings.saved', 'Calendar settings saved'), 'success')\n }}\n />\n {editorMounted ? (\n <CalendarEventEditor\n open={editor.open}\n mode={editor.mode}\n item={editor.item}\n defaultDate={anchor}\n defaultRange={createRange}\n typeLabels={typeLabels}\n typeColors={typeColors}\n surfacedTypes={preferences.activityTypes}\n eventCategories={preferences.eventCategories}\n conflictScope={preferences.conflictScope}\n currentUserId={currentUserId}\n onOpenChange={(open) => setEditor((current) => ({ ...current, open }))}\n onSaved={refetch}\n />\n ) : null}\n </div>\n )\n}\n"],
5
+ "mappings": ";AAqdU,cAuEJ,YAvEI;AAndV,YAAY,WAAW;AACvB,OAAO,aAAa;AACpB,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AACrB,SAAS,SAAS,gBAAgB,mCAAmC;AACrE,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,aAAa;AACtB,SAAS,0BAA0B;AACnC,SAAS,cAAc,sBAAsB;AAC7C,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,kBAAkB,wBAAwB;AAUnD,MAAM,sBAAsB;AAAA,EAC1B,MAAM,OAAO,uBAAuB,EAAE,KAAK,CAAC,QAAQ,IAAI,mBAAmB;AAAA,EAC3E,EAAE,KAAK,MAAM;AACf;AAEA,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AAC3B,MAAM,8BAA8B;AACpC,MAAM,uBAAuB;AAC7B,MAAM,gBAAsC,EAAE,OAAO,CAAC,GAAG,QAAQ,MAAM,aAAa,KAAK;AAIzF,MAAM,iBAAiB;AAEvB,SAAS,2BAAoC;AAC3C,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AACtD,QAAM,UAAU,MAAM;AACpB,UAAM,aAAa,IAAI,gBAAgB;AACvC,QAAI,YAAY;AAChB,YAAiC,2BAA2B;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,QAAQ,WAAW;AAAA,MACnB,MAAM,KAAK,UAAU,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC;AAAA,IACrD,CAAC,EACE,KAAK,CAAC,SAAS;AACd,UAAI,aAAa,CAAC,KAAK,GAAI;AAC3B,YAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ,OAAO,IAC9C,KAAK,OAAO,QAAQ,IAAI,CAAC,YAAY,OAAO,OAAO,CAAC,IACpD,CAAC;AACL,mBAAa,QAAQ,KAAK,CAAC,mBAAmB,aAAa,gBAAgB,cAAc,CAAC,CAAC;AAAA,IAC7F,CAAC,EACA,MAAM,MAAM;AACX,UAAI,CAAC,aAAa,CAAC,WAAW,OAAO,QAAS,cAAa,KAAK;AAAA,IAClE,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AACZ,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAEA,SAAS,qBAA6B;AACpC,QAAM,WAAW,KAAK,eAAe,EAAE,gBAAgB,EAAE;AACzD,QAAM,gBAAgB,EAAC,oBAAI,KAAK,GAAE,kBAAkB;AACpD,QAAM,OAAO,iBAAiB,IAAI,MAAM;AACxC,QAAM,WAAW,KAAK,IAAI,aAAa;AACvC,QAAM,QAAQ,KAAK,MAAM,WAAW,EAAE;AACtC,QAAM,UAAU,WAAW;AAC3B,QAAM,SAAS,UAAU,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,KAAK;AACpG,SAAO,GAAG,QAAQ,QAAQ,MAAM;AAClC;AAEA,SAAS,eAAe,UAAwC;AAC9D,QAAM,UAAU,UAAU,KAAK,KAAK;AACpC,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,gBAAgB,KAAK,OAAO,EAAG,QAAO;AAC1C,MAAI,UAAU,KAAK,OAAO,EAAG,QAAO,WAAW,OAAO;AACtD,SAAO;AACT;AAEA,SAAS,eAAe,MAAkC;AACxD,SAAO,KAAK,wBAAwB,EAAE,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,IAAI;AACrE;AAEO,SAAS,iBAAiB;AAC/B,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAuB,MAAM;AAC3D,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAe,MAAM,oBAAI,KAAK,CAAC;AACjE,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAS,2BAA2B;AAC5F,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAqC,UAAU;AAEjF,QAAM,UAAU,MAAM;AACpB,QAAI,OAAO,cAAc,oBAAqB;AAC9C,YAAQ,KAAK;AACb,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AACL,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAsB,KAAK;AACvD,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,EAAE;AACrD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,EAAE;AAC/D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA+B,aAAa;AAChF,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAsB,EAAE,MAAM,OAAO,MAAM,UAAU,MAAM,KAAK,CAAC;AACnG,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAA4C,IAAI;AAC5F,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAS,KAAK;AAC5D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAwB,IAAI;AAChF,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,EAAE,aAAa,gBAAgB,UAAU,qBAAqB,QAAQ,cAAc,IAAI,uBAAuB;AAErH,QAAM,QAAQ,MAAM;AAAA,IAClB,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB;AAAA,IACrD,CAAC,MAAM,QAAQ,iBAAiB;AAAA,EAClC;AACA,QAAM,EAAE,OAAO,WAAW,OAAO,WAAW,YAAY,YAAY,QAAQ,IAAI,iBAAiB,KAAK;AAEtG,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,UAAW,kBAAiB,IAAI;AAAA,EACvC,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,UAAU,MAAM;AACpB,UAAM,QAAQ,OAAO,WAAW,MAAM,mBAAmB,UAAU,GAAG,kBAAkB;AACxF,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,gBAAiB;AACtB,UAAM,QAAQ,OAAO,WAAW,MAAM,mBAAmB,IAAI,GAAG,kBAAkB;AAClF,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,eAAe,MAAM;AAAA,IACzB,MAAM,MAAM,OAAO,CAAC,SAAS,KAAK,MAAM,MAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE;AAAA,IAC3E,CAAC,OAAO,KAAK;AAAA,EACf;AAEA,QAAM,gBAAgB,MAAM,QAAQ,MAAM;AACxC,UAAM,QAAQ,gBAAgB,KAAK,EAAE,YAAY;AACjD,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,aAAa,OAAO,CAAC,SAAS;AACnC,UAAI,KAAK,MAAM,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACrD,UAAI,KAAK,YAAY,KAAK,SAAS,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACzE,YAAM,UAAW,KAAK,IAA2B;AACjD,UAAI,OAAO,YAAY,YAAY,QAAQ,YAAY,EAAE,SAAS,KAAK,EAAG,QAAO;AACjF,aAAO,KAAK,aAAa;AAAA,QAAK,CAAC,iBAC5B,YAAY,QAAQ,IAAI,YAAY,EAAE,SAAS,KAAK;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,eAAe,CAAC;AAElC,QAAM,YAAY,MAAM;AAAA,IACtB,MACE,cAAc,OAAO,CAAC,SAAS;AAC7B,UAAI,QAAQ,MAAM,SAAS,KAAK,CAAC,QAAQ,MAAM,SAAS,KAAK,eAAe,EAAG,QAAO;AACtF,UAAI,QAAQ,UAAU,KAAK,WAAW,QAAQ,OAAQ,QAAO;AAC7D,UAAI,QAAQ,eAAe,KAAK,gBAAgB,QAAQ,YAAa,QAAO;AAC5E,UAAI,CAAC,YAAY,qBAAqB,KAAK,aAAa,aAAa,KAAK,aAAa,QAAS,QAAO;AACvG,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,eAAe,SAAS,YAAY,iBAAiB;AAAA,EACxD;AAEA,QAAM,YAAY,MAAM,QAAQ,MAAM,gBAAgB,SAAS,GAAG,CAAC,SAAS,CAAC;AAE7E,QAAM,YAAY,MAAM,QAAQ,MAAM;AACpC,QAAI,QAAQ,WAAY,QAAO,UAAU,OAAO,CAAC,SAAS,KAAK,aAAa,SAAS;AACrF,QAAI,QAAQ,SAAU,QAAO,UAAU,OAAO,CAAC,SAAS,KAAK,aAAa,OAAO;AACjF,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,GAAG,CAAC;AAEnB,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,cAAc,WAAW,EAAE,OAAO,YAAY,eAAe,cAAc,CAAC;AAAA,IAClF,CAAC,WAAW,YAAY,eAAe,aAAa;AAAA,EACtD;AACA,QAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,IAAI,YAAY,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;AAElF,QAAM,gBAAgB,MAAM,QAAwB,MAAM;AACxD,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,QAAQ;AAC1B,WAAO,UACJ,OAAO,CAAC,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,EAC9C,KAAK,CAAC,OAAO,WAAW,MAAM,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ,CAAC,EACtE,MAAM,GAAG,oBAAoB,EAC7B,IAAI,CAAC,SAAS;AACb,YAAM,gBAAgB,YAAY,mBAAoB,YAAY,IAAI,KAAK,EAAE,GAAG,UAAU,IAAK;AAC/F,YAAM,OACJ,KAAK,WAAW,aACZ,cACA,gBAAgB,IACd,eACA,UAAU,KAAK,OAAO,GAAG,IACvB,UACA;AACV,aAAO,EAAE,MAAM,MAAM,cAAc;AAAA,IACrC,CAAC;AAAA,EACL,GAAG,CAAC,WAAW,aAAa,YAAY,gBAAgB,CAAC;AAEzD,QAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAM,SAAS,IAAI,IAAY,OAAO,KAAK,UAAU,CAAC;AACtD,eAAW,QAAQ,MAAO,QAAO,IAAI,KAAK,eAAe;AACzD,WAAO,CAAC,GAAG,MAAM,EACd,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC,EACjC,IAAI,CAAC,WAAW,EAAE,OAAO,OAAO,WAAW,KAAK,KAAK,MAAM,EAAE;AAAA,EAClE,GAAG,CAAC,OAAO,UAAU,CAAC;AAEtB,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,mBAAmB,oBAAI,IAAoB;AACjD,eAAW,QAAQ,OAAO;AACxB,iBAAW,eAAe,KAAK,cAAc;AAC3C,YAAI,YAAY,QAAQ,CAAC,iBAAiB,IAAI,YAAY,MAAM,GAAG;AACjE,2BAAiB,IAAI,YAAY,QAAQ,YAAY,IAAI;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,KAAK,eAAe,OAAO,IAAI,KAAK,WAAW,EAAG;AACvD,aAAO,IAAI,KAAK,aAAa,iBAAiB,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW;AAAA,IACzF;AACA,WAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,EACxB,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,EAC1C,KAAK,CAAC,OAAO,WAAW,MAAM,MAAM,cAAc,OAAO,KAAK,CAAC;AAAA,EACpE,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,gBAAgB,MAAM,QAAQ,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAElE,QAAM,YAAY,yBAAyB;AAE3C,QAAM,mBAAmB,MAAM,YAAY,MAAM;AAC/C,QAAI,CAAC,UAAW;AAChB,mBAAe,IAAI;AACnB,qBAAiB,IAAI;AACrB,cAAU,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,CAAC;AAAA,EACtD,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,SAAuB;AACtB,UAAI,CAAC,UAAW;AAChB,qBAAe,IAAI;AACnB,uBAAiB,IAAI;AACrB,gBAAU,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,eAAe,IAAI,EAAE,CAAC;AAAA,IACpE;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,oBAAoB,MAAM;AAAA,IAC9B,CAAC,OAAa,QAAc;AAC1B,UAAI,CAAC,UAAW;AAChB,qBAAe,EAAE,OAAO,IAAI,CAAC;AAC7B,uBAAiB,IAAI;AACrB,gBAAU,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,CAAC;AAAA,IACtD;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,oBAAoB,MAAM,QAAQ,MAAM;AAC5C,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,OAAO,KAAK,UAAU,GAAG;AAC3C,YAAM,QAAQ,WAAW,KAAK,KAAK;AACnC,UAAI,KAAK,IAAI,KAAK,EAAG;AACrB,WAAK,IAAI,KAAK;AACd,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,cAAU,oBAAI,KAAK,CAAC;AACpB,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,CAAC,SAA8B;AAC1E,cAAU,IAAI;AACd,cAAU,oBAAI,KAAK,CAAC;AACpB,QAAI,SAAS,YAAY;AACvB,cAAQ,MAAM;AAAA,IAChB,WAAW,SAAS,aAAa;AAC/B,cAAQ,OAAO;AAAA,IACjB,OAAO;AACL,cAAQ,QAAQ;AAChB,2BAAqB,SAAS,WAAW,KAAK,2BAA2B;AAAA,IAC3E;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,CAAC,SAAe;AAC3D,cAAU,IAAI;AACd,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAmB,MAAM,YAAY,CAAC,SAAuB;AACjE,YAAQ,IAAI;AACZ,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAyB,MAAM,YAAY,CAAC,cAAsB;AACtE,cAAU,CAAC,YAAY,QAAQ,SAAS,SAAS,CAAC;AAClD,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,MAAM,YAAY,CAAC,SAAe;AACtD,YAAQ,KAAK;AACb,cAAU,IAAI;AACd,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,MAAM,YAAY,CAAC,SAAuB;AAClE,YAAQ,MAAM;AACd,cAAU,KAAK,KAAK;AACpB,cAAU,IAAI;AACd,uBAAmB,KAAK,EAAE;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM,YAAY,CAAC,SAAuB;AAC3D,UAAM,MAAM,eAAe,KAAK,QAAQ;AACxC,QAAI,IAAK,QAAO,KAAK,KAAK,UAAU,UAAU;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,aAAa,kBAAkB,IAAI,mBAKxC;AAAA,IACD,WAAW;AAAA,IACX,gBAAgB,EAAE,8BAA8B,4BAA4B;AAAA,EAC9E,CAAC;AAED,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,SAAuB;AAC5B,YAAM,gBAAgB,KAAK,IAAI;AAC/B,UAAI;AACF,cAAM,YAAY;AAAA,UAChB,WAAW,MACT;AAAA,YAA4B,0BAA0B,KAAK,SAAS;AAAA,YAAG,MACrE,eAAe,+BAA+B;AAAA,cAC5C,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU,EAAE,IAAI,eAAe,QAAQ,WAAW,CAAC;AAAA,YAChE,CAAC;AAAA,UACH;AAAA,UACF,iBAAiB;AAAA,YACf,WAAW;AAAA,YACX;AAAA,YACA,iBAAiB,KAAK;AAAA,UACxB;AAAA,UACA,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,YAAY;AAAA,YACZ;AAAA,UACF;AAAA,QACF,CAAC;AACD,cAAM,EAAE,0CAA0C,iBAAiB,GAAG,SAAS;AAC/E,gBAAQ;AAAA,MACV,SAAS,KAAK;AAGZ,YAAI,8BAA8B,GAAG,EAAG;AACxC,cAAM,EAAE,wCAAwC,wBAAwB,GAAG,OAAO;AAAA,MACpF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,mBAAmB,aAAa,CAAC;AAAA,EAC7C;AAEA,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,UAAM,OAAO,SAAS,cAAc,wBAAwB;AAC5D,QAAI,gBAAgB,iBAAkB,MAAK,MAAM;AAAA,aACxC,gBAAgB,YAAa,MAAK,cAAc,OAAO,GAAG,MAAM;AAAA,EAC3E,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,OAAO;AAC1B,QAAM,UAAU,MAAM;AACpB,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,UAAI,MAAM,iBAAkB;AAC5B,UAAI,MAAM,WAAW,MAAM,WAAW,MAAM,OAAQ;AACpD,YAAM,SAAS,MAAM;AACrB,UAAI,kBAAkB,aAAa;AACjC,cAAM,MAAM,OAAO;AACnB,YAAI,QAAQ,WAAW,QAAQ,cAAc,QAAQ,YAAY,OAAO,kBAAmB;AAAA,MAC7F;AACA,UAAI,WAAY;AAChB,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,oBAAU,oBAAI,KAAK,CAAC;AACpB,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,KAAK;AACb,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,MAAM;AACd,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,OAAO;AACf,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,kBAAQ,QAAQ;AAChB,oBAAU,IAAI;AACd;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,gBAAM,eAAe;AACrB,2BAAiB;AACjB;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,sBAAY;AACZ;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,2BAAiB,CAAC,SAAS,CAAC,IAAI;AAChC;AAAA,QACF,KAAK;AACH,6BAAmB,IAAI;AACvB;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAChD,WAAO,MAAM,OAAO,oBAAoB,WAAW,aAAa;AAAA,EAClE,GAAG,CAAC,YAAY,aAAa,gBAAgB,CAAC;AAE9C,QAAM,qBAAsB,aAAa,CAAC,iBAAkB,CAAC;AAE7D,MAAI;AACJ,MAAI,OAAO;AACT,eACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,wCAAwC,iCAAiC;AAAA,QAClF,QACE,oBAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,MAAK,MAAK,SAAS,SACxD,YAAE,mCAAmC,OAAO,GAC/C;AAAA;AAAA,IAEJ;AAAA,EAEJ,WAAW,oBAAoB;AAC7B,eAAW,oBAAC,kBAAe,OAAO,EAAE,8BAA8B,wBAAmB,GAAG;AAAA,EAC1F,WAAW,SAAS,SAAS;AAC3B,eACE,oBAAC,aAAU,QAAgB,OAAO,WAAW,aAAa,gBAAgB,WAAW,eAAe;AAAA,EAExG,WAAW,SAAS,UAAU;AAC5B,eACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,aAAa;AAAA,QACb,OAAO;AAAA,QACP;AAAA,QACA,aAAa;AAAA;AAAA,IACf;AAAA,EAEJ,OAAO;AACL,eACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,SAAS,QAAQ,IAAI;AAAA,QAC3B;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,cAAc,YAAY;AAAA,QAC1B,eAAe,YAAY;AAAA,QAC3B,aAAa,YAAY;AAAA,QACzB;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,UAAU,YAAY,mBAAmB;AAAA,QACzC,eAAe,YAAY,oBAAoB;AAAA;AAAA,IACjD;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,sCACb;AAAA,wBAAC,kBAAe,MAAY,QAAgB,YAAY,YAAY,mBAAmB,QAAW;AAAA,IAClG;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,gBAAgB,MAAM,gBAAgB,IAAI;AAAA;AAAA,IAC5C;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU;AAAA;AAAA,IACZ;AAAA,IACA,qBAAC,SAAI,WAAU,sCACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,UACA,aAAa;AAAA,UACb,cAAc;AAAA;AAAA,MAChB;AAAA,MACC,YACC,oBAAC,OAAE,WAAU,iCAAgC,MAAK,UAC/C,YAAE,uCAAuC,+CAA+C;AAAA,QACvF,OAAO;AAAA,MACT,CAAC,GACH,IACE;AAAA,MACJ,oBAAC,SAAI,WAAU,mDAAmD,oBAAS;AAAA,OAC7E;AAAA,IACA,oBAAC,SAAI,WAAU,mBACb,8BAAC,kBAAe,eAA8B,iBAAiB,MAAM,iBAAiB,IAAI,GAAG,GAC/F;AAAA,IACA,oBAAC,mBAAgB,MAAM,eAAe,cAAc,kBAAkB;AAAA,IACtE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,QAAQ,CAAC,SAAS;AAChB,yBAAe,IAAI;AACnB,gBAAM,EAAE,qCAAqC,yBAAyB,GAAG,SAAS;AAAA,QACpF;AAAA;AAAA,IACF;AAAA,IACC,gBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,aAAa;AAAA,QACb,cAAc;AAAA,QACd;AAAA,QACA;AAAA,QACA,eAAe,YAAY;AAAA,QAC3B,iBAAiB,YAAY;AAAA,QAC7B,eAAe,YAAY;AAAA,QAC3B;AAAA,QACA,cAAc,CAAC,SAAS,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,KAAK,EAAE;AAAA,QACrE,SAAS;AAAA;AAAA,IACX,IACE;AAAA,KACN;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -1,10 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { resolveRequestContext } from "@open-mercato/shared/lib/api/context";
3
3
  import { isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
4
- import {
5
- runCrudMutationGuardAfterSuccess,
6
- validateCrudMutationGuard
7
- } from "@open-mercato/shared/lib/crud/mutation-guard";
4
+ import { runRouteMutationGuards } from "@open-mercato/shared/lib/crud/route-mutation-guard";
8
5
  import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
9
6
  import { resolveNotificationService } from "./notificationService.js";
10
7
  const NOTIFICATION_RESOURCE_KIND = "notifications.notification";
@@ -41,30 +38,26 @@ async function resolveNotificationContext(req) {
41
38
  };
42
39
  }
43
40
  async function runGuardedNotificationWrite(container, scope, req, options, write) {
44
- const guardScope = {
45
- tenantId: scope.tenantId,
46
- organizationId: scope.organizationId,
47
- userId: scope.userId ?? "",
48
- resourceKind: options.resourceKind,
49
- resourceId: options.resourceId ?? "",
50
- operation: options.operation,
51
- requestMethod: req.method,
52
- requestHeaders: req.headers
53
- };
54
- const guardResult = await validateCrudMutationGuard(container, {
55
- ...guardScope,
56
- mutationPayload: options.payload ?? null
41
+ const guarded = await runRouteMutationGuards({
42
+ container,
43
+ req,
44
+ auth: {
45
+ userId: scope.userId ?? "",
46
+ tenantId: scope.tenantId,
47
+ organizationId: scope.organizationId
48
+ },
49
+ input: {
50
+ resourceKind: options.resourceKind,
51
+ resourceId: options.resourceId ?? null,
52
+ operation: options.operation,
53
+ mutationPayload: options.payload ?? null
54
+ }
57
55
  });
58
- if (guardResult && !guardResult.ok) {
59
- return { ok: false, response: Response.json(guardResult.body, { status: guardResult.status }) };
56
+ if (!guarded.ok) {
57
+ return { ok: false, response: guarded.response };
60
58
  }
61
59
  const result = await write();
62
- if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
63
- await runCrudMutationGuardAfterSuccess(container, {
64
- ...guardScope,
65
- metadata: guardResult.metadata ?? null
66
- });
67
- }
60
+ await guarded.runAfterSuccess();
68
61
  return { ok: true, result };
69
62
  }
70
63
  function createBulkNotificationRoute(schema, serviceMethod) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/notifications/lib/routeHelpers.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport type { AwilixContainer } from 'awilix'\nimport { resolveRequestContext } from '@open-mercato/shared/lib/api/context'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { resolveNotificationService, type NotificationService } from './notificationService'\n\n/**\n * Mutation-guard resource kind for notification rows.\n */\nexport const NOTIFICATION_RESOURCE_KIND = 'notifications.notification'\n\n/**\n * Mutation-guard resource kind for notification delivery settings.\n */\nexport const NOTIFICATION_SETTINGS_RESOURCE_KIND = 'notifications.settings'\n\n/**\n * Notification scope context for service calls\n */\nexport interface NotificationScope {\n tenantId: string\n organizationId: string | null\n userId: string | null\n}\n\n/**\n * Resolved notification context from a request\n */\nexport interface NotificationRequestContext {\n service: NotificationService\n scope: NotificationScope\n ctx: Awaited<ReturnType<typeof resolveRequestContext>>['ctx']\n}\n\nfunction formatZodIssues(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length ? `${issue.path.join('.')}: ` : ''\n return `${path}${issue.message}`\n })\n .join('; ')\n}\n\nexport async function notificationValidationErrorResponse(error: z.ZodError): Promise<Response> {\n const { t } = await resolveTranslations()\n const prefix = t('api.errors.invalidPayload', 'Invalid request body')\n const details = formatZodIssues(error)\n return Response.json(\n { error: details ? `${prefix}: ${details}` : prefix },\n { status: 400 },\n )\n}\n\nexport function notificationCrudErrorResponse(error: unknown): Response | null {\n if (!isCrudHttpError(error)) return null\n return Response.json(error.body ?? { error: 'Notification request failed' }, { status: error.status })\n}\n\n/**\n * Resolve notification service and scope from a request.\n * Centralizes the common pattern used across all notification API routes.\n */\nexport async function resolveNotificationContext(req: Request): Promise<NotificationRequestContext> {\n const { ctx } = await resolveRequestContext(req)\n return {\n service: resolveNotificationService(ctx.container),\n scope: {\n tenantId: ctx.auth?.tenantId ?? '',\n organizationId: ctx.selectedOrganizationId ?? null,\n userId: ctx.auth?.sub ?? null,\n },\n ctx,\n }\n}\n\n/**\n * Mutation-guard options for a notification write.\n */\nexport interface NotificationMutationGuardOptions {\n resourceKind: string\n resourceId?: string | null\n operation: 'create' | 'update' | 'delete' | 'custom'\n payload?: Record<string, unknown> | null\n}\n\nexport type GuardedNotificationWriteResult<T> =\n | { ok: true; result: T }\n | { ok: false; response: Response }\n\n/**\n * Run a notification write through the mutation guard lifecycle.\n * Validates before the mutation, performs the write, then runs after-success\n * hooks only when the write succeeded and the guard requested them. Returns the\n * guard's own block response when validation fails so authorization behavior and\n * conflict shapes are preserved.\n */\nexport async function runGuardedNotificationWrite<T>(\n container: AwilixContainer,\n scope: NotificationScope,\n req: Request,\n options: NotificationMutationGuardOptions,\n write: () => Promise<T>,\n): Promise<GuardedNotificationWriteResult<T>> {\n const guardScope = {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId ?? '',\n resourceKind: options.resourceKind,\n resourceId: options.resourceId ?? '',\n operation: options.operation,\n requestMethod: req.method,\n requestHeaders: req.headers,\n }\n\n const guardResult = await validateCrudMutationGuard(container, {\n ...guardScope,\n mutationPayload: options.payload ?? null,\n })\n if (guardResult && !guardResult.ok) {\n return { ok: false, response: Response.json(guardResult.body, { status: guardResult.status }) }\n }\n\n const result = await write()\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n ...guardScope,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return { ok: true, result }\n}\n\n/**\n * Create a POST handler for bulk notification creation routes.\n * Used by batch, role, and feature notification endpoints.\n */\nexport function createBulkNotificationRoute<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n serviceMethod: 'createBatch' | 'createForRole' | 'createForFeature'\n) {\n return async function POST(req: Request) {\n const { service, scope, ctx } = await resolveNotificationContext(req)\n\n const body = await req.json().catch(() => ({}))\n const parsed = schema.safeParse(body)\n if (!parsed.success) {\n return notificationValidationErrorResponse(parsed.error)\n }\n\n try {\n const guarded = await runGuardedNotificationWrite(\n ctx.container,\n scope,\n req,\n {\n resourceKind: NOTIFICATION_RESOURCE_KIND,\n operation: 'create',\n payload: parsed.data as Record<string, unknown>,\n },\n () => service[serviceMethod](parsed.data as never, scope),\n )\n if (!guarded.ok) return guarded.response\n const notifications = guarded.result\n\n return Response.json({\n ok: true,\n count: notifications.length,\n ids: notifications.map((n) => n.id),\n }, { status: 201 })\n } catch (error) {\n const errorResponse = notificationCrudErrorResponse(error)\n if (errorResponse) return errorResponse\n throw error\n }\n }\n}\n\n/**\n * Create OpenAPI spec for bulk notification creation routes.\n */\nexport function createBulkNotificationOpenApi<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n summary: string,\n description?: string\n) {\n return {\n POST: {\n summary,\n description,\n tags: ['Notifications'],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema,\n },\n },\n },\n responses: {\n 201: {\n description: 'Notifications created',\n content: {\n 'application/json': {\n schema: z.object({\n ok: z.boolean(),\n count: z.number(),\n ids: z.array(z.string().uuid()),\n }),\n },\n },\n },\n },\n },\n }\n}\n\n/**\n * Create a PUT handler for single notification action routes.\n * Used by read and dismiss endpoints.\n */\nexport function createSingleNotificationActionRoute(\n serviceMethod: 'markAsRead' | 'dismiss'\n) {\n return async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {\n const { id } = await params\n const { service, scope, ctx } = await resolveNotificationContext(req)\n\n try {\n const guarded = await runGuardedNotificationWrite(\n ctx.container,\n scope,\n req,\n {\n resourceKind: NOTIFICATION_RESOURCE_KIND,\n resourceId: id,\n operation: 'update',\n },\n () => service[serviceMethod](id, scope),\n )\n if (!guarded.ok) return guarded.response\n } catch (error) {\n const errorResponse = notificationCrudErrorResponse(error)\n if (errorResponse) return errorResponse\n throw error\n }\n\n return Response.json({ ok: true })\n }\n}\n\n/**\n * Create OpenAPI spec for single notification action routes.\n */\nexport function createSingleNotificationActionOpenApi(\n summary: string,\n description: string\n) {\n return {\n PUT: {\n summary,\n tags: ['Notifications'],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string', format: 'uuid' },\n },\n ],\n responses: {\n 200: {\n description,\n content: {\n 'application/json': {\n schema: z.object({ ok: z.boolean() }),\n },\n },\n },\n },\n },\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport type { AwilixContainer } from 'awilix'\nimport { resolveRequestContext } from '@open-mercato/shared/lib/api/context'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { runRouteMutationGuards } from '@open-mercato/shared/lib/crud/route-mutation-guard'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { resolveNotificationService, type NotificationService } from './notificationService'\n\n/**\n * Mutation-guard resource kind for notification rows.\n */\nexport const NOTIFICATION_RESOURCE_KIND = 'notifications.notification'\n\n/**\n * Mutation-guard resource kind for notification delivery settings.\n */\nexport const NOTIFICATION_SETTINGS_RESOURCE_KIND = 'notifications.settings'\n\n/**\n * Notification scope context for service calls\n */\nexport interface NotificationScope {\n tenantId: string\n organizationId: string | null\n userId: string | null\n}\n\n/**\n * Resolved notification context from a request\n */\nexport interface NotificationRequestContext {\n service: NotificationService\n scope: NotificationScope\n ctx: Awaited<ReturnType<typeof resolveRequestContext>>['ctx']\n}\n\nfunction formatZodIssues(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length ? `${issue.path.join('.')}: ` : ''\n return `${path}${issue.message}`\n })\n .join('; ')\n}\n\nexport async function notificationValidationErrorResponse(error: z.ZodError): Promise<Response> {\n const { t } = await resolveTranslations()\n const prefix = t('api.errors.invalidPayload', 'Invalid request body')\n const details = formatZodIssues(error)\n return Response.json(\n { error: details ? `${prefix}: ${details}` : prefix },\n { status: 400 },\n )\n}\n\nexport function notificationCrudErrorResponse(error: unknown): Response | null {\n if (!isCrudHttpError(error)) return null\n return Response.json(error.body ?? { error: 'Notification request failed' }, { status: error.status })\n}\n\n/**\n * Resolve notification service and scope from a request.\n * Centralizes the common pattern used across all notification API routes.\n */\nexport async function resolveNotificationContext(req: Request): Promise<NotificationRequestContext> {\n const { ctx } = await resolveRequestContext(req)\n return {\n service: resolveNotificationService(ctx.container),\n scope: {\n tenantId: ctx.auth?.tenantId ?? '',\n organizationId: ctx.selectedOrganizationId ?? null,\n userId: ctx.auth?.sub ?? null,\n },\n ctx,\n }\n}\n\n/**\n * Mutation-guard options for a notification write.\n */\nexport interface NotificationMutationGuardOptions {\n resourceKind: string\n resourceId?: string | null\n operation: 'create' | 'update' | 'delete' | 'custom'\n payload?: Record<string, unknown> | null\n}\n\nexport type GuardedNotificationWriteResult<T> =\n | { ok: true; result: T }\n | { ok: false; response: Response }\n\n/**\n * Run a notification write through the mutation guard lifecycle.\n * Validates before the mutation, performs the write, then runs after-success\n * hooks only when the write succeeded and the guard requested them. Returns the\n * guard's own block response when validation fails so authorization behavior and\n * conflict shapes are preserved.\n */\nexport async function runGuardedNotificationWrite<T>(\n container: AwilixContainer,\n scope: NotificationScope,\n req: Request,\n options: NotificationMutationGuardOptions,\n write: () => Promise<T>,\n): Promise<GuardedNotificationWriteResult<T>> {\n const guarded = await runRouteMutationGuards({\n container,\n req,\n auth: {\n userId: scope.userId ?? '',\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n },\n input: {\n resourceKind: options.resourceKind,\n resourceId: options.resourceId ?? null,\n operation: options.operation,\n mutationPayload: options.payload ?? null,\n },\n })\n if (!guarded.ok) {\n return { ok: false, response: guarded.response }\n }\n\n const result = await write()\n\n await guarded.runAfterSuccess()\n\n return { ok: true, result }\n}\n\n/**\n * Create a POST handler for bulk notification creation routes.\n * Used by batch, role, and feature notification endpoints.\n */\nexport function createBulkNotificationRoute<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n serviceMethod: 'createBatch' | 'createForRole' | 'createForFeature'\n) {\n return async function POST(req: Request) {\n const { service, scope, ctx } = await resolveNotificationContext(req)\n\n const body = await req.json().catch(() => ({}))\n const parsed = schema.safeParse(body)\n if (!parsed.success) {\n return notificationValidationErrorResponse(parsed.error)\n }\n\n try {\n const guarded = await runGuardedNotificationWrite(\n ctx.container,\n scope,\n req,\n {\n resourceKind: NOTIFICATION_RESOURCE_KIND,\n operation: 'create',\n payload: parsed.data as Record<string, unknown>,\n },\n () => service[serviceMethod](parsed.data as never, scope),\n )\n if (!guarded.ok) return guarded.response\n const notifications = guarded.result\n\n return Response.json({\n ok: true,\n count: notifications.length,\n ids: notifications.map((n) => n.id),\n }, { status: 201 })\n } catch (error) {\n const errorResponse = notificationCrudErrorResponse(error)\n if (errorResponse) return errorResponse\n throw error\n }\n }\n}\n\n/**\n * Create OpenAPI spec for bulk notification creation routes.\n */\nexport function createBulkNotificationOpenApi<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n summary: string,\n description?: string\n) {\n return {\n POST: {\n summary,\n description,\n tags: ['Notifications'],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema,\n },\n },\n },\n responses: {\n 201: {\n description: 'Notifications created',\n content: {\n 'application/json': {\n schema: z.object({\n ok: z.boolean(),\n count: z.number(),\n ids: z.array(z.string().uuid()),\n }),\n },\n },\n },\n },\n },\n }\n}\n\n/**\n * Create a PUT handler for single notification action routes.\n * Used by read and dismiss endpoints.\n */\nexport function createSingleNotificationActionRoute(\n serviceMethod: 'markAsRead' | 'dismiss'\n) {\n return async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {\n const { id } = await params\n const { service, scope, ctx } = await resolveNotificationContext(req)\n\n try {\n const guarded = await runGuardedNotificationWrite(\n ctx.container,\n scope,\n req,\n {\n resourceKind: NOTIFICATION_RESOURCE_KIND,\n resourceId: id,\n operation: 'update',\n },\n () => service[serviceMethod](id, scope),\n )\n if (!guarded.ok) return guarded.response\n } catch (error) {\n const errorResponse = notificationCrudErrorResponse(error)\n if (errorResponse) return errorResponse\n throw error\n }\n\n return Response.json({ ok: true })\n }\n}\n\n/**\n * Create OpenAPI spec for single notification action routes.\n */\nexport function createSingleNotificationActionOpenApi(\n summary: string,\n description: string\n) {\n return {\n PUT: {\n summary,\n tags: ['Notifications'],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string', format: 'uuid' },\n },\n ],\n responses: {\n 200: {\n description,\n content: {\n 'application/json': {\n schema: z.object({ ok: z.boolean() }),\n },\n },\n },\n },\n },\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -243,7 +243,7 @@ function PaymentTransactionsPage() {
243
243
  }
244
244
  }, [loadDetail, loadRows, runMutation, selectedId, t]);
245
245
  const providerOptions = React.useMemo(() => {
246
- const values = Array.from(new Set(rows.map((row) => row.providerKey).filter(Boolean))).sort();
246
+ const values = Array.from(new Set(rows.map((row) => row.providerKey).filter(Boolean))).sort((a, b) => a.localeCompare(b));
247
247
  return values.map((value) => ({
248
248
  label: formatTypeLabel(value),
249
249
  value
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/payment_gateways/backend/payment-gateways/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Page, PageHeader, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { LogList, type LogListEntry } from '@open-mercato/ui/backend/LogList'\nimport { CreditCard, HandCoins, RefreshCw, Webhook } from 'lucide-react'\n\ntype TransactionRow = {\n id: string\n paymentId: string\n providerKey: string\n providerSessionId?: string | null\n gatewayPaymentId?: string | null\n gatewayRefundId?: string | null\n unifiedStatus: string\n gatewayStatus?: string | null\n amount: string\n currencyCode: string\n redirectUrl?: string | null\n lastWebhookAt?: string | null\n lastPolledAt?: string | null\n createdAt: string | null\n updatedAt: string | null\n}\n\ntype TransactionLogEntry = {\n id: string\n integrationId: string\n runId?: string | null\n scopeEntityType?: string | null\n scopeEntityId?: string | null\n level: 'info' | 'warn' | 'error'\n message: string\n code?: string | null\n payload?: Record<string, unknown> | null\n createdAt: string | null\n}\n\ntype TransactionDetail = {\n transaction: {\n id: string\n paymentId: string\n providerKey: string\n providerSessionId?: string | null\n gatewayPaymentId?: string | null\n gatewayRefundId?: string | null\n unifiedStatus: string\n gatewayStatus?: string | null\n redirectUrl?: string | null\n amount: string\n currencyCode: string\n gatewayMetadata?: Record<string, unknown> | null\n webhookLog?: Array<{\n eventType: string\n receivedAt: string\n idempotencyKey: string\n unifiedStatus: string\n processed: boolean\n }> | null\n lastWebhookAt?: string | null\n lastPolledAt?: string | null\n expiresAt?: string | null\n createdAt: string | null\n updatedAt: string | null\n }\n logs: TransactionLogEntry[]\n}\n\ntype TransactionsResponse = {\n items: TransactionRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n}\n\nconst STATUS_STYLES: Record<string, string> = {\n pending: 'bg-slate-100 text-slate-800',\n authorized: 'bg-blue-100 text-blue-800',\n captured: 'bg-green-100 text-green-800',\n partially_captured: 'bg-emerald-100 text-emerald-800',\n refunded: 'bg-amber-100 text-amber-800',\n partially_refunded: 'bg-orange-100 text-orange-800',\n cancelled: 'bg-zinc-200 text-zinc-900',\n failed: 'bg-red-100 text-red-800',\n expired: 'bg-neutral-200 text-neutral-900',\n unknown: 'bg-purple-100 text-purple-800',\n}\n\nfunction formatDateTime(value: string | null | undefined): string {\n if (!value) return '\u2014'\n const parsed = new Date(value)\n if (Number.isNaN(parsed.getTime())) return value\n return parsed.toLocaleString()\n}\n\nfunction formatAmount(value: string, currencyCode: string): string {\n const amount = Number(value)\n if (Number.isNaN(amount)) return `${value} ${currencyCode}`\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency: currencyCode,\n }).format(amount)\n } catch {\n return `${amount.toFixed(2)} ${currencyCode}`\n }\n}\n\nfunction formatTypeLabel(value: string): string {\n return value\n .split('_')\n .filter(Boolean)\n .map((part) => part[0]?.toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nfunction formatLogDetailLabel(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((part) => part[0]?.toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nfunction isPrimitiveLogValue(value: unknown): value is string | number | boolean | null {\n return value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean'\n}\n\nfunction splitLogPayload(payload: Record<string, unknown> | null | undefined) {\n if (!payload) {\n return {\n inlineEntries: [] as Array<[string, string | number | boolean | null]>,\n nestedEntries: [] as Array<[string, unknown]>,\n }\n }\n\n const inlineEntries: Array<[string, string | number | boolean | null]> = []\n const nestedEntries: Array<[string, unknown]> = []\n Object.entries(payload).forEach(([key, value]) => {\n if (isPrimitiveLogValue(value)) {\n inlineEntries.push([key, value])\n return\n }\n nestedEntries.push([key, value])\n })\n return { inlineEntries, nestedEntries }\n}\n\nfunction DetailStat({ label, value }: { label: string; value: React.ReactNode }) {\n return (\n <div className=\"rounded-lg border bg-muted/30 px-4 py-3\">\n <div className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</div>\n <div className=\"mt-1 text-sm font-medium\">{value}</div>\n </div>\n )\n}\n\nexport default function PaymentTransactionsPage() {\n const t = useT()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<TransactionRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n const [detail, setDetail] = React.useState<TransactionDetail | null>(null)\n const [isLoadingDetail, setIsLoadingDetail] = React.useState(false)\n const [detailError, setDetailError] = React.useState<string | null>(null)\n const [isRefreshingStatus, setIsRefreshingStatus] = React.useState(false)\n const [isCapturing, setIsCapturing] = React.useState(false)\n const { runMutation } = useGuardedMutation<{\n entityType: string\n entityId?: string\n }>({\n contextId: 'payment_gateways:transactions-detail',\n })\n const noneLabel = t('common.none', 'None')\n const requestedTransactionId = React.useMemo(() => {\n const raw = searchParams.get('transactionId')\n return raw && raw.trim().length > 0 ? raw.trim() : null\n }, [searchParams])\n\n const formatLogPrimitiveValue = React.useCallback((value: string | number | boolean | null): string => {\n if (value === null) return noneLabel\n if (typeof value === 'boolean') return value ? t('common.yes', 'Yes') : t('common.no', 'No')\n return String(value)\n }, [noneLabel, t])\n\n const loadRows = React.useCallback(async () => {\n setIsLoading(true)\n const params = new URLSearchParams({\n page: String(page),\n pageSize: '20',\n })\n if (search.trim()) params.set('search', search.trim())\n if (typeof filterValues.providerKey === 'string' && filterValues.providerKey) {\n params.set('providerKey', filterValues.providerKey)\n }\n if (typeof filterValues.status === 'string' && filterValues.status) {\n params.set('status', filterValues.status)\n }\n const fallback: TransactionsResponse = { items: [], total: 0, page, pageSize: 20, totalPages: 1 }\n const call = await apiCall<TransactionsResponse>(`/api/payment_gateways/transactions?${params.toString()}`, undefined, { fallback })\n if (call.ok && call.result) {\n setRows(Array.isArray(call.result.items) ? call.result.items : [])\n setTotal(call.result.total ?? 0)\n setTotalPages(call.result.totalPages ?? 1)\n } else {\n flash(t('payment_gateways.transactions.error.load', 'Failed to load payment transactions'), 'error')\n setRows([])\n setTotal(0)\n setTotalPages(1)\n }\n setIsLoading(false)\n }, [filterValues.providerKey, filterValues.status, page, search, t])\n\n const loadDetail = React.useCallback(async (transactionId: string) => {\n setIsLoadingDetail(true)\n setDetailError(null)\n const call = await apiCall<TransactionDetail>(`/api/payment_gateways/transactions/${encodeURIComponent(transactionId)}`, undefined, { fallback: null })\n if (call.ok && call.result) {\n setDetail(call.result)\n } else {\n setDetail(null)\n setDetailError(t('payment_gateways.transactions.error.loadDetail', 'Failed to load transaction details'))\n }\n setIsLoadingDetail(false)\n }, [t])\n\n React.useEffect(() => {\n void loadRows()\n }, [loadRows, scopeVersion])\n\n React.useEffect(() => {\n if (!selectedId) {\n setDetail(null)\n setDetailError(null)\n return\n }\n void loadDetail(selectedId)\n }, [loadDetail, selectedId])\n\n React.useEffect(() => {\n setSelectedId((current) => (current && rows.some((row) => row.id === current) ? current : null))\n }, [rows])\n\n React.useEffect(() => {\n if (!requestedTransactionId) return\n if (!rows.some((row) => row.id === requestedTransactionId)) return\n setSelectedId(requestedTransactionId)\n }, [requestedTransactionId, rows])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (typeof value === 'string' && value.trim()) next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefreshStatus = React.useCallback(async () => {\n if (!selectedId) return\n setIsRefreshingStatus(true)\n try {\n await runMutation({\n operation: async () => {\n await apiCallOrThrow('/api/payment_gateways/status', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ transactionId: selectedId }),\n })\n },\n context: {\n entityType: 'payment_gateways:gateway_transaction',\n entityId: selectedId,\n },\n mutationPayload: { transactionId: selectedId },\n })\n await Promise.all([\n loadRows(),\n loadDetail(selectedId),\n ])\n flash(t('payment_gateways.transactions.success.refreshStatus', 'Transaction status refreshed'), 'success')\n } catch (error) {\n const message = error instanceof Error && error.message\n ? error.message\n : t('payment_gateways.transactions.error.refreshStatus', 'Failed to refresh transaction status')\n flash(message, 'error')\n } finally {\n setIsRefreshingStatus(false)\n }\n }, [loadDetail, loadRows, runMutation, selectedId, t])\n\n const handleCapturePayment = React.useCallback(async () => {\n if (!selectedId) return\n setIsCapturing(true)\n try {\n await runMutation({\n operation: async () => {\n await apiCallOrThrow('/api/payment_gateways/capture', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ transactionId: selectedId }),\n })\n },\n context: {\n entityType: 'payment_gateways:gateway_transaction',\n entityId: selectedId,\n },\n mutationPayload: { transactionId: selectedId },\n })\n await Promise.all([\n loadRows(),\n loadDetail(selectedId),\n ])\n flash(t('payment_gateways.transactions.success.capture', 'Payment captured'), 'success')\n } catch (error) {\n const message = error instanceof Error && error.message\n ? error.message\n : t('payment_gateways.transactions.error.capture', 'Failed to capture payment')\n flash(message, 'error')\n } finally {\n setIsCapturing(false)\n }\n }, [loadDetail, loadRows, runMutation, selectedId, t])\n\n const providerOptions = React.useMemo(() => {\n const values = Array.from(new Set(rows.map((row) => row.providerKey).filter(Boolean))).sort()\n return values.map((value) => ({\n label: formatTypeLabel(value),\n value,\n }))\n }, [rows])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'providerKey',\n type: 'select',\n label: t('payment_gateways.transactions.filters.provider', 'Provider'),\n options: [\n { label: t('payment_gateways.transactions.filters.allProviders', 'All providers'), value: '' },\n ...providerOptions,\n ],\n },\n {\n id: 'status',\n type: 'select',\n label: t('payment_gateways.transactions.filters.status', 'Status'),\n options: [\n { label: t('payment_gateways.transactions.filters.allStatuses', 'All statuses'), value: '' },\n { label: t('payment_gateways.status.pending', 'Pending'), value: 'pending' },\n { label: t('payment_gateways.status.authorized', 'Authorized'), value: 'authorized' },\n { label: t('payment_gateways.status.captured', 'Captured'), value: 'captured' },\n { label: t('payment_gateways.status.partially_captured', 'Partially Captured'), value: 'partially_captured' },\n { label: t('payment_gateways.status.refunded', 'Refunded'), value: 'refunded' },\n { label: t('payment_gateways.status.partially_refunded', 'Partially Refunded'), value: 'partially_refunded' },\n { label: t('payment_gateways.status.cancelled', 'Cancelled'), value: 'cancelled' },\n { label: t('payment_gateways.status.failed', 'Failed'), value: 'failed' },\n { label: t('payment_gateways.status.expired', 'Expired'), value: 'expired' },\n { label: t('payment_gateways.status.unknown', 'Unknown'), value: 'unknown' },\n ],\n },\n ], [providerOptions, t])\n\n const columns = React.useMemo<ColumnDef<TransactionRow>[]>(() => [\n {\n accessorKey: 'paymentId',\n header: t('payment_gateways.transactions.columns.paymentId', 'Payment'),\n cell: ({ row }) => (\n <div className=\"space-y-1\">\n <div className=\"font-medium\">{row.original.paymentId}</div>\n <div className=\"text-xs text-muted-foreground\">{row.original.id}</div>\n </div>\n ),\n meta: { maxWidth: '20rem' },\n },\n {\n accessorKey: 'providerKey',\n header: t('payment_gateways.transactions.columns.provider', 'Provider'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n <span>{formatTypeLabel(row.original.providerKey)}</span>\n </div>\n ),\n },\n {\n accessorKey: 'unifiedStatus',\n header: t('payment_gateways.transactions.columns.status', 'Status'),\n cell: ({ row }) => (\n <Badge variant=\"secondary\" className={STATUS_STYLES[row.original.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${row.original.unifiedStatus}`, formatTypeLabel(row.original.unifiedStatus))}\n </Badge>\n ),\n },\n {\n accessorKey: 'amount',\n header: t('payment_gateways.transactions.columns.amount', 'Amount'),\n cell: ({ row }) => formatAmount(row.original.amount, row.original.currencyCode),\n },\n {\n accessorKey: 'providerSessionId',\n header: t('payment_gateways.transactions.columns.session', 'Session'),\n cell: ({ row }) => (\n <span className=\"font-mono text-xs text-muted-foreground\">\n {row.original.providerSessionId ?? '\u2014'}\n </span>\n ),\n meta: { maxWidth: '18rem', truncate: true },\n },\n {\n accessorKey: 'updatedAt',\n header: t('payment_gateways.transactions.columns.updatedAt', 'Updated'),\n cell: ({ row }) => formatDateTime(row.original.updatedAt),\n },\n ], [t])\n\n const selectedSummary = React.useMemo(\n () => rows.find((row) => row.id === selectedId) ?? null,\n [rows, selectedId],\n )\n const canCaptureSelected = React.useMemo(() => {\n const status = detail?.transaction.unifiedStatus ?? selectedSummary?.unifiedStatus ?? null\n return status === 'authorized'\n }, [detail?.transaction.unifiedStatus, selectedSummary?.unifiedStatus])\n\n return (\n <Page>\n <PageHeader\n title={t('payment_gateways.transactions.title', 'Payment Transactions')}\n description={t('payment_gateways.transactions.description', 'Track all payment-gateway transactions, inspect webhook activity, and review provider logs from one place.')}\n />\n <PageBody className=\"space-y-6\">\n <DataTable\n stickyActionsColumn\n title={t('payment_gateways.transactions.tableTitle', 'Transactions')}\n columns={columns}\n data={rows}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('payment_gateways.transactions.searchPlaceholder', 'Search by payment, transaction, session, or gateway id')}\n perspective={{ tableId: 'payment_gateways.transactions.list' }}\n pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}\n isLoading={isLoading}\n onRowClick={(row) => setSelectedId((current) => current === row.id ? null : row.id)}\n rowActions={(row) => (\n <RowActions items={[\n {\n id: 'details',\n label: selectedId === row.id\n ? t('payment_gateways.transactions.actions.hideDetails', 'Hide details')\n : t('payment_gateways.transactions.actions.showDetails', 'Show details'),\n onSelect: () => setSelectedId((current) => current === row.id ? null : row.id),\n },\n ]} />\n )}\n />\n\n {selectedId ? (\n <Card>\n <CardHeader className=\"gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-1\">\n <CardTitle>{t('payment_gateways.transactions.detail.title', 'Transaction details')}</CardTitle>\n {selectedSummary ? (\n <div className=\"flex flex-wrap items-center gap-2 text-sm text-muted-foreground\">\n <span>{selectedSummary.paymentId}</span>\n <span>\u2022</span>\n <span>{formatTypeLabel(selectedSummary.providerKey)}</span>\n <Badge variant=\"secondary\" className={STATUS_STYLES[selectedSummary.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${selectedSummary.unifiedStatus}`, formatTypeLabel(selectedSummary.unifiedStatus))}\n </Badge>\n </div>\n ) : null}\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleRefreshStatus()}\n disabled={isRefreshingStatus || isLoadingDetail || isCapturing}\n >\n {isRefreshingStatus ? <Spinner className=\"mr-2 h-4 w-4\" /> : <RefreshCw className=\"mr-2 h-4 w-4\" />}\n {t('payment_gateways.transactions.actions.refreshStatus', 'Refresh status')}\n </Button>\n {canCaptureSelected ? (\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void handleCapturePayment()}\n disabled={isRefreshingStatus || isLoadingDetail || isCapturing}\n >\n {isCapturing ? <Spinner className=\"mr-2 h-4 w-4\" /> : <HandCoins className=\"mr-2 h-4 w-4\" />}\n {t('payment_gateways.transactions.actions.capture', 'Capture payment')}\n </Button>\n ) : null}\n </CardHeader>\n <CardContent className=\"space-y-6\">\n {isLoadingDetail ? <LoadingMessage label={t('payment_gateways.transactions.detail.loading', 'Loading transaction details')} /> : null}\n {!isLoadingDetail && detailError ? <ErrorMessage label={detailError} /> : null}\n {!isLoadingDetail && !detailError && detail ? (\n <>\n <div className=\"grid gap-4 lg:grid-cols-4\">\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.status', 'Status')}\n value={(\n <Badge variant=\"secondary\" className={STATUS_STYLES[detail.transaction.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${detail.transaction.unifiedStatus}`, formatTypeLabel(detail.transaction.unifiedStatus))}\n </Badge>\n )}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.gatewayStatus', 'Gateway status')}\n value={detail.transaction.gatewayStatus ?? noneLabel}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.amount', 'Amount')}\n value={formatAmount(detail.transaction.amount, detail.transaction.currencyCode)}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.provider', 'Provider')}\n value={formatTypeLabel(detail.transaction.providerKey)}\n />\n </div>\n\n <div className=\"grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]\">\n <div className=\"space-y-6\">\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.identifiers', 'Identifiers')}</h3>\n <dl className=\"grid gap-3 md:grid-cols-2\">\n {[\n [t('payment_gateways.transactions.columns.transactionId', 'Transaction ID'), detail.transaction.id],\n [t('payment_gateways.transactions.columns.paymentId', 'Payment ID'), detail.transaction.paymentId],\n [t('payment_gateways.transactions.columns.session', 'Session ID'), detail.transaction.providerSessionId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.gatewayPaymentId', 'Gateway payment ID'), detail.transaction.gatewayPaymentId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.gatewayRefundId', 'Gateway refund ID'), detail.transaction.gatewayRefundId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.redirectUrl', 'Redirect URL'), detail.transaction.redirectUrl ?? '\u2014'],\n [t('payment_gateways.transactions.columns.createdAt', 'Created at'), formatDateTime(detail.transaction.createdAt)],\n [t('payment_gateways.transactions.columns.updatedAt', 'Updated at'), formatDateTime(detail.transaction.updatedAt)],\n [t('payment_gateways.transactions.columns.lastWebhookAt', 'Last webhook'), formatDateTime(detail.transaction.lastWebhookAt)],\n [t('payment_gateways.transactions.columns.lastPolledAt', 'Last poll'), formatDateTime(detail.transaction.lastPolledAt)],\n ].map(([label, value]) => (\n <div key={label} className=\"rounded-lg border bg-muted/30 px-4 py-3\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 break-all text-sm\">{value}</dd>\n </div>\n ))}\n </dl>\n </section>\n\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Webhook className=\"h-4 w-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.webhooks', 'Webhook activity')}</h3>\n </div>\n {detail.transaction.webhookLog && detail.transaction.webhookLog.length > 0 ? (\n <div className=\"overflow-hidden rounded-lg border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/50\">\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.eventType', 'Event')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.status', 'Status')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.processed', 'Processed')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.receivedAt', 'Received')}</th>\n </tr>\n </thead>\n <tbody>\n {detail.transaction.webhookLog.map((entry) => (\n <tr key={`${entry.idempotencyKey}:${entry.receivedAt}`} className=\"border-b last:border-0\">\n <td className=\"px-4 py-2 font-medium\">{entry.eventType}</td>\n <td className=\"px-4 py-2\">\n <Badge variant=\"secondary\" className={STATUS_STYLES[entry.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${entry.unifiedStatus}`, formatTypeLabel(entry.unifiedStatus))}\n </Badge>\n </td>\n <td className=\"px-4 py-2\">{entry.processed ? t('common.yes', 'Yes') : t('common.no', 'No')}</td>\n <td className=\"px-4 py-2 text-muted-foreground\">{formatDateTime(entry.receivedAt)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('payment_gateways.transactions.detail.webhooksEmpty', 'No webhook events have been recorded for this transaction yet.')}</p>\n )}\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.logs', 'Gateway logs')}</h3>\n <LogList\n entries={detail.logs.map<LogListEntry>((log) => {\n const metadataEntries = [\n [t('payment_gateways.transactions.log.time', 'Time'), formatDateTime(log.createdAt)],\n [t('payment_gateways.transactions.log.level', 'Level'), t(`payment_gateways.transactions.level.${log.level}`, log.level)],\n [t('payment_gateways.transactions.log.code', 'Code'), log.code ?? null],\n [t('payment_gateways.transactions.log.runId', 'Run ID'), log.runId ?? null],\n [t('payment_gateways.transactions.log.entityType', 'Entity Type'), log.scopeEntityType ?? null],\n [t('payment_gateways.transactions.log.entityId', 'Entity ID'), log.scopeEntityId ?? null],\n ].filter((entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].trim().length > 0)\n const { inlineEntries, nestedEntries } = splitLogPayload(log.payload)\n\n return {\n id: log.id,\n time: formatDateTime(log.createdAt),\n level: log.level,\n levelLabel: t(`payment_gateways.transactions.level.${log.level}`, log.level),\n message: log.message,\n body: (\n <div className=\"space-y-4\">\n {metadataEntries.length > 0 ? (\n <dl className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {metadataEntries.map(([label, value]) => (\n <div key={label} className=\"rounded-md border bg-muted/30 px-3 py-2\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 break-all text-sm\">{value}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n {inlineEntries.length > 0 ? (\n <dl className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {inlineEntries.map(([key, value]) => (\n <div key={key} className=\"rounded-md border bg-muted/30 px-3 py-2\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{formatLogDetailLabel(key)}</dt>\n <dd className=\"mt-1 break-words text-sm\">{formatLogPrimitiveValue(value)}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n {nestedEntries.map(([key, value]) => (\n <JsonDisplay\n key={key}\n data={value}\n title={formatLogDetailLabel(key)}\n defaultExpanded\n maxInitialDepth={1}\n theme=\"dark\"\n maxHeight=\"16rem\"\n className=\"p-4\"\n />\n ))}\n </div>\n ),\n }\n })}\n emptyMessage={t('payment_gateways.transactions.detail.logsEmpty', 'No transaction-scoped logs are available yet.')}\n />\n </section>\n </div>\n\n <div className=\"space-y-4\">\n <JsonDisplay\n data={detail.transaction.gatewayMetadata ?? {}}\n title={t('payment_gateways.transactions.detail.gatewayMetadata', 'Gateway metadata')}\n defaultExpanded\n maxInitialDepth={1}\n theme=\"dark\"\n maxHeight=\"24rem\"\n className=\"p-4\"\n />\n <InjectionSpot\n spotId=\"admin.page:payment-gateways/transactions:after\"\n context={{ selectedPaymentId: detail.transaction.paymentId }}\n />\n </div>\n </div>\n </>\n ) : null}\n </CardContent>\n </Card>\n ) : null}\n </PageBody>\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Page, PageHeader, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { LogList, type LogListEntry } from '@open-mercato/ui/backend/LogList'\nimport { CreditCard, HandCoins, RefreshCw, Webhook } from 'lucide-react'\n\ntype TransactionRow = {\n id: string\n paymentId: string\n providerKey: string\n providerSessionId?: string | null\n gatewayPaymentId?: string | null\n gatewayRefundId?: string | null\n unifiedStatus: string\n gatewayStatus?: string | null\n amount: string\n currencyCode: string\n redirectUrl?: string | null\n lastWebhookAt?: string | null\n lastPolledAt?: string | null\n createdAt: string | null\n updatedAt: string | null\n}\n\ntype TransactionLogEntry = {\n id: string\n integrationId: string\n runId?: string | null\n scopeEntityType?: string | null\n scopeEntityId?: string | null\n level: 'info' | 'warn' | 'error'\n message: string\n code?: string | null\n payload?: Record<string, unknown> | null\n createdAt: string | null\n}\n\ntype TransactionDetail = {\n transaction: {\n id: string\n paymentId: string\n providerKey: string\n providerSessionId?: string | null\n gatewayPaymentId?: string | null\n gatewayRefundId?: string | null\n unifiedStatus: string\n gatewayStatus?: string | null\n redirectUrl?: string | null\n amount: string\n currencyCode: string\n gatewayMetadata?: Record<string, unknown> | null\n webhookLog?: Array<{\n eventType: string\n receivedAt: string\n idempotencyKey: string\n unifiedStatus: string\n processed: boolean\n }> | null\n lastWebhookAt?: string | null\n lastPolledAt?: string | null\n expiresAt?: string | null\n createdAt: string | null\n updatedAt: string | null\n }\n logs: TransactionLogEntry[]\n}\n\ntype TransactionsResponse = {\n items: TransactionRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n}\n\nconst STATUS_STYLES: Record<string, string> = {\n pending: 'bg-slate-100 text-slate-800',\n authorized: 'bg-blue-100 text-blue-800',\n captured: 'bg-green-100 text-green-800',\n partially_captured: 'bg-emerald-100 text-emerald-800',\n refunded: 'bg-amber-100 text-amber-800',\n partially_refunded: 'bg-orange-100 text-orange-800',\n cancelled: 'bg-zinc-200 text-zinc-900',\n failed: 'bg-red-100 text-red-800',\n expired: 'bg-neutral-200 text-neutral-900',\n unknown: 'bg-purple-100 text-purple-800',\n}\n\nfunction formatDateTime(value: string | null | undefined): string {\n if (!value) return '\u2014'\n const parsed = new Date(value)\n if (Number.isNaN(parsed.getTime())) return value\n return parsed.toLocaleString()\n}\n\nfunction formatAmount(value: string, currencyCode: string): string {\n const amount = Number(value)\n if (Number.isNaN(amount)) return `${value} ${currencyCode}`\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency: currencyCode,\n }).format(amount)\n } catch {\n return `${amount.toFixed(2)} ${currencyCode}`\n }\n}\n\nfunction formatTypeLabel(value: string): string {\n return value\n .split('_')\n .filter(Boolean)\n .map((part) => part[0]?.toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nfunction formatLogDetailLabel(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((part) => part[0]?.toUpperCase() + part.slice(1))\n .join(' ')\n}\n\nfunction isPrimitiveLogValue(value: unknown): value is string | number | boolean | null {\n return value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean'\n}\n\nfunction splitLogPayload(payload: Record<string, unknown> | null | undefined) {\n if (!payload) {\n return {\n inlineEntries: [] as Array<[string, string | number | boolean | null]>,\n nestedEntries: [] as Array<[string, unknown]>,\n }\n }\n\n const inlineEntries: Array<[string, string | number | boolean | null]> = []\n const nestedEntries: Array<[string, unknown]> = []\n Object.entries(payload).forEach(([key, value]) => {\n if (isPrimitiveLogValue(value)) {\n inlineEntries.push([key, value])\n return\n }\n nestedEntries.push([key, value])\n })\n return { inlineEntries, nestedEntries }\n}\n\nfunction DetailStat({ label, value }: { label: string; value: React.ReactNode }) {\n return (\n <div className=\"rounded-lg border bg-muted/30 px-4 py-3\">\n <div className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</div>\n <div className=\"mt-1 text-sm font-medium\">{value}</div>\n </div>\n )\n}\n\nexport default function PaymentTransactionsPage() {\n const t = useT()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<TransactionRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n const [detail, setDetail] = React.useState<TransactionDetail | null>(null)\n const [isLoadingDetail, setIsLoadingDetail] = React.useState(false)\n const [detailError, setDetailError] = React.useState<string | null>(null)\n const [isRefreshingStatus, setIsRefreshingStatus] = React.useState(false)\n const [isCapturing, setIsCapturing] = React.useState(false)\n const { runMutation } = useGuardedMutation<{\n entityType: string\n entityId?: string\n }>({\n contextId: 'payment_gateways:transactions-detail',\n })\n const noneLabel = t('common.none', 'None')\n const requestedTransactionId = React.useMemo(() => {\n const raw = searchParams.get('transactionId')\n return raw && raw.trim().length > 0 ? raw.trim() : null\n }, [searchParams])\n\n const formatLogPrimitiveValue = React.useCallback((value: string | number | boolean | null): string => {\n if (value === null) return noneLabel\n if (typeof value === 'boolean') return value ? t('common.yes', 'Yes') : t('common.no', 'No')\n return String(value)\n }, [noneLabel, t])\n\n const loadRows = React.useCallback(async () => {\n setIsLoading(true)\n const params = new URLSearchParams({\n page: String(page),\n pageSize: '20',\n })\n if (search.trim()) params.set('search', search.trim())\n if (typeof filterValues.providerKey === 'string' && filterValues.providerKey) {\n params.set('providerKey', filterValues.providerKey)\n }\n if (typeof filterValues.status === 'string' && filterValues.status) {\n params.set('status', filterValues.status)\n }\n const fallback: TransactionsResponse = { items: [], total: 0, page, pageSize: 20, totalPages: 1 }\n const call = await apiCall<TransactionsResponse>(`/api/payment_gateways/transactions?${params.toString()}`, undefined, { fallback })\n if (call.ok && call.result) {\n setRows(Array.isArray(call.result.items) ? call.result.items : [])\n setTotal(call.result.total ?? 0)\n setTotalPages(call.result.totalPages ?? 1)\n } else {\n flash(t('payment_gateways.transactions.error.load', 'Failed to load payment transactions'), 'error')\n setRows([])\n setTotal(0)\n setTotalPages(1)\n }\n setIsLoading(false)\n }, [filterValues.providerKey, filterValues.status, page, search, t])\n\n const loadDetail = React.useCallback(async (transactionId: string) => {\n setIsLoadingDetail(true)\n setDetailError(null)\n const call = await apiCall<TransactionDetail>(`/api/payment_gateways/transactions/${encodeURIComponent(transactionId)}`, undefined, { fallback: null })\n if (call.ok && call.result) {\n setDetail(call.result)\n } else {\n setDetail(null)\n setDetailError(t('payment_gateways.transactions.error.loadDetail', 'Failed to load transaction details'))\n }\n setIsLoadingDetail(false)\n }, [t])\n\n React.useEffect(() => {\n void loadRows()\n }, [loadRows, scopeVersion])\n\n React.useEffect(() => {\n if (!selectedId) {\n setDetail(null)\n setDetailError(null)\n return\n }\n void loadDetail(selectedId)\n }, [loadDetail, selectedId])\n\n React.useEffect(() => {\n setSelectedId((current) => (current && rows.some((row) => row.id === current) ? current : null))\n }, [rows])\n\n React.useEffect(() => {\n if (!requestedTransactionId) return\n if (!rows.some((row) => row.id === requestedTransactionId)) return\n setSelectedId(requestedTransactionId)\n }, [requestedTransactionId, rows])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (typeof value === 'string' && value.trim()) next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefreshStatus = React.useCallback(async () => {\n if (!selectedId) return\n setIsRefreshingStatus(true)\n try {\n await runMutation({\n operation: async () => {\n await apiCallOrThrow('/api/payment_gateways/status', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ transactionId: selectedId }),\n })\n },\n context: {\n entityType: 'payment_gateways:gateway_transaction',\n entityId: selectedId,\n },\n mutationPayload: { transactionId: selectedId },\n })\n await Promise.all([\n loadRows(),\n loadDetail(selectedId),\n ])\n flash(t('payment_gateways.transactions.success.refreshStatus', 'Transaction status refreshed'), 'success')\n } catch (error) {\n const message = error instanceof Error && error.message\n ? error.message\n : t('payment_gateways.transactions.error.refreshStatus', 'Failed to refresh transaction status')\n flash(message, 'error')\n } finally {\n setIsRefreshingStatus(false)\n }\n }, [loadDetail, loadRows, runMutation, selectedId, t])\n\n const handleCapturePayment = React.useCallback(async () => {\n if (!selectedId) return\n setIsCapturing(true)\n try {\n await runMutation({\n operation: async () => {\n await apiCallOrThrow('/api/payment_gateways/capture', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ transactionId: selectedId }),\n })\n },\n context: {\n entityType: 'payment_gateways:gateway_transaction',\n entityId: selectedId,\n },\n mutationPayload: { transactionId: selectedId },\n })\n await Promise.all([\n loadRows(),\n loadDetail(selectedId),\n ])\n flash(t('payment_gateways.transactions.success.capture', 'Payment captured'), 'success')\n } catch (error) {\n const message = error instanceof Error && error.message\n ? error.message\n : t('payment_gateways.transactions.error.capture', 'Failed to capture payment')\n flash(message, 'error')\n } finally {\n setIsCapturing(false)\n }\n }, [loadDetail, loadRows, runMutation, selectedId, t])\n\n const providerOptions = React.useMemo(() => {\n const values = Array.from(new Set(rows.map((row) => row.providerKey).filter(Boolean))).sort((a, b) => a.localeCompare(b))\n return values.map((value) => ({\n label: formatTypeLabel(value),\n value,\n }))\n }, [rows])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'providerKey',\n type: 'select',\n label: t('payment_gateways.transactions.filters.provider', 'Provider'),\n options: [\n { label: t('payment_gateways.transactions.filters.allProviders', 'All providers'), value: '' },\n ...providerOptions,\n ],\n },\n {\n id: 'status',\n type: 'select',\n label: t('payment_gateways.transactions.filters.status', 'Status'),\n options: [\n { label: t('payment_gateways.transactions.filters.allStatuses', 'All statuses'), value: '' },\n { label: t('payment_gateways.status.pending', 'Pending'), value: 'pending' },\n { label: t('payment_gateways.status.authorized', 'Authorized'), value: 'authorized' },\n { label: t('payment_gateways.status.captured', 'Captured'), value: 'captured' },\n { label: t('payment_gateways.status.partially_captured', 'Partially Captured'), value: 'partially_captured' },\n { label: t('payment_gateways.status.refunded', 'Refunded'), value: 'refunded' },\n { label: t('payment_gateways.status.partially_refunded', 'Partially Refunded'), value: 'partially_refunded' },\n { label: t('payment_gateways.status.cancelled', 'Cancelled'), value: 'cancelled' },\n { label: t('payment_gateways.status.failed', 'Failed'), value: 'failed' },\n { label: t('payment_gateways.status.expired', 'Expired'), value: 'expired' },\n { label: t('payment_gateways.status.unknown', 'Unknown'), value: 'unknown' },\n ],\n },\n ], [providerOptions, t])\n\n const columns = React.useMemo<ColumnDef<TransactionRow>[]>(() => [\n {\n accessorKey: 'paymentId',\n header: t('payment_gateways.transactions.columns.paymentId', 'Payment'),\n cell: ({ row }) => (\n <div className=\"space-y-1\">\n <div className=\"font-medium\">{row.original.paymentId}</div>\n <div className=\"text-xs text-muted-foreground\">{row.original.id}</div>\n </div>\n ),\n meta: { maxWidth: '20rem' },\n },\n {\n accessorKey: 'providerKey',\n header: t('payment_gateways.transactions.columns.provider', 'Provider'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n <span>{formatTypeLabel(row.original.providerKey)}</span>\n </div>\n ),\n },\n {\n accessorKey: 'unifiedStatus',\n header: t('payment_gateways.transactions.columns.status', 'Status'),\n cell: ({ row }) => (\n <Badge variant=\"secondary\" className={STATUS_STYLES[row.original.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${row.original.unifiedStatus}`, formatTypeLabel(row.original.unifiedStatus))}\n </Badge>\n ),\n },\n {\n accessorKey: 'amount',\n header: t('payment_gateways.transactions.columns.amount', 'Amount'),\n cell: ({ row }) => formatAmount(row.original.amount, row.original.currencyCode),\n },\n {\n accessorKey: 'providerSessionId',\n header: t('payment_gateways.transactions.columns.session', 'Session'),\n cell: ({ row }) => (\n <span className=\"font-mono text-xs text-muted-foreground\">\n {row.original.providerSessionId ?? '\u2014'}\n </span>\n ),\n meta: { maxWidth: '18rem', truncate: true },\n },\n {\n accessorKey: 'updatedAt',\n header: t('payment_gateways.transactions.columns.updatedAt', 'Updated'),\n cell: ({ row }) => formatDateTime(row.original.updatedAt),\n },\n ], [t])\n\n const selectedSummary = React.useMemo(\n () => rows.find((row) => row.id === selectedId) ?? null,\n [rows, selectedId],\n )\n const canCaptureSelected = React.useMemo(() => {\n const status = detail?.transaction.unifiedStatus ?? selectedSummary?.unifiedStatus ?? null\n return status === 'authorized'\n }, [detail?.transaction.unifiedStatus, selectedSummary?.unifiedStatus])\n\n return (\n <Page>\n <PageHeader\n title={t('payment_gateways.transactions.title', 'Payment Transactions')}\n description={t('payment_gateways.transactions.description', 'Track all payment-gateway transactions, inspect webhook activity, and review provider logs from one place.')}\n />\n <PageBody className=\"space-y-6\">\n <DataTable\n stickyActionsColumn\n title={t('payment_gateways.transactions.tableTitle', 'Transactions')}\n columns={columns}\n data={rows}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('payment_gateways.transactions.searchPlaceholder', 'Search by payment, transaction, session, or gateway id')}\n perspective={{ tableId: 'payment_gateways.transactions.list' }}\n pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}\n isLoading={isLoading}\n onRowClick={(row) => setSelectedId((current) => current === row.id ? null : row.id)}\n rowActions={(row) => (\n <RowActions items={[\n {\n id: 'details',\n label: selectedId === row.id\n ? t('payment_gateways.transactions.actions.hideDetails', 'Hide details')\n : t('payment_gateways.transactions.actions.showDetails', 'Show details'),\n onSelect: () => setSelectedId((current) => current === row.id ? null : row.id),\n },\n ]} />\n )}\n />\n\n {selectedId ? (\n <Card>\n <CardHeader className=\"gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-1\">\n <CardTitle>{t('payment_gateways.transactions.detail.title', 'Transaction details')}</CardTitle>\n {selectedSummary ? (\n <div className=\"flex flex-wrap items-center gap-2 text-sm text-muted-foreground\">\n <span>{selectedSummary.paymentId}</span>\n <span>\u2022</span>\n <span>{formatTypeLabel(selectedSummary.providerKey)}</span>\n <Badge variant=\"secondary\" className={STATUS_STYLES[selectedSummary.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${selectedSummary.unifiedStatus}`, formatTypeLabel(selectedSummary.unifiedStatus))}\n </Badge>\n </div>\n ) : null}\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleRefreshStatus()}\n disabled={isRefreshingStatus || isLoadingDetail || isCapturing}\n >\n {isRefreshingStatus ? <Spinner className=\"mr-2 h-4 w-4\" /> : <RefreshCw className=\"mr-2 h-4 w-4\" />}\n {t('payment_gateways.transactions.actions.refreshStatus', 'Refresh status')}\n </Button>\n {canCaptureSelected ? (\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void handleCapturePayment()}\n disabled={isRefreshingStatus || isLoadingDetail || isCapturing}\n >\n {isCapturing ? <Spinner className=\"mr-2 h-4 w-4\" /> : <HandCoins className=\"mr-2 h-4 w-4\" />}\n {t('payment_gateways.transactions.actions.capture', 'Capture payment')}\n </Button>\n ) : null}\n </CardHeader>\n <CardContent className=\"space-y-6\">\n {isLoadingDetail ? <LoadingMessage label={t('payment_gateways.transactions.detail.loading', 'Loading transaction details')} /> : null}\n {!isLoadingDetail && detailError ? <ErrorMessage label={detailError} /> : null}\n {!isLoadingDetail && !detailError && detail ? (\n <>\n <div className=\"grid gap-4 lg:grid-cols-4\">\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.status', 'Status')}\n value={(\n <Badge variant=\"secondary\" className={STATUS_STYLES[detail.transaction.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${detail.transaction.unifiedStatus}`, formatTypeLabel(detail.transaction.unifiedStatus))}\n </Badge>\n )}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.gatewayStatus', 'Gateway status')}\n value={detail.transaction.gatewayStatus ?? noneLabel}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.amount', 'Amount')}\n value={formatAmount(detail.transaction.amount, detail.transaction.currencyCode)}\n />\n <DetailStat\n label={t('payment_gateways.transactions.detail.summary.provider', 'Provider')}\n value={formatTypeLabel(detail.transaction.providerKey)}\n />\n </div>\n\n <div className=\"grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]\">\n <div className=\"space-y-6\">\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.identifiers', 'Identifiers')}</h3>\n <dl className=\"grid gap-3 md:grid-cols-2\">\n {[\n [t('payment_gateways.transactions.columns.transactionId', 'Transaction ID'), detail.transaction.id],\n [t('payment_gateways.transactions.columns.paymentId', 'Payment ID'), detail.transaction.paymentId],\n [t('payment_gateways.transactions.columns.session', 'Session ID'), detail.transaction.providerSessionId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.gatewayPaymentId', 'Gateway payment ID'), detail.transaction.gatewayPaymentId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.gatewayRefundId', 'Gateway refund ID'), detail.transaction.gatewayRefundId ?? '\u2014'],\n [t('payment_gateways.transactions.columns.redirectUrl', 'Redirect URL'), detail.transaction.redirectUrl ?? '\u2014'],\n [t('payment_gateways.transactions.columns.createdAt', 'Created at'), formatDateTime(detail.transaction.createdAt)],\n [t('payment_gateways.transactions.columns.updatedAt', 'Updated at'), formatDateTime(detail.transaction.updatedAt)],\n [t('payment_gateways.transactions.columns.lastWebhookAt', 'Last webhook'), formatDateTime(detail.transaction.lastWebhookAt)],\n [t('payment_gateways.transactions.columns.lastPolledAt', 'Last poll'), formatDateTime(detail.transaction.lastPolledAt)],\n ].map(([label, value]) => (\n <div key={label} className=\"rounded-lg border bg-muted/30 px-4 py-3\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 break-all text-sm\">{value}</dd>\n </div>\n ))}\n </dl>\n </section>\n\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Webhook className=\"h-4 w-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.webhooks', 'Webhook activity')}</h3>\n </div>\n {detail.transaction.webhookLog && detail.transaction.webhookLog.length > 0 ? (\n <div className=\"overflow-hidden rounded-lg border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/50\">\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.eventType', 'Event')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.status', 'Status')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.processed', 'Processed')}</th>\n <th className=\"px-4 py-2 text-left font-medium\">{t('payment_gateways.transactions.columns.receivedAt', 'Received')}</th>\n </tr>\n </thead>\n <tbody>\n {detail.transaction.webhookLog.map((entry) => (\n <tr key={`${entry.idempotencyKey}:${entry.receivedAt}`} className=\"border-b last:border-0\">\n <td className=\"px-4 py-2 font-medium\">{entry.eventType}</td>\n <td className=\"px-4 py-2\">\n <Badge variant=\"secondary\" className={STATUS_STYLES[entry.unifiedStatus] ?? ''}>\n {t(`payment_gateways.status.${entry.unifiedStatus}`, formatTypeLabel(entry.unifiedStatus))}\n </Badge>\n </td>\n <td className=\"px-4 py-2\">{entry.processed ? t('common.yes', 'Yes') : t('common.no', 'No')}</td>\n <td className=\"px-4 py-2 text-muted-foreground\">{formatDateTime(entry.receivedAt)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('payment_gateways.transactions.detail.webhooksEmpty', 'No webhook events have been recorded for this transaction yet.')}</p>\n )}\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">{t('payment_gateways.transactions.detail.logs', 'Gateway logs')}</h3>\n <LogList\n entries={detail.logs.map<LogListEntry>((log) => {\n const metadataEntries = [\n [t('payment_gateways.transactions.log.time', 'Time'), formatDateTime(log.createdAt)],\n [t('payment_gateways.transactions.log.level', 'Level'), t(`payment_gateways.transactions.level.${log.level}`, log.level)],\n [t('payment_gateways.transactions.log.code', 'Code'), log.code ?? null],\n [t('payment_gateways.transactions.log.runId', 'Run ID'), log.runId ?? null],\n [t('payment_gateways.transactions.log.entityType', 'Entity Type'), log.scopeEntityType ?? null],\n [t('payment_gateways.transactions.log.entityId', 'Entity ID'), log.scopeEntityId ?? null],\n ].filter((entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].trim().length > 0)\n const { inlineEntries, nestedEntries } = splitLogPayload(log.payload)\n\n return {\n id: log.id,\n time: formatDateTime(log.createdAt),\n level: log.level,\n levelLabel: t(`payment_gateways.transactions.level.${log.level}`, log.level),\n message: log.message,\n body: (\n <div className=\"space-y-4\">\n {metadataEntries.length > 0 ? (\n <dl className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {metadataEntries.map(([label, value]) => (\n <div key={label} className=\"rounded-md border bg-muted/30 px-3 py-2\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 break-all text-sm\">{value}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n {inlineEntries.length > 0 ? (\n <dl className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {inlineEntries.map(([key, value]) => (\n <div key={key} className=\"rounded-md border bg-muted/30 px-3 py-2\">\n <dt className=\"text-overline font-medium uppercase tracking-wide text-muted-foreground\">{formatLogDetailLabel(key)}</dt>\n <dd className=\"mt-1 break-words text-sm\">{formatLogPrimitiveValue(value)}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n {nestedEntries.map(([key, value]) => (\n <JsonDisplay\n key={key}\n data={value}\n title={formatLogDetailLabel(key)}\n defaultExpanded\n maxInitialDepth={1}\n theme=\"dark\"\n maxHeight=\"16rem\"\n className=\"p-4\"\n />\n ))}\n </div>\n ),\n }\n })}\n emptyMessage={t('payment_gateways.transactions.detail.logsEmpty', 'No transaction-scoped logs are available yet.')}\n />\n </section>\n </div>\n\n <div className=\"space-y-4\">\n <JsonDisplay\n data={detail.transaction.gatewayMetadata ?? {}}\n title={t('payment_gateways.transactions.detail.gatewayMetadata', 'Gateway metadata')}\n defaultExpanded\n maxInitialDepth={1}\n theme=\"dark\"\n maxHeight=\"24rem\"\n className=\"p-4\"\n />\n <InjectionSpot\n spotId=\"admin.page:payment-gateways/transactions:after\"\n context={{ selectedPaymentId: detail.transaction.paymentId }}\n />\n </div>\n </div>\n </>\n ) : null}\n </CardContent>\n </Card>\n ) : null}\n </PageBody>\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }