{"version":3,"file":"index.cjs","names":[],"sources":["../src/services/dashboardApi.js","../src/components/cards/CalendarCard.jsx","../src/components/DynamicTabs.jsx","../src/services/popupApi.js","../src/components/cards/dashboardVisibleCards.js","../src/components/cards/cardConfig.js","../src/components/CustomPagination.jsx","../src/components/cards/DynamicCards.jsx","../src/components/cards/HierarchyUserFilter.jsx","../src/utils/autoValueRules.js","../src/components/form/duplicateRecord.js","../src/components/form/useDuplicateCheck.js","../src/components/form/storedFileName.js","../src/services/dropdownApi.js","../src/utils/accessToken.js","../src/hooks/useDropdownFields.js","../src/contexts/PermissionContext.jsx","../src/hooks/useMenuPermission.js","../src/hooks/usePermissions.js","../src/utils/actionPermission.js","../src/utils/actionRuleEngine.js","../src/config/responseMappings/default.json","../src/services/responseMapping/mapListResponse.js","../src/components/viewSummaryConfig.js","../src/components/ViewSummaryWidget.jsx","../src/hooks/useDropdownValues.js","../src/components/filters/DynamicFieldFilter.jsx","../src/components/images/common/eyeoutlined.svg","../src/components/images/common/frame.svg","../src/components/images/common/unorderedlistoutlined.svg","../src/components/ListView.jsx","../src/services/pendingHandoff.js","../src/services/skillMatchApi.js","../src/services/candidatesApi.js","../src/services/sourceProviderActions.js","../src/components/AddFormV1.jsx","../src/components/AppAlert.jsx","../src/components/detail/timelineUtils.js","../src/components/detail/timeline.jsx","../src/components/detail/activityMeta.jsx","../src/components/detail/ActivityTab.jsx","../src/components/detail/NotesTab.jsx","../src/components/detail/ActivityNotesCard.jsx","../src/components/AssigneeAvatars.jsx","../src/components/upload/bulkUploadValidation.js","../src/components/upload/BulkUploadPanel.jsx","../src/services/jobsApi.js","../src/components/DescriptionBlock.jsx","../src/hooks/useVisibleTabs.js","../src/components/detail/detailConfig/financeHeaderCommon.js","../src/components/detail/detailConfig/modules/billingConfig.js","../src/components/detail/detailConfig/configUtils.js","../src/components/detail/detailConfig/modules/candidateConfig.js","../src/components/detail/detailConfig/modules/employerConfig.js","../src/components/detail/detailEmptiness.js","../src/components/detail/detailVisibility.js","../src/components/detail/historyRateKeys.js","../src/utils/currency.js","../src/components/detail/emptyText.js","../src/components/detail/fieldRenderEngine.jsx","../src/components/DetailViewV1.jsx","../src/components/detail/detailConfig/modules/jobConfig.js","../src/components/detail/detailConfig/modules/payrollConfig.js","../src/components/detail/detailConfig/modules/submissionConfig.js","../src/components/detail/detailConfig/modules/submissionJobConfig.js","../src/components/detail/detailConfig/headerSpec.js","../src/components/detail/detailConfig/headerConfig.js","../src/components/detail/headerMeta.js","../src/components/detail/auxRecords.js","../src/components/finance/financeUtils.js","../src/components/finance/FinanceComponents.jsx","../src/components/finance/FinanceRecordsTable.jsx","../src/components/detail/DetailHeaderCard.jsx","../src/components/detail/tabContentRegistry.jsx","../src/hooks/useRecordRefresh.js","../src/components/DetailViewPage.jsx","../src/components/form/editFormOptionFallbacks.js","../src/components/form/verifyLockState.js","../src/components/EditFormV1.jsx","../src/hooks/useModuleActions.js","../src/components/actions/ModuleRowActions.jsx","../src/components/ParamCardView.jsx","../src/components/ParamListView.jsx","../src/components/searchBuilder/RangeSliderField.jsx","../src/components/searchBuilder/dateRangePresets.js","../src/components/searchBuilder/DateRangePresetField.jsx","../src/components/searchBuilder/fieldTypeRegistry.jsx","../src/components/searchBuilder/SearchFieldControl.jsx","../src/components/searchBuilder/BooleanQueryField.jsx","../src/components/searchBuilder/booleanQueryUtils.js","../src/components/searchBuilder/buildBooleanRequest.js","../src/components/searchBuilder/buildTraditionalParams.js","../src/components/searchBuilder/buildFilterConditions.js","../src/services/booleanSearchApi.js","../src/services/candidateSearchAdapter.js","../src/components/SearchBuilderV1.jsx","../src/components/StatusBadge.jsx","../src/components/StylishDynamicTabs.jsx","../src/components/TemplateEditor.jsx","../src/components/finance/FinanceListToolbar.jsx","../src/components/timesheet/timesheetHoursPolicy.js","../src/components/timesheet/TimesheetComponents.jsx","../src/components/finance/FinanceTimesheetAnalysis.jsx","../src/components/finance/financeApprovalConfig.js","../src/components/finance/financeApprovalEngine.js","../src/components/finance/FinanceApprovalPanel.jsx","../src/components/finance/financeApprovalData.js","../src/components/detail/FileListCard.jsx","../src/hooks/useEditForm.js","../src/assets/images/login-1.svg","../src/assets/images/login-2.svg","../src/assets/images/sidebar/logo_icon.svg","../src/assets/images/sidebar/logo_text.svg","../src/assets/images/sidebar/zn-icn-arrow-close.svg","../src/assets/images/sidebar/zn-icn-admin.svg","../src/assets/images/sidebar/zn-icn-assignments.svg","../src/assets/images/sidebar/zn-icn-jobs.svg","../src/assets/images/sidebar/zn-icn-candidate.svg","../src/assets/images/sidebar/zn-icn-client-management.svg","../src/assets/images/sidebar/zn-icn-dashboard.svg","../src/assets/images/sidebar/zn-icn-employer-management.svg","../src/assets/images/sidebar/zn-icn-help.svg","../src/assets/images/sidebar/zn-icn-network.svg","../src/assets/images/sidebar/zn-icn-reports.svg","../src/assets/images/sidebar/zn-icn-settings.svg","../src/assets/images/sidebar/zn-icn-scheduler.svg","../src/assets/images/sidebar/zn-icn-submission.svg","../src/assets/images/sidebar/zn-icn-onboarding.svg","../src/assets/images/sidebar/zn-icn-timesheet.svg","../src/assets/images/sidebar/zn-campaign-sidebar.svg","../src/assets/images/sidebar/zn-icn-inbox.svg","../src/assets/images/sidebar/zn-icn-billing.svg","../src/assets/images/sidebar/zn-icn-payroll.svg","../src/components/layouts/Header.jsx","../src/components/layouts/Sidebar.jsx","../src/components/auth/AuthGuard.jsx","../src/components/auth/RoutePermissionGuard.jsx","../src/components/layouts/AppShell.jsx","../src/components/auth/Login.jsx","../src/services/testingApi.js","../src/components/auth/ProjectSelect.jsx","../src/components/auth/withAuthGuard.jsx","../src/services/adminCoreApi.js","../src/utils/permissionApplicability.js","../src/components/cards/AppCard.jsx","../src/pages/Modules/Admin/components/ModuleFieldConfigEditor.jsx","../src/utils/moduleOptions.js","../src/pages/Modules/Admin/components/RoleFormPermissionsEditor.jsx","../src/pages/Modules/Admin/components/RoleActionsEditor.jsx","../src/components/form/conditionOperators.js","../src/pages/Modules/Admin/uniqueValidationConfig.js","../src/components/admin/OtpGateModal.jsx","../src/pages/Modules/Admin/components/DefaultFieldsPanel.jsx","../src/pages/Modules/Admin/formOptions.js","../src/pages/Modules/Admin/FormGroupsSection.jsx","../src/pages/Modules/Admin/DetailGroupsSection.jsx","../src/services/emailTemplateApi.js","../src/pages/Modules/Admin/RowActionsSection.jsx","../src/pages/Modules/Admin/ModuleActionRulesSection.jsx","../src/pages/Modules/Admin/ActionsSection.jsx","../src/pages/Modules/Admin/TemplatesSection.jsx","../src/pages/Modules/Admin/AiServiceSettingsSection.jsx","../src/pages/Modules/Admin/IntegrationSettingsSection.jsx","../src/pages/Modules/Admin/AutomationsSection.jsx","../src/pages/Modules/Admin/WorkflowsSection.jsx","../src/pages/Modules/Admin/MastersSection.jsx","../src/pages/Modules/Admin/POMsaSettingsSection.jsx","../src/pages/admin/MenusSection.jsx","../src/pages/admin/AdminDashboard.jsx","../src/pages/Modules/AdminPage.jsx","../src/components/auth/CoreThemeAdminApp.jsx","../src/components/popups/mailUtils.js","../src/components/popups/CommonMailComposer.jsx","../src/components/popups/MailPopup.jsx","../src/components/detail/DescriptionBlock.jsx","../src/components/popups/PreviewPopup.jsx","../src/components/popups/WizardPopup.jsx","../src/components/popups/dynamic/PopupHeader.jsx","../src/components/popups/dynamic/PopupBody.jsx","../src/components/popups/dynamic/PopupFooter.jsx","../src/components/popups/dynamic/utils/popupUtils.js","../src/components/popups/dynamic/richSelectOption.jsx","../src/components/popups/dynamic/fieldRegistry.jsx","../src/components/popups/dynamic/PopupFields.jsx","../src/components/popups/dynamic/hooks/usePopupOptions.js","../src/components/popups/dynamic/hooks/usePopupSearch.js","../src/components/popups/dynamic/hooks/usePopupSubmit.js","../src/components/popups/dynamic/DynamicPopup.jsx","../src/components/popups/definitions/delete/config.js","../src/components/popups/definitions/delete/api.js","../src/components/form/inProgressGate.js","../src/components/popups/definitions/quick-submit/api.js","../src/components/popups/definitions/quick-submit/config.js","../src/components/popups/definitions/add-notes/config.js","../src/services/notesApi.js","../src/components/popups/definitions/add-notes/api.js","../src/components/popups/definitions/tag-to-job/config.js","../src/services/workflowApi.js","../src/components/popups/definitions/tag-to-job/api.js","../src/components/popups/definitions/change-status/config.js","../src/components/popups/definitions/change-status/api.js","../src/components/popups/definitions/remove-from-shortlist/config.js","../src/components/popups/definitions/remove-from-shortlist/api.js","../src/components/popups/definitions/add-to-groups/config.js","../src/components/popups/definitions/add-to-groups/api.js","../src/components/popups/definitions/self-assign/SelfAssignBody.jsx","../src/components/popups/definitions/self-assign/config.js","../src/components/popups/definitions/self-assign/api.js","../src/components/popups/definitions/others-assign/config.js","../src/components/popups/definitions/others-assign/api.js","../src/components/popups/definitions/sticky-notes/config.js","../src/components/popups/definitions/sticky-notes/api.js","../src/components/popups/definitions/move-to-onboarding/config.js","../src/components/popups/definitions/move-to-onboarding/api.js","../src/components/popups/definitions/approve-rate/config.js","../src/components/popups/definitions/approve-rate/api.js","../src/services/mailApproveApi.js","../src/components/popups/definitions/manager-approve/ManagerApproveBody.jsx","../src/components/popups/definitions/manager-approve/config.js","../src/components/popups/definitions/manager-approve/api.js","../src/components/popups/definitions/manager-reapprove/ManagerReapproveBody.jsx","../src/components/popups/definitions/manager-reapprove/config.js","../src/components/popups/definitions/manager-reapprove/api.js","../src/components/popups/definitions/reject/config.js","../src/components/popups/definitions/reject/api.js","../src/components/popups/definitions/index.js","../src/components/popups/AddBatchCandidatePopup.jsx","../src/components/popups/dynamic/DynamicPopupRoute.jsx","../src/components/popups/definitions/vendor-share/config.js","../src/components/popups/definitions/vendor-share/api.js","../src/components/popups/VendorShareDrawer.jsx","../src/components/form/validation.js","../src/components/form/forms.jsx","../src/pages/admin/AdminPageWithShell.jsx","../src/components/cards/StatsCards.jsx","../src/pages/Modules/Admin/UsersSection.jsx","../src/pages/Modules/Admin/TeamsSection.jsx","../src/pages/Modules/Admin/components/RolePermPanel.jsx","../src/pages/Modules/Admin/RolesSection.jsx","../src/pages/Modules/Admin/PermissionsPage.jsx","../src/components/cards/OnboardingCard.jsx","../src/pages/Modules/LegacyAdminPage.jsx","../src/pages/stickyNotesFullPage.jsx","../src/pages/BulkUpload/index.jsx","../src/services/dropdownValues/testPageValues.js","../src/pages/TestingPage/test-form.jsx","../src/pages/TestingPage/ZinnextTestForm.jsx","../src/pages/TestingPage/ManageModules.jsx","../src/pages/TestingPage/ManageSubmodules.jsx","../src/pages/TestingPage/ZinnextTableView.jsx","../src/pages/TestingPage/testHomePage.jsx","../src/pages/TestingPage/lms-test-form.jsx","../src/pages/TestingPage/lmsHomePage.jsx","../src/services/mergedListApi.js","../src/services/workflowModuleListApi.js","../src/index.js"],"sourcesContent":["import { apiGetWithAuth, ensureToken } from './authApi';\nimport { AUTH_URL, SUBMISSIONS_URL, JOBS_URL, CANDIDATES_URL } from './apiConfig';\n\nexport async function getJobSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n  const query = params.toString();\n  return apiGetWithAuth(JOBS_URL, `/job-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getCandidateSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n  const query = params.toString();\n  return apiGetWithAuth(CANDIDATES_URL, `/profile-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getSubmissionSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n  const query = params.toString();\n  return apiGetWithAuth(SUBMISSIONS_URL, `/profile-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getDashboardCards(\n  moduleName,\n  { method = 'POST', params = {}, body = {} } = {}\n) {\n  const token = await ensureToken();\n  const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` };\n\n  const search = new URLSearchParams({ moduleName });\n  Object.entries(params).forEach(([k, v]) => {\n    if (v !== undefined && v !== null && v !== '') search.append(k, String(v));\n  });\n\n  const options = { method, headers };\n  if (method === 'POST' || method === 'PUT') {\n    options.body = JSON.stringify(body ?? {});\n  }\n\n  const res = await fetch(`${AUTH_URL}/dashboard/cards?${search.toString()}`, options);\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  return res.json();\n}\n\nexport async function getDynamicCommonCount(payload = {}) {\n  const token = await ensureToken();\n  const res = await fetch(`${AUTH_URL}/dynamic-common-count`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n    body: JSON.stringify(payload),\n  });\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  return res.json();\n}\n\nexport async function getDashboardOnboardingCount(payload, limit = 10, offset = 0) {\n  const token = await ensureToken();\n  const res = await fetch(\n    `${SUBMISSIONS_URL}/dashboard-onboarding-count?offset=${offset}&limit=${limit}`,\n    {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n      body: JSON.stringify(payload),\n    }\n  );\n  const json = await res.json();\n  return json.data ?? json;\n}\n\nexport async function getDashboardCalendar(payload = {}) {\n  // This used to live on the submissions service; it is served by the auth\n  // backend now so the whole dashboard resolves its user scope through one\n  // hierarchy. Same request/response shape as before.\n  const token = await ensureToken();\n  const res = await fetch(`${AUTH_URL}/dashboard-calendar`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n    body: JSON.stringify(payload),\n  });\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  return res.json();\n}\n\n// The account's users nested by reporting manager, already scoped to what the\n// caller is allowed to see. Shape: { scope, selfUserId, totalCount, users[] }\n// where each user carries { userId, name, email, children[] }.\nexport async function getUserHierarchyTree() {\n  return apiGetWithAuth(AUTH_URL, '/users/hierarchy-tree');\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport {\n  Button,\n  Card,\n  Col,\n  Popover,\n  Row,\n  Spin,\n  Typography,\n  Tooltip,\n} from \"antd\";\nimport {\n  CalendarOutlined,\n  LeftOutlined,\n  RightOutlined,\n} from \"@ant-design/icons\";\nimport { getDashboardCalendar } from \"../../services/dashboardApi\";\n\nconst { Title, Text } = Typography;\n\nconst DAYS_SUN = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst DAYS_MON = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\nconst MONTHS = [\n  \"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\n  \"July\",\"August\",\"September\",\"October\",\"November\",\"December\",\n];\n\nconst DOT_COLORS = {\n  green: \"#22c55e\",\n  red: \"#ef4444\",\n  orange: \"#f97316\",\n  blue: \"#3b82f6\",\n};\n\nfunction resolveColor(color) {\n  return DOT_COLORS[color] || color || \"#586888\";\n}\n\nfunction pad(n) {\n  return String(n).padStart(2, \"0\");\n}\n\n/**\n * Build a flat array of cell descriptors for a calendar month.\n * startDay: 'Sun' (default, dashboard) | 'Mon' (timesheet / ISO week)\n * Filler cells have { day: null, cur: false }\n * Real cells have { day: <number>, cur: true }\n */\nfunction buildCells(year, month, startDay = \"Sun\") {\n  const rawDow     = new Date(year, month, 1).getDay(); // 0=Sun … 6=Sat\n  const offset     = startDay === \"Mon\" ? (rawDow === 0 ? 6 : rawDow - 1) : rawDow;\n  const daysInMonth = new Date(year, month + 1, 0).getDate();\n\n  const cells = [];\n  for (let i = 0; i < offset; i++) cells.push({ day: null, cur: false });\n  for (let d = 1; d <= daysInMonth; d++) cells.push({ day: d, cur: true });\n  while (cells.length % 7 !== 0) cells.push({ day: null, cur: false });\n  return cells;\n}\n\nfunction chunk(arr, size) {\n  const out = [];\n  for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));\n  return out;\n}\n\nfunction parseDescription(desc) {\n  if (!desc) return { text: \"\", author: null };\n  const m = desc.match(/\\n\\s*-\\s*([^\\n]+)\\s*$/);\n  if (m) return { text: desc.slice(0, m.index).trim(), author: m[1].trim() };\n  return { text: desc.trim(), author: null };\n}\n\nfunction buildEvents(days = []) {\n  const map = {};\n  days.forEach((day) => {\n    map[day.date] = (day.events || []).map((e) => {\n      const { text, author } = parseDescription(e.description);\n      return { color: e.color, label: e.label, title: e.title, text, author };\n    });\n  });\n  return map;\n}\n\nfunction EventsPopoverContent({ events }) {\n  return (\n    <div style={{ maxWidth: 280, maxHeight: 260, overflowY: \"auto\" }}>\n      {events.map((e, i) => (\n        <div\n          key={i}\n          style={{\n            display: \"flex\", gap: 8, padding: \"6px 0\",\n            borderBottom: i < events.length - 1 ? \"1px solid #f0f0f0\" : \"none\",\n          }}\n        >\n          <span\n            className=\"calendar-dot\"\n            style={{ background: resolveColor(e.color), marginTop: 6, flexShrink: 0 }}\n          />\n          <div style={{ minWidth: 0 }}>\n            <Text strong style={{ fontSize: 13, display: \"block\" }}>{e.title || e.label}</Text>\n            {e.text && (\n              <Text style={{ fontSize: 12, color: \"#555\", whiteSpace: \"pre-line\", wordBreak: \"break-word\" }}>\n                {e.text}\n              </Text>\n            )}\n            {e.author && (\n              <Text style={{ fontSize: 11, color: \"#999\", display: \"block\", marginTop: 2 }}>\n                — {e.author}\n              </Text>\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n/**\n * CalendarCard — dual-mode calendar component following the same isControlled\n * pattern as ListView.\n *\n * ── DASHBOARD / AUTO MODE (default — no config props needed) ─────────────────\n *   <CalendarCard userIds={[...]} />\n *   Fetches data via getDashboardCalendar(), renders coloured event dots + popover.\n *\n * ── CONTROLLED / CONFIG MODE (pass any of the config props) ─────────────────\n *   <CalendarCard\n *     days={flatDayArray}         // external day data; skips internal fetch\n *     startDay=\"Mon\"              // 'Sun' (default) | 'Mon' for ISO work week\n *     renderDayContent={fn}       // (dateKey, dayObj) => JSX; replaces dot render\n *     onDayClick={fn}             // (dateKey, dayObj) => void; replaces internal popover\n *     headerExtra={<JSX />}       // controls injected into card header (beside the month label)\n *     legend={[{label,color,icon}]} // overrides API-returned legend\n *     readonly={false}            // disables cell interaction\n *     className=\"my-class\"        // extra CSS class on the Card wrapper\n *     monthLabel=\"Jan 2026\"       // overrides auto-computed month label\n *     onPrevMonth={fn}            // external prev-month handler (replaces internal state)\n *     onNextMonth={fn}            // external next-month handler\n *   />\n *\n * Controlled mode is detected when `days` is not undefined OR `renderDayContent`\n * or `onDayClick` is provided — same isControlled pattern as ListView.\n */\nexport default function CalendarCard({\n  // ── dashboard (auto) props ──────────────────────────────────────────────────\n  userIds = [],\n\n  // ── config / controlled props ───────────────────────────────────────────────\n  days             = undefined,   // external day array → skips internal fetch\n  startDay         = \"Sun\",       // 'Sun' | 'Mon'\n  renderDayContent = undefined,   // (dateKey, dayObj) => JSX\n  onDayClick       = undefined,   // (dateKey, dayObj) => void\n  headerExtra      = undefined,   // JSX injected in header (next to the month label)\n  legend           = undefined,   // override legend; [{label, color, icon}]\n  readonly         = false,\n  className        = \"\",\n  monthLabel       = undefined,   // override displayed month+year label\n  year             = undefined,   // controlled grid year (use with `month`)\n  month            = undefined,   // controlled grid month 1-12 (use with `year`)\n  onPrevMonth      = undefined,   // external nav handler\n  onNextMonth      = undefined,\n  prevDisabled     = false,       // grey out + disable the Previous month button\n  nextDisabled     = false,       // grey out + disable the Next month button\n}) {\n  // isControlled: any config prop signals controlled mode (no internal fetch)\n  const isControlled = days !== undefined || renderDayContent !== undefined || onDayClick !== undefined;\n\n  const today  = new Date();\n  const [internalView, setInternalView] = useState({ year: today.getFullYear(), month: today.getMonth() });\n  // When the caller drives the month (year + month provided), the grid MUST follow\n  // it so the generated date-keys (e.g. \"2026-06-01\") match the `days` data. Without\n  // this the grid stays on the current month and every cell renders \"No log\".\n  const view = (year != null && month != null)\n    ? { year: Number(year), month: Number(month) - 1 }\n    : internalView;\n  const [events, setEvents]           = useState({});\n  const [apiLegend, setApiLegend]     = useState([]);\n  const [loading, setLoading]         = useState(false);\n  const [activePopover, setActivePopover] = useState(null);\n\n  const userKey = JSON.stringify(userIds);\n  const DAYS    = startDay === \"Mon\" ? DAYS_MON : DAYS_SUN;\n\n  // ── Internal data fetch (dashboard / auto mode only) ────────────────────────\n  const fetchData = useCallback(async () => {\n    setLoading(true);\n    try {\n      const res = await getDashboardCalendar({ userIds });\n      if (res?.status && res?.data) {\n        setApiLegend(res.data.legend || []);\n        setEvents(buildEvents(res.data.days || []));\n      } else {\n        setApiLegend([]);\n        setEvents({});\n      }\n    } catch (err) {\n      console.error(\"CalendarCard fetch error:\", err);\n    } finally {\n      setLoading(false);\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [userKey]);\n\n  useEffect(() => {\n    if (isControlled) return; // skip when caller manages data\n    fetchData();\n  }, [isControlled, fetchData]);\n\n  useEffect(() => {\n    window.addEventListener(\"dashboard-calendar:refresh\", fetchData);\n    return () => window.removeEventListener(\"dashboard-calendar:refresh\", fetchData);\n  }, [fetchData]);\n\n  // ── Navigation ──────────────────────────────────────────────────────────────\n  const handlePrev = onPrevMonth ?? (() =>\n    setInternalView((v) => v.month === 0 ? { year: v.year - 1, month: 11 } : { ...v, month: v.month - 1 })\n  );\n  const handleNext = onNextMonth ?? (() =>\n    setInternalView((v) => v.month === 11 ? { year: v.year + 1, month: 0 } : { ...v, month: v.month + 1 })\n  );\n\n  // ── Grid ────────────────────────────────────────────────────────────────────\n  const cells = buildCells(view.year, view.month, startDay);\n  const weeks  = chunk(cells, 7);\n\n  // Build dateKey → dayObj lookup from the external days array (controlled mode)\n  const externalDayMap = {};\n  if (days !== undefined) {\n    (days || []).forEach((d) => { if (d?.date) externalDayMap[d.date] = d; });\n  }\n\n  const displayLegend = legend ?? apiLegend;\n  const displayLabel  = monthLabel ?? `${MONTHS[view.month]} ${view.year}`;\n\n  return (\n    <Card\n      className={`calendar-card${className ? ` ${className}` : \"\"}`}\n      title={\n        <div className=\"calendar-header-title\">\n          <CalendarOutlined />\n          <Title level={5} style={{ margin: 0 }}>{displayLabel}</Title>\n          {/* headerExtra sits beside the month label, not the nav buttons — the\n              only current consumer (Timesheet's Select/Quick Log controls) reads\n              as part of \"what month am I acting on\", not calendar navigation. */}\n          {headerExtra}\n        </div>\n      }\n      extra={\n        <div className=\"calendar-nav\" style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n          <Tooltip title=\"Previous month\">\n            <Button type=\"text\" icon={<LeftOutlined />} size=\"small\" onClick={handlePrev} disabled={prevDisabled} />\n          </Tooltip>\n          <Tooltip title=\"Next month\">\n            <Button type=\"text\" icon={<RightOutlined />} size=\"small\" onClick={handleNext} disabled={nextDisabled} />\n          </Tooltip>\n        </div>\n      }\n    >\n      <Spin spinning={loading}>\n        {/* Day-name header row */}\n        <Row gutter={[6, 0]} className=\"calendar-day-names\">\n          {DAYS.map((d) => (\n            <Col key={d} flex=\"1\" className=\"calendar-day-name\">{d}</Col>\n          ))}\n        </Row>\n\n        {/* Calendar grid — one Row per week */}\n        <div className=\"calendar-weeks\">\n          {weeks.map((week, wi) => (\n            <Row key={wi} gutter={[6, 6]} align=\"top\" className=\"calendar-week-row\">\n              {week.map((cell, ci) => {\n                // ── Filler cell (prev/next month overflow) ─────────────────\n                if (!cell.cur || cell.day === null) {\n                  return (\n                    <Col key={ci} flex=\"1\">\n                      <div className=\"calendar-cell calendar-cell--filler\" />\n                    </Col>\n                  );\n                }\n\n                const dateKey = `${view.year}-${pad(view.month + 1)}-${pad(cell.day)}`;\n                const isToday =\n                  cell.day === today.getDate() &&\n                  view.month === today.getMonth() &&\n                  view.year === today.getFullYear();\n\n                // ── Controlled mode: delegate cell content to renderDayContent ─\n                if (isControlled) {\n                  const dayObj = externalDayMap[dateKey] ?? null;\n\n                  // If caller provides a full custom renderer, render it directly\n                  // in the Col without an extra wrapper (lets TimesheetDayCell\n                  // be the outermost element — same pattern as field.render in ListView)\n                  if (renderDayContent) {\n                    return (\n                      <Col key={ci} flex=\"1\">\n                        {renderDayContent(dateKey, dayObj, { isToday, readonly })}\n                      </Col>\n                    );\n                  }\n\n                  // Caller provided onDayClick but no custom renderer — show date\n                  // number in a clickable cell\n                  return (\n                    <Col key={ci} flex=\"1\">\n                      <div\n                        className={[\n                          \"calendar-cell\",\n                          isToday ? \"today\" : \"\",\n                          readonly ? \"calendar-cell--readonly\" : \"\",\n                        ].filter(Boolean).join(\" \")}\n                        onClick={() => !readonly && onDayClick?.(dateKey, dayObj)}\n                        style={{ cursor: readonly ? \"default\" : \"pointer\" }}\n                      >\n                        <div className=\"calendar-cell-inner\">\n                          <Text className=\"calendar-cell-number\">{cell.day}</Text>\n                        </div>\n                      </div>\n                    </Col>\n                  );\n                }\n\n                // ── Dashboard / auto mode: dots + popover ─────────────────\n                const dayEvents = events[dateKey] || [];\n                const dotColors = [...new Set(dayEvents.map((e) => e.color))].slice(0, 3);\n\n                return (\n                  <Col key={ci} flex=\"1\">\n                    <div className={`calendar-cell${isToday ? \" today\" : \"\"}`}>\n                      <div className=\"calendar-cell-inner\">\n                        <Text className=\"calendar-cell-number\">{cell.day}</Text>\n                        {dayEvents.length > 0 && (\n                          <Popover\n                            open={activePopover === dateKey}\n                            trigger=\"click\"\n                            content={<EventsPopoverContent events={dayEvents} />}\n                            placement=\"topRight\"\n                            destroyTooltipOnHide\n                            onOpenChange={(visible) =>\n                              setActivePopover(visible ? dateKey : null)\n                            }\n                          >\n                            <div className=\"calendar-cell-dots\">\n                              {dotColors.map((color, j) => (\n                                <span\n                                  key={j}\n                                  className=\"calendar-dot\"\n                                  style={{ background: resolveColor(color) }}\n                                />\n                              ))}\n                            </div>\n                          </Popover>\n                        )}\n                      </div>\n                    </div>\n                  </Col>\n                );\n              })}\n            </Row>\n          ))}\n        </div>\n\n        {/* Legend */}\n        {displayLegend.length > 0 && (\n          <div className=\"calendar-legend\">\n            {displayLegend.map(({ label, color, icon }) => (\n              <div key={label} className=\"calendar-legend-item\">\n                {icon\n                  ? <span className=\"calendar-legend-badge\" style={{ background: resolveColor(color) }}>{icon}</span>\n                  : <span className=\"calendar-legend-dot\" style={{ background: resolveColor(color) }} />\n                }\n                <Text>{label}</Text>\n              </div>\n            ))}\n          </div>\n        )}\n      </Spin>\n    </Card>\n  );\n}\n","import { Space, Tabs, Badge } from 'antd';\n\nfunction hasCount(count) {\n  return count !== null && count !== undefined;\n}\n\nfunction capitalizeFirstLetter(value) {\n  const label = String(value);\n\n  return label.charAt(0).toUpperCase() + label.slice(1);\n}\n\nfunction normalizeTab(tab, index) {\n  if (!tab || typeof tab !== 'object') return null;\n\n  const key = tab.key ?? tab.value ?? tab.id ?? String(index);\n  const title = tab.title ?? tab.tabTitle ?? tab.label ?? tab.name;\n  const count = tab.count ?? tab.countValue;\n\n  if (!key || !title) return null;\n\n  return {\n    ...tab,\n    key: String(key),\n    label: (\n      <Space size={6}>\n        <span>{capitalizeFirstLetter(title)}</span>\n        {hasCount(count) && (\n          <Badge\n            className=\"dynamic-tabs-count\"\n            count={count}\n            overflowCount={Number.MAX_SAFE_INTEGER}\n          />\n        )}\n      </Space>\n    ),\n  };\n}\n\nexport default function DynamicTabs({\n  tabs = [],\n  activeKey,\n  onChange,\n  className,\n  extra,\n}) {\n  const items = tabs\n    .map(normalizeTab)\n    .filter(Boolean);\n\n  if (!items.length) return null;\n\n  const selectedKey = items.some((tab) => tab.key === activeKey)\n    ? activeKey\n    : items[0].key;\n\n  return (\n    <Tabs\n      activeKey={selectedKey}\n      className={className}\n      items={items}\n      onChange={onChange}\n      tabBarExtraContent={extra}\n    />\n  );\n}\n","import { fetchJsonWithAuth, apiGetWithAuth } from './authApi';\nimport { AUTH_URL, CANDIDATES_URL, JOBS_URL, SUBMISSIONS_URL } from './apiConfig';\n\nfunction getTenantContext() {\n  return {\n    tenantId: localStorage.getItem('tenantId') || '',\n    businessId: localStorage.getItem('businessId') || '',\n    businessUnitId: localStorage.getItem('businessUnitId') || '',\n  };\n}\n\nfunction getUserId() {\n  return Number(localStorage.getItem('userId')) || 0;\n}\n\nconst unwrap = (json) => json?.data ?? json;\n\n// Assigned-user rows arrive from several Jobs endpoints in different shapes.\n// Some carry a recruiterName, some only first_name, and older records may carry\n// nothing but the numeric legacy user id. Resolve that id through Auth so both\n// Self Assign and Assign to Others show a person's name rather than an opaque\n// number. Requests are cached because both popups can ask for the same people.\nconst assignedUserNameCache = new Map();\n\nfunction assignedUserId(user) {\n  return user?.recruiterId\n    ?? user?.legacyUserId\n    ?? user?.user_id\n    ?? user?.userId\n    ?? user?.USER_ID\n    ?? user?.id\n    ?? user?._id;\n}\n\nfunction assignedUserDisplayName(user) {\n  if (!user || typeof user !== 'object') return '';\n  const firstName = user.first_name ?? user.firstName ?? user.FIRST_NAME;\n  const lastName = user.last_name ?? user.lastName ?? user.LAST_NAME;\n  return [firstName, lastName].filter(Boolean).join(' ').trim()\n    || user.recruiterName\n    || user.name\n    || user.user_name\n    || user.userName\n    || user.USER_NAME\n    || user.email\n    || '';\n}\n\nasync function fetchAssignedUserName(userId) {\n  const key = String(userId ?? '').trim();\n  if (!key) return '';\n  if (!assignedUserNameCache.has(key)) {\n    assignedUserNameCache.set(key,\n      fetchJsonWithAuth(AUTH_URL, `/get-detailed-view?userId=${encodeURIComponent(key)}`)\n        .then((json) => assignedUserDisplayName(json?.data ?? json ?? null))\n        .catch(() => ''),\n    );\n  }\n  return assignedUserNameCache.get(key);\n}\n\n// ── The user directory ───────────────────────────────────────────────────────\n// One fetch of everyone, indexed by EVERY id shape a job row might carry.\n//\n// The per-id lookup above answers only \"what is this person called\". Assigned\n// people are also shown with their ROLE and REPORTING MANAGER (the Self Assign\n// \"Team Members Allocated\" table), and nothing was ever populating those — so\n// both columns rendered \"-\" on every row, for every job. The directory carries\n// all three, so one request answers the whole table instead of N requests\n// answering a third of it.\n//\n// Cached for the session: the same people appear across Self Assign, Assign to\n// Others, and repeated opens of both.\nlet userDirectoryPromise = null;\n\nfunction indexUserDirectory(rows) {\n  const byId = new Map();\n  (Array.isArray(rows) ? rows : []).forEach((row) => {\n    const entry = {\n      name: assignedUserDisplayName(row),\n      role_name: row?.roleName ?? row?.role_name ?? '',\n      reporting_name: row?.reportingName ?? row?.reporting_name ?? '',\n    };\n    // A job stores whichever id its era used, so index them all rather than\n    // guessing which one this deployment writes.\n    [row?.userId, row?.user_id, row?.legacyUserId, row?.id, row?._id].forEach((id) => {\n      const key = String(id ?? '').trim();\n      if (key) byId.set(key, entry);\n    });\n  });\n  return byId;\n}\n\nfunction fetchUserDirectory() {\n  if (!userDirectoryPromise) {\n    userDirectoryPromise = fetchJsonWithAuth(AUTH_URL, '/get-all-users?limit=500&offset=0')\n      .then((json) => {\n        const payload = json?.data ?? json ?? {};\n        return indexUserDirectory(payload.users ?? payload ?? []);\n      })\n      // Best effort: a directory that will not load must not stop the popup —\n      // rows fall back to whatever the job row itself carries.\n      .catch(() => new Map());\n  }\n  return userDirectoryPromise;\n}\n\nasync function enrichAssignedUser(user) {\n  const id = assignedUserId(user);\n  const directory = await fetchUserDirectory();\n  const entry = directory.get(String(id ?? '').trim()) ?? {};\n  // Precedence matters and is easy to get backwards: a CURRENT name must beat\n  // the one the job stored, because a person who has since been renamed should\n  // not keep appearing under their old name. So it is bulk directory → per-id\n  // lookup → whatever the job row carried (deleted user / directory down).\n  const name = entry.name || (await fetchAssignedUserName(id)) || assignedUserDisplayName(user);\n  return {\n    ...user,\n    name,\n    role_name: entry.role_name || user?.role_name || user?.roleName || '',\n    reporting_name: entry.reporting_name || user?.reporting_name || user?.reportingName || '',\n  };\n}\n\n// ── Change Status ────────────────────────────────────────────────────────────\n\nexport async function changeModuleStatus(module, ids, status) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/module-data-update', {\n    method: 'PUT',\n    body: JSON.stringify({ module, ids, updates: { status } }),\n  });\n  return unwrap(json);\n}\n\n// ── Delete ───────────────────────────────────────────────────────────────────\n\n// One common delete for EVERY module — the same DB-driven gateway that already\n// serves add/edit. The gateway is storage-aware: it soft-deletes a mongo-storage\n// module in place, or proxies to a proxy-module's downstream delete endpoint\n// (jobs/candidates/…) using that module's configured gateway.deletePath — so\n// there is no hardcoded per-module routing here anymore. Role gating is handled\n// upstream by the action's delete permission (canDelete) before this runs.\nexport async function deleteModuleRecords(module, ids) {\n  const list = Array.isArray(ids) ? ids : [ids];\n  const results = await Promise.all(\n    list\n      .filter(Boolean)\n      .map((id) =>\n        fetchJsonWithAuth(\n          AUTH_URL,\n          `/module/delete/${encodeURIComponent(id)}?module=${encodeURIComponent(module)}`,\n          { method: 'DELETE' },\n        ),\n      ),\n  );\n  return results[results.length - 1] ?? {};\n}\n\n// ── Job search (shared by quick-submit and tag-to-job) ───────────────────────\n\nexport async function searchJobs(searchQuery) {\n  const json = await fetchJsonWithAuth(JOBS_URL, '/joblist', {\n    method: 'POST',\n    body: JSON.stringify({\n      ...getTenantContext(),\n      searchQuery,\n      userId: getUserId(),\n    }),\n  });\n  return unwrap(json);\n}\n\n// ── Quick Submit ─────────────────────────────────────────────────────────────\n\nexport async function searchCandidatesForSubmit(jobId, search = '') {\n  const json = await fetchJsonWithAuth(CANDIDATES_URL, '/quicksubmit/list', {\n    method: 'POST',\n    body: JSON.stringify({ jobId, search }),\n  });\n  return unwrap(json);\n}\n\nexport async function quickSubmitCandidate({ jobId, candidateId }) {\n  const json = await fetchJsonWithAuth(SUBMISSIONS_URL, '/review', {\n    method: 'POST',\n    body: JSON.stringify({\n      ...getTenantContext(),\n      jobId,\n      candidateId: Array.isArray(candidateId) ? candidateId : [candidateId],\n    }),\n  });\n  return unwrap(json);\n}\n\n// ── Add Notes & Share ─────────────────────────────────────────────────────────\n\nexport async function getMentionUsers(search = '') {\n  const params = search ? `?search=${encodeURIComponent(search)}` : '';\n  return apiGetWithAuth(JOBS_URL, `/users/any${params}`);\n}\n\n// Note: `mentionedUsers` (usernames parsed out of the '@mention' text) is\n// intentionally not sent — the backend's NotesMaster.receiver field is a\n// single numeric user id, not a list of usernames, so forwarding it always\n// fails unmarshaling (\"cannot unmarshal string into ... of type int\").\nexport async function addStickyNote({ relatedIds, module, title, targetDate, notes }) {\n  return fetchJsonWithAuth(JOBS_URL, '/notes', {\n    method: 'POST',\n    body: JSON.stringify({\n      schemaVersion: 1,\n      ...getTenantContext(),\n      title,\n      notes,\n      notesFor: module || 'general',\n      // The backend expects an ObjectID or null here, not an empty array —\n      // a plain dashboard note (no selected row) has nothing to relate to.\n      notesRelatedId: Array.isArray(relatedIds) && relatedIds.length ? relatedIds : null,\n      // An empty-string reminder time fails backend time parsing — omit the\n      // whole object (like a null target date) instead of sending \"\".\n      reminder: targetDate ? { type: 'single', time: targetDate, interval: '' } : null,\n      targetDate: targetDate || null,\n    }),\n  });\n}\n\n// PUT /notes/{id} → update an existing sticky note's title/notes/reminder.\nexport async function updateStickyNote(noteId, { title, targetDate, notes }) {\n  return fetchJsonWithAuth(JOBS_URL, `/notes/${encodeURIComponent(noteId)}`, {\n    method: 'PUT',\n    body: JSON.stringify({\n      title,\n      notes,\n      reminder: targetDate ? { type: 'single', time: targetDate, interval: '' } : null,\n      targetDate: targetDate || null,\n    }),\n  });\n}\n\n// PUT /notes/{id}/resolve → mark a sticky note resolved.\nexport async function resolveStickyNote(noteId) {\n  return fetchJsonWithAuth(JOBS_URL, `/notes/${encodeURIComponent(noteId)}/resolve`, {\n    method: 'PUT',\n  });\n}\n\n// ── Tag to Job ────────────────────────────────────────────────────────────────\n\nexport async function tagCandidatesToJob({ jobId, candidateIds, hiringStage }) {\n  return fetchJsonWithAuth(JOBS_URL, '/source/hiringStgUpdate', {\n    method: 'PUT',\n    body: JSON.stringify({\n      ...getTenantContext(),\n      multiJobId: Array.isArray(jobId) ? jobId : [jobId],\n      applicantId: Array.isArray(candidateIds) ? candidateIds : [candidateIds],\n      updateStatus: String(hiringStage ?? '').toLowerCase(),\n      updateStatusType: 'call',\n      responseType: 'responded',\n      hiriringStatusChangeType: 'tagToJobs',\n      comments: '',\n      userId: getUserId(),\n    }),\n  });\n}\n\n// ── Add to Groups ─────────────────────────────────────────────────────────────\n\nexport async function getCandidateGroups() {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    '/masters/dropdown?masterName=candidateGroups&offset=0&limit=50',\n  );\n  return unwrap(json);\n}\n\nexport async function addCandidatesToGroup({ candidateIds, groupId, groupName }) {\n  const json = await fetchJsonWithAuth(CANDIDATES_URL, '/actions/update-group', {\n    method: 'PUT',\n    body: JSON.stringify({ candidateIds, groupId, groupName }),\n  });\n  return unwrap(json);\n}\n\n// ── Self Assign ───────────────────────────────────────────────────────────────\n\nexport async function selfAssignJob({ jobIds, rate, priority }) {\n  return fetchJsonWithAuth(JOBS_URL, '/assign?type=self', {\n    method: 'PUT',\n    body: JSON.stringify({\n      multiJobId: Array.isArray(jobIds) ? jobIds : [jobIds],\n      userId: getUserId(),\n      schemaVersion: 1,\n      ...getTenantContext(),\n      // jobPayDetails: rate ?? {},\n    priority: priority != null ? String(priority) : \"false\",\n      priorityFrom: null,\n      recruitersData: [],\n    }),\n  });\n}\n\n// Self-assign confirmation info — the same GET /self-assign the old Jobs\n// SelfAssignPopup used to decide between \"Are you sure?\" and the \"Team Members\n// Allocated\" table. Returns { assignedUsers, totalSubmissions, targetSubmissions,\n// message } with the API envelope's `message` preserved (apiGetWithAuth would\n// drop it by unwrapping `.data`, so this reads the raw envelope). When a job has\n// no submissions the backend returns `data: []` + the confirmation message.\nexport async function getSelfAssignInfo(jobId) {\n  if (!jobId) return { assignedUsers: [], totalSubmissions: 0, targetSubmissions: 0, message: '' };\n  const json = await fetchJsonWithAuth(JOBS_URL, `/self-assign?jobId=${encodeURIComponent(jobId)}`);\n  const data = json?.data;\n  const message = json?.message ?? '';\n  if (Array.isArray(data)) {\n    const assignedUsers = await Promise.all(data.map(enrichAssignedUser));\n    return { assignedUsers, totalSubmissions: 0, targetSubmissions: 0, message };\n  }\n  if (!data || typeof data !== 'object') {\n    return { assignedUsers: [], totalSubmissions: 0, targetSubmissions: 0, message };\n  }\n  const assignedUsers = await Promise.all(\n    (Array.isArray(data.assignedUsers) ? data.assignedUsers : []).map(enrichAssignedUser),\n  );\n  return {\n    assignedUsers,\n    totalSubmissions: data.totalSubmissions ?? 0,\n    targetSubmissions: data.targetSubmissions ?? 0,\n    message,\n  };\n}\n\n// ── Others Assign ─────────────────────────────────────────────────────────────\n\nexport function normalizeAssignableUser(user) {\n  const rawId = user?.user_id\n    ?? user?.userId\n    ?? user?.USER_ID\n    ?? user?.legacyUserId\n    ?? user?.id\n    ?? user?._id;\n  const value = rawId === undefined || rawId === null ? '' : String(rawId).trim();\n  if (!value) return null;\n\n  const fullName = [user?.first_name ?? user?.firstName, user?.last_name ?? user?.lastName]\n    .filter(Boolean)\n    .join(' ')\n    .trim();\n  const label = user?.name\n    || user?.user_name\n    || user?.userName\n    || user?.USER_NAME\n    || fullName\n    || user?.email\n    || value;\n\n  return { ...user, label: String(label), value };\n}\n\nexport async function getAssignableUsers() {\n  const data = await apiGetWithAuth(JOBS_URL, '/users/manager');\n  const users = Array.isArray(data) ? data : (data ? [data] : []);\n  return users.map(normalizeAssignableUser).filter(Boolean);\n}\n\n// Already-assigned recruiters for the others-assign popup. The old Jobs\n// AssignPopup sourced this from GET /pay-details/{id} (job.recruiters), which\n// reliably returns the assigned recruiters regardless of submission count —\n// unlike /self-assign, whose `assignedUsers` only appears once a job has\n// submissions. Normalizes into `recruitersData` [{ recruiterId, id, user_id,\n// name }] so both PopupFields (reads user_id/id + name) and\n// buildOtherAssignmentPayload (reads recruiterId) work off one shape.\nexport async function getJobAssignedRecruiters(jobId) {\n  if (!jobId) return { recruitersData: [] };\n  const data = await apiGetWithAuth(JOBS_URL, `/pay-details/${encodeURIComponent(jobId)}`);\n  const recruiters = data && typeof data === 'object' && Array.isArray(data.recruiters)\n    ? data.recruiters\n    : [];\n  const recruitersData = (await Promise.all(recruiters\n    .map(async (r) => {\n      const id = r?.recruiterId ?? r?.user_id ?? r?.userId ?? r?.id;\n      if (id === undefined || id === null || id === '') return null;\n      // ALWAYS enrich, even when the row already carries a name. Skipping\n      // enrichment for named rows is what left Role and Reporting blank on\n      // every \"Team Members Allocated\" row: the job stores a name but never a\n      // role or a reporting manager, so the columns had nothing to render and\n      // showed \"-\". The directory is fetched once and cached, so enriching\n      // every row costs the same as enriching one.\n      const enriched = await enrichAssignedUser({ ...r, recruiterId: id });\n      return {\n        recruiterId: id,\n        id,\n        user_id: id,\n        name: enriched.name,\n        role_name: enriched.role_name ?? enriched.roleName ?? '',\n        reporting_name: enriched.reporting_name ?? enriched.reportingName ?? '',\n      };\n    })))\n    .filter(Boolean);\n  return { ...(data && typeof data === 'object' ? data : {}), recruitersData };\n}\n\nexport function toAssignmentUserId(userId) {\n  const numericUserId = Number(userId);\n  if (!Number.isInteger(numericUserId) || numericUserId <= 0) {\n    throw new Error('A valid user must be selected before assigning the job');\n  }\n  return numericUserId;\n}\n\nfunction toRecruiterId(recruiter) {\n  const rawId = typeof recruiter === 'object'\n    ? recruiter?.recruiterId ?? recruiter?.user_id ?? recruiter?.userId ?? recruiter?.id\n    : recruiter;\n  const id = Number(rawId);\n  return Number.isInteger(id) && id > 0 ? id : null;\n}\n\nexport function buildOtherAssignmentPayload({\n  jobIds,\n  userId,\n  rate,\n  priority,\n  removedIds,\n  existingRecruiters,\n}) {\n  const removed = new Set((removedIds ?? []).map(String));\n  const existing = (existingRecruiters ?? [])\n    .map(toRecruiterId)\n    .filter((id) => id !== null && !removed.has(String(id)));\n\n  // userId may now be an ARRAY (multi-select \"Assign to\") or a single value.\n  // Every selected recruiter is folded into recruitersData — the backend's\n  // ResolveAssignmentRecruiterIDs unions userId + recruitersData, so putting them\n  // all here assigns everyone at once. userId keeps the first selected for the\n  // single-value field / notifications.\n  const selected = (Array.isArray(userId) ? userId : [userId])\n    .map(toRecruiterId)\n    .filter((id) => id !== null);\n  // A removal-only submit is legitimate — the user took somebody off the job\n  // and added nobody. This used to throw, which (together with the popup's\n  // disabled OK button) made removal impossible to save at all. assignJobToOthers\n  // only calls this when there IS something to add, so reaching here with an\n  // empty selection means a genuinely empty request.\n  if (selected.length === 0) {\n    throw new Error('A valid user must be selected before assigning the job');\n  }\n\n  const recruitersData = Array.from(new Set([...existing, ...selected]));\n\n  return {\n    multiJobId: Array.isArray(jobIds) ? jobIds : [jobIds],\n    userId: selected[0],\n    schemaVersion: 1,\n    ...getTenantContext(),\n    // jobPayDetails: rate ?? {},\n    priority: String(priority ?? false),\n    priorityFrom: '',\n    recruitersData,\n  };\n}\n\n// removeJobRecruiters — takes recruiters OFF a job.\n//\n// The Jobs service's PUT /assign?type=other cannot do this. Proven against the\n// live service: it MERGES `recruitersData` into the job's existing recruiters\n// (send [14,149,145] for a job holding [14,149,145,74] and 74 survives), and it\n// rejects a userId that is already assigned (\"Job Already Assigned is\n// recruiter\"). No payload shape expresses a removal, and that service's source\n// is not in this repo.\n//\n// The Be_Auth gateway CAN: PATCH /module/update/{id} writes the `recruiters`\n// array verbatim — a true replace — and the jobs-assign platform workflows\n// recompute `assignedUserIds` (assignee + reporting chain) off it afterwards,\n// so My Jobs stays correct without any extra call.\n//\n// The remaining recruiters are taken from the job RECORD, not rebuilt from the\n// popup's rows: the popup only carries {recruiterId, name}, so reconstructing\n// the array here would silently drop each survivor's email and assignedDateTime.\nasync function removeJobRecruiters(jobIds, removedIds) {\n  const removed = new Set((removedIds ?? []).map(String));\n  if (!removed.size) return;\n\n  await Promise.all((jobIds ?? []).map(async (jobId) => {\n    const listed = await fetchJsonWithAuth(\n      AUTH_URL,\n      `/module/list?module=jobs&id=${encodeURIComponent(jobId)}`,\n    );\n    const payload = listed?.data?.data ?? listed?.data ?? listed;\n    const record = Array.isArray(payload) ? payload[0] : payload;\n    const current = Array.isArray(record?.recruiters) ? record.recruiters : [];\n    const kept = current.filter((r) => !removed.has(String(toRecruiterId(r) ?? '')));\n    // Nothing actually matched — don't issue a write that would rewrite the\n    // array to itself and stamp a spurious audit entry.\n    if (kept.length === current.length) return;\n    await fetchJsonWithAuth(AUTH_URL, `/module/update/${encodeURIComponent(jobId)}?module=jobs`, {\n      method: 'PATCH',\n      body: JSON.stringify({ recruiters: kept }),\n    });\n  }));\n}\n\nexport async function assignJobToOthers(params) {\n  const jobIds = Array.isArray(params?.jobIds) ? params.jobIds : [params?.jobIds].filter(Boolean);\n  const removedIds = params?.removedIds ?? [];\n  const selected = (Array.isArray(params?.userId) ? params.userId : [params?.userId])\n    .map(toRecruiterId)\n    .filter((id) => id !== null);\n\n  // ADDITIONS go through the Jobs service so its side effects (assignment\n  // notifications, recruiter records) still happen. Only run it when there is\n  // something to add: it errors on an already-assigned user, so a removal-only\n  // submit must not touch it.\n  let result;\n  if (selected.length > 0) {\n    result = await fetchJsonWithAuth(JOBS_URL, '/assign?type=other', {\n      method: 'PUT',\n      body: JSON.stringify(buildOtherAssignmentPayload(params)),\n    });\n  }\n\n  // REMOVALS afterwards, so the authoritative final list is written last and\n  // the add call's merge cannot resurrect somebody the user just took off.\n  await removeJobRecruiters(jobIds, removedIds);\n  return result;\n}\n\n// ── Move to Onboarding ────────────────────────────────────────────────────────\n\nexport async function moveToOnboarding({ submissionId, isMail = false }) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/submissions/move-to-onboarding', {\n    method: 'POST',\n    body: JSON.stringify({ submissionId, isMail: !!isMail }),\n  });\n  return unwrap(json);\n}\n\n// ── Approve Rate ──────────────────────────────────────────────────────────────\n\nexport async function approveSubmission(submissionId, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/submissions/approve', {\n    method: 'POST',\n    body: JSON.stringify({ submissionId, ...payload }),\n  });\n  return unwrap(json);\n}\n\nexport async function getVMSApprove(submissionId) {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    `/submissions/vms-approve?submissionId=${encodeURIComponent(submissionId)}`,\n  );\n  return unwrap(json);\n}\n\n// sendSubmissionForCfoApproval — re-submits a workforce engagement to the CFO\n// (POST SUBMISSIONS_URL /workforce-engagements/{id}/cfo-approval/send), the\n// same endpoint the Onboarding page's \"Send for Approval\" uses. Used by the\n// submission-manager Re-Approve popup after a CFO rejection: the manager fixes\n// the proposed rate and re-sends it for CFO review. billRate = proposed rate,\n// payRate = employer/candidate-accepted rate. The backend requires\n// proposedRate, candidateRate and a valid approvalUrl.\n// `rateUnit` is the unit the recruiter actually chose, resolved by the finance\n// engine off the submission (falling back to the job's). It used to be hardcoded\n// to 'hr' here, which meant a monthly/yearly engagement was sent to the CFO\n// described as hourly — the rate NUMBER was right and its unit was wrong, so the\n// request read as a wildly different amount of money. Defaulted to 'hr' so\n// existing callers that don't pass it keep their previous behaviour.\nexport async function sendSubmissionForCfoApproval(engagementId, {\n  submissionId = '',\n  billRate, payRate, currency = '$', rateUnit = 'hr', referralId, referralRate, referralType, referralEnabled, vmsPercent = 0, documentIds = [], remarks = null,\n} = {}) {\n  const targetPath = engagementId\n    ? `/workforce-engagements/${encodeURIComponent(engagementId)}/cfo-approval/send`\n    : `/submissions/${encodeURIComponent(submissionId)}/cfo-approval/send`;\n  if (!engagementId && !submissionId) {\n    throw new Error('Submission is required to send for approval.');\n  }\n  const origin = typeof window !== 'undefined' ? window.location.origin : '';\n  const approvalTargetId = engagementId || submissionId;\n  const json = await fetchJsonWithAuth(\n    SUBMISSIONS_URL,\n    targetPath,\n    {\n      method: 'POST',\n      body: JSON.stringify({\n        proposedRate: {\n          candidateProposedRate: Number(billRate) || 0,\n          candidateProposedRateCurrency: currency,\n          candidateProposedRateCurrencySymbol: '',\n          candidateProposedRateUnit: rateUnit,\n        },\n        candidateRate: {\n          candidateAcceptedRate: Number(payRate) || 0,\n          candidateAcceptedCurrency: currency,\n          candidateAcceptedCurrencySymbol: '',\n          candidateAcceptedPayUnit: rateUnit,\n          candidateAcceptedRateNegotiable: false,\n        },\n        // Omit referralRate during manager re-approval unless the caller\n        // intentionally supplies it. Sending 0 would erase the referral\n        // entered earlier by the onboarding team.\n        ...(referralId !== undefined && referralId !== null && referralId !== ''\n          ? { referralId }\n          : {}),\n        ...(referralRate !== undefined && referralRate !== null\n          ? { referralRate: Number(referralRate) || 0 }\n          : {}),\n        ...(referralType !== undefined && referralType !== null && referralType !== ''\n          ? { referralType }\n          : {}),\n        ...(referralEnabled !== undefined && referralEnabled !== null\n          ? { referralEnabled: Boolean(referralEnabled) }\n          : {}),\n        vmsPercent: Number(vmsPercent) || 0,\n        documentIds,\n        remarks,\n        approvalUrl: `${origin}/cfo-approval/${encodeURIComponent(approvalTargetId)}`,\n      }),\n    },\n  );\n  return unwrap(json);\n}\n\n// ── Reject ────────────────────────────────────────────────────────────────────\n\nexport async function rejectSubmission({ submissionId, rejectReasonId, rejectReason, rejectReasonComments }) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/submissions/reject', {\n    method: 'POST',\n    body: JSON.stringify({ submissionId, rejectReasonId, rejectReason, rejectReasonComments }),\n  });\n  return unwrap(json);\n}\n\n// Reports whether a candidate already has a (non-deleted) submission for a job,\n// so Quick Submit can block a duplicate before starting a fresh submission.\n// Returns { exists, submissionId? }.\nexport async function checkSubmissionExists({ jobId, applicantId }) {\n  const params = new URLSearchParams({ jobId: String(jobId ?? ''), applicantId: String(applicantId ?? '') });\n  const json = await fetchJsonWithAuth(AUTH_URL, `/submissions/exists?${params.toString()}`);\n  return unwrap(json) ?? { exists: false };\n}\n\n// Quick Submit dropdown searches, served by the Auth gateway. Unlike the\n// Jobs/Candidates microservice list endpoints — which scope results to the\n// LOGGED-IN USER (jobs: only where the user is a hiringProgress recruiter;\n// candidates: only createdBy the user unless the role has view-all) and so\n// return NOTHING for any other user — these are tenant-scoped, so every user\n// of the tenant can search its jobs and candidates. Each row also carries\n// disable/alreadySubmitted/submissionId so duplicates are flagged in the same\n// round trip.\nexport async function searchQuickSubmitJobs({ searchQuery, candidateId }) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/quick-submit/job-search', {\n    method: 'POST',\n    body: JSON.stringify({ searchQuery: searchQuery ?? '', candidateId: candidateId ? String(candidateId) : '' }),\n  });\n  const list = unwrap(json);\n  return Array.isArray(list) ? list : [];\n}\n\nexport async function searchQuickSubmitCandidates({ search, jobId }) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/quick-submit/candidate-search', {\n    method: 'POST',\n    body: JSON.stringify({ search: search ?? '', jobId: jobId ? String(jobId) : '' }),\n  });\n  const list = unwrap(json);\n  return Array.isArray(list) ? list : [];\n}\n\n// Batched form of checkSubmissionExists: given one anchor id and the list of\n// ids on the other side, returns which pairs already have a submission. Used to\n// mark/disable already-submitted rows in the Quick Submit dropdowns (both\n// directions) BEFORE the user picks one.\n//\n// Pass either { jobId, applicantIds } or { applicantId, jobIds }.\n// Returns a Map keyed by the *other* side's id → { submissionId, submittedAt }.\nexport async function checkSubmissionsExistBulk({ jobId, applicantId, jobIds, applicantIds }) {\n  const anchoredOnJob = !!jobId;\n  const body = {};\n  if (jobId) body.jobId = String(jobId);\n  if (applicantId) body.applicantId = String(applicantId);\n  if (Array.isArray(jobIds)) body.jobIds = jobIds.filter(Boolean).map(String);\n  if (Array.isArray(applicantIds)) body.applicantIds = applicantIds.filter(Boolean).map(String);\n\n  const otherIds = anchoredOnJob ? body.applicantIds : body.jobIds;\n  if (!otherIds?.length) return new Map();\n\n  const json = await fetchJsonWithAuth(AUTH_URL, '/submissions/exists-bulk', {\n    method: 'POST',\n    body: JSON.stringify(body),\n  });\n  const pairs = unwrap(json)?.pairs ?? [];\n  return new Map(\n    pairs.map((pair) => [\n      String(anchoredOnJob ? pair.applicantId : pair.jobId),\n      { submissionId: pair.submissionId ?? '', submittedAt: pair.submittedAt ?? null },\n    ]),\n  );\n}\n\n// ── Remove from Shortlist ─────────────────────────────────────────────────────\n\nexport async function removeFromShortlist({ jobId, candidateIds }) {\n  return fetchJsonWithAuth(JOBS_URL, '/source/hiringStgUpdate', {\n    method: 'PUT',\n    body: JSON.stringify({\n      ...getTenantContext(),\n      multiJobId: Array.isArray(jobId) ? jobId : [jobId],\n      applicantId: Array.isArray(candidateIds) ? candidateIds : [candidateIds],\n      updateStatus: 'pipeline',\n      updateStatusType: 'call',\n      responseType: 'responded',\n      hiriringStatusChangeType: 'tagToJobs',\n      comments: '',\n      userId: getUserId(),\n    }),\n  });\n}\n","export const DASHBOARD_VISIBLE_CARDS = {\n  jobsCount: [\n    'total',\n    'Total Jobs',\n    'active',\n    'Active Jobs',\n    'myAssignedCount',\n    'My Jobs',\n  ],\n  submissionCount: [\n    'Selected',\n    'Submitted to client',\n    'Submitted to Client',\n    'Not Submitted',\n    'Approved',\n  ],\n  // onboardingCount: [\n  //   'inProgress',\n  //   'In Progress',\n  //   'hired',\n  //   'Hired',\n  //   'projectCompleted',\n  //   'Project Completed',\n  //   'archive',\n  //   'Archive',\n  // ],\n};\n\nexport function visibleCardsFor(moduleName) {\n  return DASHBOARD_VISIBLE_CARDS[moduleName] ?? null;\n}\n","import dayjs from 'dayjs';\nimport { visibleCardsFor } from './dashboardVisibleCards';\n\n/*\n  ════════════════════════════════════════════════════════════════════════════\n  cardConfig.js — the ONLY file you edit to add / tweak a dashboard widget.\n  ════════════════════════════════════════════════════════════════════════════\n  <DynamicCards moduleName=\"stickyNotes\" /> looks the module up here, calls the\n  common Auth endpoint (/dashboard/cards?moduleName=...), and renders the LIVE\n  response with this config. Pass ONLY the moduleName from the page.\n  (The page may also pass `title` to override the heading below.)\n\n  Each entry:\n    title    -> heading above the section (page `title` prop overrides it)\n    variant  -> 'sticky'     : sticky-note cards (needs the *Key field map below)\n                'counts'     : one stat card per number in the response object\n                'submission' : \"Total Client Submission\" look — a header total\n                               + one progress bar per number (totalKey/infoText)\n                'list'       : stat cards from an array (uses titleKey/countKey/…)\n                'metrics'    : plain label/value rows in one card (optional header\n                               badge via `headerExtra`); pass an ARRAY as staticData\n                               to switch it to one row per array item (`listRows`)\n                'bars'       : full-width solid-colour rows, label left, value right\n    request  -> how to call the gateway:\n                  method 'GET' | 'POST'\n                  params { limit, offset, type, … }  -> query string\n                  body   { … }                       -> JSON body (POST only)\n    listPath -> dot-path to the data inside the API response:\n                  'data.data' -> array (sticky/list) ; 'data' -> counts object\n\n  Field map (sticky/list): every key OPTIONAL, [a, b] joins two fields.\n  'counts' needs no field map — it auto-labels each number in the response.\n\n  ──────────────────────────────────────────────────────────────────────────\n  CUSTOMISE EACH CARD (all optional, work on every variant)\n  ──────────────────────────────────────────────────────────────────────────\n  Every card has a NAME:\n    • counts / submission -> the humanized label   ('inProgress' -> 'In Progress')\n    • sticky              -> the value of `colorBy` (e.g. the `status` text)\n    • list                -> the first titleKey value\n\n  color    -> base color for ALL cards in the section:\n                omit          -> plain (counts) / auto-cycle (sticky)\n                'auto'        -> a different palette color per card\n                'green'       -> that one fixed color for every card\n\n  colorMap -> per-card color BY NAME (overrides `color`), case-insensitive:\n                colorMap: { 'In Progress': 'purple', Hired: 'green', Rejected: 'red' }\n              Submission bars accept a palette name OR a raw hex ('#0ea5e9').\n              counts / submission: the NAME may be the RAW API key\n              ('pendingSubmissionCount') OR the humanized label ('Pending Submission Count').\n\n  labelMap -> (counts / submission) rename a card's displayed text. Key by the\n              raw API name OR the humanized label:\n                labelMap: { pendingSubmissionCount: 'Pending', submittedToClientCount: 'Submitted' }\n\n  colorBy  -> (sticky) which API field the colorMap/hide names come from:\n                colorBy: 'status'  +  colorMap: { Pending: 'peach', Done: 'green' }\n\n  hide     -> drop specific cards. Each entry is EITHER:\n                a name   (string)  -> hides the card with that name (case-insensitive;\n                                      counts/submission match the raw key OR the label)\n                an index (number)  -> hides the card at that 0-based position\n                hide: ['Rejected', 0]\n\n  ──────────────────────────────────────────────────────────────────────────\n  ALIGNMENT & COUNT\n  ──────────────────────────────────────────────────────────────────────────\n  layout   -> 'COLSxROWS' — sets columns AND caps the count to cols*rows:\n                '4x2' -> 4 across, max 8 cards   '3x3' -> 3 across, max 9\n                '2x4' -> 2 across, max 8 cards\n  columns  -> just the column count, no cap (e.g. columns: 3).\n  maxCount -> just a hard cap on the number of cards, keeps current columns.\n              (explicit columns/maxCount win over whatever `layout` implies.)\n              Defaults: counts/list = 4 cols, sticky = 2 cols, submission = 1.\n\n  Palette color names (defined in PALETTE / dynamicCard.css):\n                blue green purple peach red gray\n  (sticky + counts use these as CSS classes; submission uses them as bar colors.)\n\n  EVERYTHING above is also overridable per-placement from the page:\n    <DynamicCards moduleName=\"jobsCount\" title=\"Jobs\" layout=\"4x2\" />\n*/\nexport const MODULE_CONFIG = {\n  stickyNotes: {\n    title: \"Sticky Notes\",\n    variant: \"sticky\",\n    request: { method: \"GET\", params: { limit: 20, offset: 0 } },\n    listPath: \"data.data\",\n    // Where the sticky-note \"View all\" link navigates to (omit to hide it).\n    maxCount: 4,\n    viewAllUrl: \"/viewall-sticky\",\n    // Dispatched (window.dispatchEvent(new Event(...))) by the add-note popup\n    // on a successful save; ModuleCards listens for it and refetches, since\n    // closing the popup returns to this same mounted component (no remount).\n    refreshEvent: \"sticky-notes:refresh\",\n    pillKey: \"status\",\n    headingKey: \"title\",\n    bodyKey: \"notes\",\n    // Notes sit in a fixed-height card; the body is clamped to this many lines\n    // with an ellipsis. Hovering a CLIPPED note shows the full text in a popover\n    // (notes that fit show no popover). 2–6 supported (see dynamicCard.css).\n    bodyLines: 3,\n    footerLeftKey: \"createdByName\",\n    footerRightKey: \"createdAt\",\n    dateKey: \"reminder.time\",\n    // Colour each note from its `status` value (falls back to the auto cycle\n    // for any status not listed here). Edit the names to match your API.\n    colorBy: \"status\",\n    colorMap: {\n      Note: \"green\",\n      Tagged: \"red\",\n    },\n    color: \"auto\",\n    // hide: ['Archived'],   // e.g. hide notes whose status is 'Archived'\n  },\n\n  jobsCount: {\n    variant: \"counts\",\n    dynamicCommonCount: {\n      module: \"jobs\",\n      keys: [\"jobRecruitmentStatus\", \"jobStatus\"],\n    },\n    listPath: \"\",\n    layout: \"4x2\",\n    groupSeparator: \"\",\n    labelMap: {\n      total: \"Total Jobs\",\n      active: \"Active Jobs\",\n      myAssignedCount: \"My Jobs\",\n    },\n    color: \"#f1f3f8\",\n    show: visibleCardsFor(\"jobsCount\"),\n    hide: [\"inactive\", \"submitted\", \"noSubmissions\"],\n  },\n\n  // Rendered as the \"Total Client Submission\" card: one header total + a\n  // horizontal progress bar per number in the response (ClientSubmissionCard look).\n  submissionCount: {\n    title: \"Total Client Submission\",\n    tooltipText:\n      \"Includes all submissions that are pending and submitted to the client.\",\n    variant: \"submission\",\n    dynamicCommonCount: {\n      module: \"submissions\",\n      keys: [\"clientSubmissionStatus.clientSubmissionStatusText\"],\n    },\n    listPath: \"\",\n    // 'total' key is preserved in the flat object from the dashboard conversion.\n    totalKey: \"total\",\n    labelMap: {\n      Selected: \"Selected\",\n      \"Submitted to client\": \"Submitted to Client\",\n      \"Not Submitted\": \"Not Submitted\",\n      Approved: \"Approved\",\n    },\n    colorMap: {\n      Selected: \"rgb(234, 175, 12)\",\n      \"Submitted to client\": \"green\",\n      \"Not Submitted\": \"red\",\n      Approved: \"#1d4ed8\",\n    },\n    show: visibleCardsFor(\"submissionCount\"),\n  },\n\n  leadAptitude: {\n    title: \"Aptitude Test Results\",\n    variant: \"assessment\",\n    request: {\n      method: \"GET\",\n      params: {},\n    },\n    listPath: \"data\",\n    totalKey: \"totalScore\",\n    maxKey: \"maximumScore\",\n    statusKey: \"status\",\n    attemptDateKey: \"attemptDate\",\n    timeTakenKey: \"timeTaken\",\n    rankKey: \"rank\",\n    labelMap: {\n      logicalReasoning: \"Logical Reasoning\",\n      quantitativeAptitude: \"Quantitative Aptitude\",\n      verbalAbility: \"Verbal Ability\",\n    },\n    colorMap: {\n      logicalReasoning: \"#7c3aed\",\n      quantitativeAptitude: \"#0891b2\",\n      verbalAbility: \"#16a34a\",\n    },\n    hide: [\"status\", \"attemptDate\", \"timeTaken\", \"rank\", \"maximumScore\"],\n  },\n\n  onboardingCount: {\n    variant: \"counts\",\n    dynamicCommonCount: {\n      module: \"onboarding\",\n      keys: [\"onboardingObStage\"],\n    },\n    listPath: \"\",\n    frame: true,\n    frameTitle: \"Onboarding\",\n    frameClassName: \"onboarding-card\",\n    viewAll: true,\n    footer: true,\n    columns: 4,\n    valueMap: {\n      inProgress: \"Under Review\",\n      hired: \"Onboarded\",\n      projectCompleted: \"Project cycle closed\",\n      archive: \"No longer active\",\n    },\n    labelMap: {\n      inProgress: \"In Progress\",\n      hired: \"Hired\",\n      projectCompleted: \"Project Completed\",\n      archive: \"Archive\",\n    },\n    aggregateMap: {\n      inProgress: [\"inProgress\", \"In Progress\"],\n      hired: [\"hired\", \"Hired\", \"Active\"],\n      projectCompleted: [\"projectCompleted\", \"Project Completed\", \"Completed\"],\n      archive: [\"archive\", \"Archive\", \"Not Hired\", \"Candidate Backout\"],\n    },\n    show: visibleCardsFor(\"onboardingCount\"),\n    hide: [\"total\", \"totalGrossMargin\", \"totalNetMargin\"],\n  },\n\n  // Timesheet review/calendar sidebar — driven off already-fetched detail data\n  // via <DynamicCards staticData={...} />, not a live dashboard fetch. See the\n  // 'metrics' / 'bars' variant docs above.\n  timesheetMonthlySummary: {\n    variant: \"metrics\",\n    title: \"Monthly Summary\",\n    valueSuffix: \" hrs\",\n    rows: [\n      { key: \"unapprovedPayableHours\", label: \"Unapproved Payable hours\", sublabel: \"(S + O)\" },\n      { key: \"nonPayableHours\", label: \"Non-payable hours\", sublabel: \"(Leave/Holidays)\" },\n      { key: \"approvedPayableHours\", label: \"Approved Payable hours\", valueColor: \"#15803d\" },\n    ],\n  },\n\n  // Only rendered by the page when a `weeks` array exists (e.g. the resource's\n  // own Timesheet Calendar page); pass `staticData={weeks}` directly (an array),\n  // not the summary object — see the 'metrics' variant's list mode.\n  timesheetWeeklyTotals: {\n    variant: \"metrics\",\n    title: \"Weekly Totals (S + O)\",\n    plainHeader: true,\n    valueSuffix: \" hrs\",\n    listRows: {\n      itemValueKey: \"weeklyTotals.payable\",\n      itemLabel: (week, i) => {\n        const start = week.weekStart ? dayjs(week.weekStart).format(\"MMM D\") : \"\";\n        const end = week.weekEnd ? dayjs(week.weekEnd).format(\"MMM D\") : \"\";\n        const label = `Week ${week.weekNumber ?? i + 1}`;\n        return start && end ? `${label} (${start} - ${end})` : label;\n      },\n    },\n  },\n\n  timesheetHourBreakdown: {\n    variant: \"bars\",\n    valueSuffix: \" hrs\",\n    rows: [\n      { key: \"totalSTHours\", label: \"Standard\", color: \"#1d4ed8\", bg: \"#D0E6FF\" },\n      { key: \"totalOTHours\", label: \"Overtime\", color: \"#15803d\", bg: \"#d9f7e3\" },\n      { key: \"leaveHours\", label: \"Leaves\", color: \"#b45309\", bg: \"#FFECBA\" },\n      { key: \"holidayHours\", label: \"Holidays\", color: \"#6d28d9\", bg: \"#ede9fe\", fallback: 0 },\n    ],\n  },\n\n  // Finance (Billing + Payroll) KPI row. The page computes `items` itself\n  // (icons, labels, formatted money, tones — same shape FinanceKpiRow's\n  // `items` prop always took) and passes it straight through as staticData;\n  // this config only picks the 'kpi' variant. One entry covers both routes\n  // since FinanceListPage.jsx renders both Billing and Payroll.\n  financeKpiRow: {\n    variant: \"kpi\",\n  },\n};\n\n// ── Colour palettes ─────────────────────────────────────────────────────────\n// Names here must exist as classes in dynamicCard.css (.dyn-card-item.<name>\n// and .sticky-note.<name>). Add a name here AND a class there to extend them.\n\n// counts / list cards cycle through these when color:'auto'.\nexport const PALETTE = [\"blue\", \"green\", \"purple\", \"peach\", \"red\", \"gray\"];\n\n// sticky notes cycle through these when color:'auto'.\nexport const STICKY_PALETTE = [\"purple\", \"peach\", \"green\"];\n\n// submission bars cycle through these hex values when no colorMap matches.\nexport const BAR_PALETTE = [\n  \"#1d4ed8\",\n  \"#ef4444\",\n  \"#16a34a\",\n  \"#9333ea\",\n  \"#f59e0b\",\n  \"#0891b2\",\n];\n\n// Palette NAME -> hex, so colorMap palette names work for the inline submission bars.\nexport const NAMED_COLORS = {\n  blue: \"#1d4ed8\",\n  green: \"#16a34a\",\n  purple: \"#9333ea\",\n  peach: \"#f97316\",\n  red: \"#ef4444\",\n  gray: \"#6b7280\",\n};\n\n// Returns the effective config: built-in defaults deep-merged with whatever\n// the host project injected via configureCoreTheme({ cardConfig: { … } }) or\n// window.__CORE_THEME_CONFIG__.cardConfig. Called at render time so it always\n// picks up the host's config even when set after import evaluation.\nexport function getModuleConfig() {\n  const hostConfig =\n    (typeof window !== 'undefined' && window.__CORE_THEME_CONFIG__?.cardConfig) ?? {};\n  // Shallow merge per key: host entries WIN over built-ins, but built-ins remain\n  // unless the host replaces them. To extend a built-in entry use spread:\n  //   cardConfig: { jobsCount: { ...builtIn.jobsCount, title: 'Open Positions' } }\n  return { ...MODULE_CONFIG, ...hostConfig };\n}\n\n// Built-in defaults for PeriodBadgeTag (Standard/Supplementary and friends) —\n// same host-override contract as getModuleConfig() above, one level deeper\n// (per config key, not per top-level field) since each entry is fully\n// self-contained rather than a title/rows/variant bag.\nconst PERIOD_BADGE_CONFIG = {\n  timesheet: {\n    currentLabel: 'Standard',      currentColor: 'blue',\n    pastLabel: 'Supplementary',    pastColor: 'gold',\n    // Full calendar months back that still count as \"current\". 0 = only\n    // this month; 1 = this month and last month both read as Standard.\n    thresholdMonths: 0,\n  },\n};\n\n// Effective period-badge config for `key` (e.g. 'timesheet'): built-in\n// default merged with configureCoreTheme({ periodBadgeConfig: { [key]: {…} } })\n// or window.__CORE_THEME_CONFIG__.periodBadgeConfig — host entries win,\n// field by field, over the matching built-in.\nexport function getPeriodBadgeConfig(key) {\n  const hostConfig =\n    (typeof window !== 'undefined' && window.__CORE_THEME_CONFIG__?.periodBadgeConfig) ?? {};\n  return { ...PERIOD_BADGE_CONFIG[key], ...hostConfig[key] };\n}\n\nexport default MODULE_CONFIG;\n","import { Flex, Pagination, Select, Space } from 'antd';\nimport AppTypography from './typography/Typography';\nimport { colorVars } from '../theme/colors/colors';\n\nexport default function CustomPagination({ current, pageSize, total, onChange, onPageSizeChange }) {\n  const start = Math.min((current - 1) * pageSize + 1, total);\n  const end = Math.min(current * pageSize, total);\n\n  return (\n    <Flex\n      align=\"center\"\n      justify=\"space-between\"\n      className=\"custom-pagination\"\n      style={{ color: colorVars.textSecondary }}\n    >\n      <Space size={5} align=\"center\">\n        <AppTypography variant=\"body\" color=\"secondary\">\n          Show\n        </AppTypography>\n        <Select\n          value={pageSize}\n          size=\"small\"\n          style={{ width: 72 }}\n          popupMatchSelectWidth={72}\n          onChange={(val) => {\n            onPageSizeChange(val);\n            onChange(1);\n          }}\n          options={[\n            { value: 10, label: '10' },\n            { value: 12, label: '12' },\n            { value: 25, label: '25' },\n            { value: 50, label: '50' },\n            { value: 100, label: '100' },\n          ]}\n        />\n        <AppTypography variant=\"body\" color=\"secondary\">\n          / page\n        </AppTypography>\n      </Space>\n\n      <Space size={16} align=\"center\">\n        <AppTypography variant=\"body\" color=\"secondary\">\n          {`Showing ${start} - ${end} of ${total}`}\n        </AppTypography>\n        <Pagination\n          current={current}\n          pageSize={pageSize}\n          total={total}\n          showSizeChanger={false}\n          showQuickJumper={false}\n          showLessItems\n          onChange={onChange}\n        />\n      </Space>\n    </Flex>\n  );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { formatApp, formatAppDateTime } from '../../services/timezone';\nimport { getDefaults } from '../../services/detailDefaults';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { Button, Card, Col, Popover, Progress, Row, Space, Spin, Statistic, Tag, Tooltip, Typography, Empty, message } from 'antd';\nimport DynamicTabs from '../DynamicTabs';\nimport { PlusOutlined, InfoCircleOutlined, EditOutlined, CheckCircleOutlined } from '@ant-design/icons';\nimport { getDashboardCards, getDynamicCommonCount } from '../../services/dashboardApi';\nimport { resolveStickyNote } from '../../services/popupApi';\nimport { getModuleConfig, PALETTE, STICKY_PALETTE, BAR_PALETTE, NAMED_COLORS } from './cardConfig';\nimport '../../styles/dynamicCard.css';\nimport CustomPagination from '../CustomPagination';\n\nconst { Title, Text } = Typography;\n\n/*\n  Rendering engine for the dashboard cards. The WHAT (which widgets exist, their\n  colours, what to hide) lives in cardConfig.js — edit that file, not this one.\n*/\n\n// Read a field from a record. [a, b] joins them (e.g. first + last name).\n// A dotted key ('reminder.time') walks into nested objects.\nfunction read(item, key) {\n  if (Array.isArray(key)) return key.map(k => read(item, k)).filter(has).join(' ');\n  if (typeof key === 'string' && key.includes('.')) {\n    return key.split('.').reduce((o, k) => (o == null ? o : o[k]), item);\n  }\n  return item[key];\n}\n\nconst has = v => v != null && v !== '';\n\nfunction sx(group, key, fallback = {}) {\n  return { ...fallback, ...(group.styles?.[key] || {}) };\n}\n\nfunction sectionTitle(group) {\n  return has(group.title) ? <Title level={5} style={sx(group, 'headerTitle')}>{group.title}</Title> : undefined;\n}\n\nfunction sectionExtra(group, extra) {\n  return has(group.title) ? extra : undefined;\n}\n\nfunction isNamedColor(color) {\n  return ['blue', 'green', 'purple', 'peach', 'red', 'gray'].includes(lc(color));\n}\n\nfunction cardSkin(group, color) {\n  const token = color || '';\n  const baseStyle = sx(group, 'card');\n  if (!has(token)) return { className: '', style: baseStyle };\n  if (isNamedColor(token)) return { className: token, style: baseStyle };\n  return {\n    className: '',\n    style: {\n      ...baseStyle,\n      background: token,\n      borderColor: group.styles?.card?.borderColor || token,\n    },\n  };\n}\n\n// Walk a dot-path inside the API response ('data.data' -> json.data.data).\nfunction getPath(obj, path) {\n  if (!path) return obj;\n  return path.split('.').reduce((o, k) => (o == null ? o : o[k]), obj);\n}\n\n// Turn 'finalGrossMargin' / 'project_completed' into 'Final Gross Margin'.\nfunction humanize(key) {\n  return String(key)\n    .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n    .replace(/[_-]+/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim()\n    .replace(/\\b\\w/g, c => c.toUpperCase());\n}\n\n// Turn an ISO date into something readable. The backend uses the year 0001\n// (\"0001-01-01T00:00:00Z\") to mean \"no date\" — we treat that as empty.\nfunction formatDate(value) {\n  if (!has(value)) return null;\n  const d = new Date(value);\n  if (isNaN(d) || d.getFullYear() <= 1) return null;\n  // Tenant zone + configured format, so a card and the record it links to never\n  // disagree about what day something happened.\n  return formatApp(d, getDefaults().dateFormat);\n}\n\nfunction toWholeNumber(value) {\n  const num = Number(value);\n  return Number.isFinite(num) && num >= 0 ? num : null;\n}\n\nfunction stripTrailingCounts(title) {\n  return String(title ?? '').replace(/(?:\\s*\\(\\d+[\\d,]*\\))+\\s*$/, '').trim();\n}\n\nfunction getStickyCountBreakdown(response, list) {\n  const totalCandidates = [\n    response?.data?.total,\n    response?.data?.count,\n    response?.data?.totalCount,\n    response?.data?.pagination?.total,\n    response?.data?.data?.total,\n    response?.data?.data?.count,\n    response?.data?.data?.totalCount,\n    response?.total,\n    response?.count,\n    response?.totalCount,\n    response?.pagination?.total,\n  ];\n  const todoCandidates = [\n    response?.data?.todoCount,\n    response?.data?.toDoCount,\n    response?.data?.pendingCount,\n    response?.data?.data?.todoCount,\n    response?.data?.data?.toDoCount,\n    response?.todoCount,\n    response?.toDoCount,\n    response?.pendingCount,\n  ];\n  const resolvedCandidates = [\n    response?.data?.resolvedCount,\n    response?.data?.data?.resolvedCount,\n    response?.resolvedCount,\n  ];\n\n  const todoCount = todoCandidates.map(toWholeNumber).find((value) => value !== null);\n  const resolvedCount = resolvedCandidates.map(toWholeNumber).find((value) => value !== null);\n  const countedTotal = totalCandidates.map(toWholeNumber).find((value) => value !== null);\n  const derivedTotal = todoCount !== null && resolvedCount !== null ? todoCount + resolvedCount : null;\n  const listTotal = Array.isArray(list) ? list.length : null;\n\n  return {\n    totalCount: countedTotal ?? derivedTotal ?? listTotal,\n    todoCount,\n    resolvedCount,\n  };\n}\n\n/**\n * Collect every config entry for a slot: prefix, prefix2, prefix3 ...\n * Returns the api field names with the HIGHER number first, so adding\n * `titleKey2` stacks it on top of `titleKey`. Infinite by design.\n */\nfunction slotFields(group, prefix) {\n  const numbered = new RegExp(`^${prefix}\\\\d+$`);\n  return Object.keys(group)\n    .filter(k => k === prefix || numbered.test(k))\n    .map(k => ({ field: group[k], n: k === prefix ? 1 : Number(k.slice(prefix.length)) }))\n    .sort((a, b) => b.n - a.n)\n    .map(m => m.field);\n}\n\n// columns -> antd 24-grid span. 3 cols -> 8, 4 cols -> 6.\nfunction spanFor(columns) {\n  return Math.max(1, Math.floor(24 / (columns || 4)));\n}\n\n// Parse a 'COLSxROWS' layout string -> { columns, maxCount }.\n//   '4x2' -> 4 columns, at most 8 cards ; '3x3' -> 3 columns, 9 cards.\nfunction parseLayout(layout) {\n  if (typeof layout !== 'string') return {};\n  const m = layout.toLowerCase().replace(/\\s/g, '').match(/^(\\d+)x(\\d+)$/);\n  if (!m) return {};\n  const columns = Number(m[1]);\n  return { columns, maxCount: columns * Number(m[2]) };\n}\n\n// Resolve the grid for a group from (highest priority first):\n//   explicit `columns` / `maxCount`  ->  `layout` ('4x2')  ->  defaultColumns.\n// Returns { columns, span, maxCount } — maxCount undefined means \"no limit\".\nfunction resolveLayout(group, defaultColumns) {\n  const lay = parseLayout(group.layout);\n  const columns = group.columns ?? lay.columns ?? defaultColumns;\n  const maxCount = group.maxCount ?? lay.maxCount;\n  return { columns, span: spanFor(columns), maxCount };\n}\n\n// Cap a list to maxCount (undefined/0 -> no cap).\nfunction capTo(arr, maxCount) {\n  return maxCount ? arr.slice(0, maxCount) : arr;\n}\n\n// Color is opt-in per group:\n//   no `color`      -> '' (plain white card)\n//   color: 'auto'   -> a different palette color per card\n//   color: 'green'  -> that fixed color for every card\nfunction cardColor(group, i) {\n  if (!group.color) return '';\n  if (group.color === 'auto') return PALETTE[i % PALETTE.length];\n  return group.color;\n}\n\n// lowercase + trim, for case-insensitive name matching.\nconst lc = v => String(v ?? '').trim().toLowerCase();\n\n// `name` may be a single string OR an array of candidate names (e.g. the raw\n// API key AND its humanized label). Returns true if any candidate matches `key`.\nfunction nameEq(key, name) {\n  const names = Array.isArray(name) ? name : [name];\n  return names.some(n => has(n) && lc(n) === lc(key));\n}\n\n// Per-card color override BY NAME (see `colorMap` in the config docs).\n// `name` can be one name or several candidates ([rawKey, humanizedLabel]).\n// Returns the color token (e.g. 'green' or '#0ea5e9') or null if no match.\nfunction mappedColor(group, name) {\n  if (!group.colorMap) return null;\n  const hit = Object.keys(group.colorMap).find(k => nameEq(k, name));\n  return hit ? group.colorMap[hit] : null;\n}\n\n// Per-card LABEL override BY NAME (see `labelMap` in the config docs).\n// Matches by raw key OR humanized label; returns `fallback` if no override.\nfunction mappedLabel(group, name, fallback) {\n  if (!group.labelMap) return fallback;\n  const hit = Object.keys(group.labelMap).find(k => nameEq(k, name));\n  return hit ? group.labelMap[hit] : fallback;\n}\n\n// Per-card SUB-VALUE shown under the count BY NAME (see `valueMap` in the config).\n// Matches by raw key OR humanized label; returns null if no override.\nfunction mappedValue(group, name) {\n  if (!group.valueMap) return null;\n  const hit = Object.keys(group.valueMap).find(k => nameEq(k, name));\n  return hit ? group.valueMap[hit] : null;\n}\n\n// Optional allow-list. When present, only these cards render. Names can match\n// raw API keys or display labels, same as hide/labelMap.\nfunction isShown(group, name) {\n  if (!Array.isArray(group.show) || group.show.length === 0) return true;\n  return group.show.some(s => nameEq(s, name));\n}\n\n// Should this card be dropped?  hide: [ 'Rejected', 0 ]\n//   string -> matches the card NAME (case-insensitive; raw key OR label)\n//   number -> matches the card INDEX (0-based, original position)\nfunction isHidden(group, name, index) {\n  if (!isShown(group, name)) return true;\n  if (!Array.isArray(group.hide)) return false;\n  return group.hide.some(h =>\n    typeof h === 'number' ? h === index : nameEq(h, name));\n}\n\n// The \"name\" of a list-variant record = its first non-empty titleKey value.\n// Used so colorMap / hide can target list cards by their title.\nfunction listItemName(group, item) {\n  for (const f of slotFields(group, 'titleKey')) {\n    const v = read(item, f);\n    if (has(v)) return v;\n  }\n  return null;\n}\n\n// An object of numbers ({ inProgress: 4, hired: 9 }) -> card items.\n// Each item keeps its raw `key` so colorMap/hide/labelMap can target a card by\n// either the raw API name ('pendingSubmissionCount') or its humanized `label`.\nfunction countsToItems(obj) {\n  if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return [];\n  return Object.entries(obj)\n    .filter(([, v]) => typeof v === 'number' || (typeof v === 'string' && v !== '' && !isNaN(v)))\n    .map(([k, v]) => ({ key: k, label: humanize(k), value: Number(v) }));\n}\n\nfunction dynamicCommonCountToFlatData(response, group) {\n  const data = response?.data ?? response;\n  const fields = Array.isArray(data?.fields) ? data.fields : null;\n  const preferredKey = group.dynamicCommonCount?.keys?.[0];\n  const selectedFields = fields\n    ? [\n        ...(fields.find(item => item.key === preferredKey) ? [fields.find(item => item.key === preferredKey)] : []),\n        ...fields.filter(item => item.key !== preferredKey),\n      ]\n    : [data];\n\n  if (!selectedFields.some(field => Array.isArray(field?.counts))) return data;\n\n  return selectedFields.reduce((acc, field) => {\n    if (!field || !Array.isArray(field.counts)) return acc;\n    acc.total = Math.max(Number(acc.total) || 0, Number(field.total) || 0);\n    field.counts.forEach(({ key, count }) => {\n      acc[key] = Number(count) || 0;\n    });\n    return acc;\n  }, { total: 0 });\n}\n\n// A counts object -> the shape ClientSubmissionCard renders:\n//   { total, rows: [{ label, value, barColor, accentColor, showInfo }] }\n// `totalKey` (if present in the response) is pulled out as the grand total and\n// kept out of the rows; otherwise the total is the sum of the row values.\nfunction countsToSubmission(obj, group) {\n  const items = countsToItems(obj);\n  const totalKey = group.totalKey;\n  const totalRaw = totalKey ? read(obj || {}, totalKey) : undefined;\n  const hasTotal = totalKey && has(totalRaw) && !isNaN(totalRaw);\n\n  const rows = items\n    .map((it, i) => ({ ...it, _i: i }))                              // keep original index\n    // drop the total row (matched by raw key OR its humanized label)\n    .filter(it => !(hasTotal && nameEq(totalKey, [it.key, it.label])))\n    .filter(it => !isHidden(group, [it.key, it.label], it._i))       // drop hidden rows\n    .map((it, visible) => {\n      // colorMap wins (name -> palette name or raw hex); else cycle the palette.\n      // Matched by raw key OR humanized label.\n      const mapped = mappedColor(group, [it.key, it.label]);\n      const barColor = mapped\n        ? (NAMED_COLORS[lc(mapped)] || mapped)\n        : BAR_PALETTE[it._i % BAR_PALETTE.length];\n      return {\n        label: mappedLabel(group, [it.key, it.label], it.label),     // labelMap rename\n        value: it.value,\n        barColor,\n        // The first VISIBLE row carries the orange accent + info icon.\n        accentColor: visible === 0 ? '#f97316' : null,\n        showInfo: visible === 0,\n      };\n    });\n\n  // Total reflects ALL rows; the display can still be capped via maxCount.\n  const total = hasTotal\n    ? Number(totalRaw)\n    : rows.reduce((sum, r) => sum + r.value, 0);\n\n  return { total, rows: capTo(rows, resolveLayout(group, 1).maxCount) };\n}\n\nfunction CardItem({ item, group, color }) {\n  const lines = key => slotFields(group, key).map(f => read(item, f)).filter(has);\n\n  const titles = lines('titleKey');\n  const counts = lines('countKey');\n  const names  = lines('nameKey');\n  const values = lines('valueKey');\n\n  const skin = cardSkin(group, color);\n\n  return (\n    <Card className={`dyn-card-item ${skin.className}`.trim()} style={skin.style} bordered>\n      {titles.map((v, i) => <Text key={`t${i}`} className=\"dyn-card-title\" style={sx(group, 'cardTitle')}>{v}</Text>)}\n      {counts.map((v, i) => <Statistic key={`c${i}`} value={v} className=\"dyn-card-stat\" valueStyle={sx(group, 'cardValue')} />)}\n      {names.map((v, i) => <Text key={`n${i}`} className=\"dyn-card-name\" style={sx(group, 'cardName')}>{v}</Text>)}\n      {values.length > 0 && (\n        <div className=\"dyn-card-footer\" style={sx(group, 'cardFooter')}>\n          {values.map((v, i) => <Text key={`v${i}`} className=\"dyn-card-sub\" style={sx(group, 'cardSub')}>{v}</Text>)}\n        </div>\n      )}\n    </Card>\n  );\n}\n\n// One section of stat cards built from an array of records (titleKey/countKey…).\nfunction StatGroup({ group }) {\n  const { span, maxCount } = resolveLayout(group, 4);\n  // Tag each record with its name + original index, drop hidden, then cap.\n  const shown = capTo(\n    (Array.isArray(group.list) ? group.list : [])\n      .map((item, i) => ({ item, name: listItemName(group, item), _i: i }))\n      .filter(r => !isHidden(group, r.name, r._i)),\n    maxCount,\n  );\n\n  return (\n    <Card\n      className=\"dyn-card-section\"\n      style={sx(group, 'section')}\n      title={sectionTitle(group)}\n      extra={sectionExtra(group, <Text type=\"secondary\" style={sx(group, 'headerExtra')}>{shown.length} cards</Text>)}\n    >\n      <Row gutter={[16, 16]}>\n        {shown.map(r => {\n          const color = mappedColor(group, r.name) || cardColor(group, r._i);\n          return (\n            <Col key={r._i} xs={24} sm={12} md={span >= 12 ? 12 : span * 2} lg={span} xl={span}>\n              <CardItem item={r.item} group={group} color={color} />\n            </Col>\n          );\n        })}\n      </Row>\n    </Card>\n  );\n}\n\n// One section of stat cards built from a counts object ({ key: number }).\nfunction CountsGroup({ group, items }) {\n  const { span, maxCount } = resolveLayout(group, 4);\n  // Keep the original index (for stable auto-colors), drop hidden, then cap.\n  const shown = capTo(\n    items\n      .map((it, i) => ({ ...it, _i: i }))\n      .filter(it => !isHidden(group, [it.key, it.label], it._i)),\n    maxCount,\n  );\n\n  return (\n    <Card\n      className=\"dyn-card-section\"\n      style={sx(group, 'section')}\n      title={sectionTitle(group)}\n      extra={sectionExtra(group, <Text type=\"secondary\" style={sx(group, 'headerExtra')}>{shown.length} cards</Text>)}\n    >\n      <Row gutter={[16, 16]}>\n        {shown.map(it => {\n          const color = mappedColor(group, [it.key, it.label]) || cardColor(group, it._i);\n          const skin = cardSkin(group, color);\n          return (\n            <Col key={it._i} xs={24} sm={12} md={span >= 12 ? 12 : span * 2} lg={span} xl={span}>\n              <Card className={`dyn-card-item ${skin.className}`.trim()} style={skin.style} bordered>\n                <Text className=\"dyn-card-title\" style={sx(group, 'cardTitle')}>\n                  {mappedLabel(group, [it.key, it.label], it.label)}\n                </Text>\n                <Statistic value={it.value} groupSeparator={group.groupSeparator ?? ','} className=\"dyn-card-stat\" valueStyle={sx(group, 'cardValue')} />\n                {has(mappedValue(group, [it.key, it.label])) && (\n                  <Text className=\"dyn-card-sub\" style={sx(group, 'cardSub')}>\n                    {mappedValue(group, [it.key, it.label])}\n                  </Text>\n                )}\n              </Card>\n            </Col>\n          );\n        })}\n      </Row>\n    </Card>\n  );\n}\n\n/**\n * Submission variant — the \"Total Client Submission\" look: a header total and\n * one horizontal progress bar per number in the counts object. Same markup as\n * the stand-alone ClientSubmissionCard, but driven by the common API here so\n * the whole dashboard stays config-driven (no separate component to call).\n */\nfunction SubmissionGroup({ group, data }) {\n  const { total, rows } = countsToSubmission(data, group);\n  const tooltipText = group.tooltipText;\n\n  return (\n    <Card className=\"submission-card\" style={sx(group, 'card')}>\n\n      {has(group.title) && (\n        <Row justify=\"space-between\" align=\"middle\" className=\"submission-header\" style={sx(group, 'submissionHeader')}>\n          <Col>\n            <Text className=\"submission-title\" style={sx(group, 'submissionTitle')}>\n              {group.title} {tooltipText && (\n                <Tooltip title={tooltipText}>\n                  <InfoCircleOutlined className=\"submission-info-icon\" style={sx(group, 'infoIcon')} />\n                </Tooltip>\n              )}\n            </Text>\n          </Col>\n          <Col>\n            <Text className=\"submission-total\" style={sx(group, 'submissionTotal')}>{Number(total || 0).toLocaleString()}</Text>\n          </Col>\n        </Row>\n      )}\n\n      <div className=\"submission-rows\" style={sx(group, 'submissionRows')}>\n        {rows.map((r, i) => (\n          <div key={`${r.label}-${i}`}>\n\n            <Row justify=\"space-between\" align=\"middle\" className=\"submission-row-header\" style={sx(group, 'submissionRowHeader')}>\n              <Col>\n                <Row align=\"middle\" gutter={6}>\n                  <Col>\n                    <Text className=\"submission-row-label\" style={sx(group, 'submissionRowLabel')}>{r.label}</Text>\n                  </Col>\n                  {/* {r.showInfo && (\n                    <Col>\n                      <Tooltip title={group.infoText}>\n                        <InfoCircleOutlined className=\"submission-info-icon\" />\n                      </Tooltip>\n                    </Col>\n                  )} */}\n                </Row>\n              </Col>\n              <Col>\n                <Text className=\"submission-row-value\" style={sx(group, 'submissionRowValue')}>\n                  {r.value}\n                </Text>\n              </Col>\n            </Row>\n\n            <div className=\"submission-bar-track\" style={sx(group, 'submissionBarTrack')}>\n              {/* {r.accentColor && (\n                <div className=\"submission-bar-accent\" style={{ background: r.accentColor }} />\n              )} */}\n             <div\n  className=\"submission-bar-fill\"\n  style={{\n    width: `${(r.value / (total || 1)) * 100}%`,\n    background: r.barColor,\n  }}\n/>\n            </div>\n\n          </div>\n        ))}\n      </div>\n\n    </Card>\n  );\n}\n\nfunction formatMetaValue(value) {\n  if (!has(value)) return '-';\n  const date = new Date(value);\n  if (!Number.isNaN(date.getTime()) && /date|time/i.test(String(value))) {\n    return formatAppDateTime(date);\n  }\n  return String(value);\n}\n\nfunction AssessmentGroup({ group, data }) {\n  const totalKey = group.totalKey ?? 'totalScore';\n  const maxKey = group.maxKey ?? 'maximumScore';\n  const statusKey = group.statusKey ?? 'status';\n  const attemptDateKey = group.attemptDateKey ?? 'attemptDate';\n  const timeTakenKey = group.timeTakenKey ?? 'timeTaken';\n  const rankKey = group.rankKey ?? 'rank';\n  const total = Number(read(data || {}, totalKey) ?? 0);\n  const maximum = Number(read(data || {}, maxKey) ?? 100) || 100;\n  const percent = Math.max(0, Math.min(100, Math.round((total / maximum) * 100)));\n  const rows = countsToSubmission(data, {\n    ...group,\n    totalKey,\n    hide: [...(Array.isArray(group.hide) ? group.hide : []), maxKey, statusKey, attemptDateKey, timeTakenKey, rankKey],\n  }).rows;\n  const metaItems = [\n    { key: statusKey, label: group.statusLabel ?? 'Status' },\n    { key: attemptDateKey, label: group.attemptDateLabel ?? 'Attempt Date' },\n    { key: timeTakenKey, label: group.timeTakenLabel ?? 'Time Taken' },\n    { key: rankKey, label: group.rankLabel ?? 'Rank' },\n  ].filter((item) => has(read(data || {}, item.key)));\n\n  return (\n    <Card className=\"assessment-card\" style={sx(group, 'card')} title={sectionTitle(group)}>\n      <div className=\"assessment-card__top\">\n        <Progress\n          type=\"circle\"\n          percent={percent}\n          format={() => `${Number(total || 0).toLocaleString()}/${maximum.toLocaleString()}`}\n          strokeColor={group.scoreColor ?? '#6d4aff'}\n          trailColor={group.trailColor ?? '#edf0f5'}\n        />\n        <dl className=\"assessment-card__meta\">\n          {metaItems.map((item) => (\n            <div key={item.key} className=\"assessment-card__meta-row\">\n              <dt>{item.label}</dt>\n              <dd>{formatMetaValue(read(data || {}, item.key))}</dd>\n            </div>\n          ))}\n        </dl>\n      </div>\n      <div className=\"submission-rows assessment-card__rows\" style={sx(group, 'submissionRows')}>\n        {rows.map((row) => (\n          <div key={row.label}>\n            <Row justify=\"space-between\" align=\"middle\" className=\"submission-row-header\" style={sx(group, 'submissionRowHeader')}>\n              <Col><Text className=\"submission-row-label\" style={sx(group, 'submissionRowLabel')}>{row.label}</Text></Col>\n              <Col><Text className=\"submission-row-value\" style={sx(group, 'submissionRowValue')}>{row.value}</Text></Col>\n            </Row>\n            <div className=\"submission-bar-track\" style={sx(group, 'submissionBarTrack')}>\n              <div\n                className=\"submission-bar-fill\"\n                style={{\n                  width: `${Math.max(0, Math.min(100, (Number(row.value) / maximum) * 100))}%`,\n                  background: row.barColor,\n                }}\n              />\n            </div>\n          </div>\n        ))}\n      </div>\n    </Card>\n  );\n}\n\n// Format a metrics/bars row value: trims a trailing \".0\" (matches the old\n// Timesheet formatHours helper) and appends the row's (or group's) suffix,\n// e.g. valueSuffix: ' hrs'. `fallback` covers fields the API may omit (0, not '-').\nfunction formatMetricValue(rawValue, row = {}, group = {}) {\n  const value = has(rawValue) ? rawValue : row.fallback;\n  if (!has(value)) return '-';\n  const n = Number(value);\n  if (!Number.isFinite(n)) return String(value);\n  const suffix = row.suffix ?? group.valueSuffix ?? '';\n  return `${n.toFixed(1).replace(/\\.0$/, '')}${suffix}`;\n}\n\n/**\n * Metrics variant — a card of plain label/value rows (e.g. Timesheet's\n * \"Monthly Summary\"), OR, when `data` is an array, one row per array item\n * (e.g. \"Weekly Totals\" driven straight off a `weeks` list) using\n * `group.listRows: { itemLabel(item, i), itemValueKey }`.\n *   group.title        -> header text\n *   group.headerExtra   -> optional node next to the title (e.g. a status pill)\n *   group.plainHeader   -> secondary-text label instead of the title+badge head row\n *   group.rows          -> [{ key, label, sublabel?, valueColor?, suffix?, fallback? }]\n *   group.valueSuffix    -> default suffix for every row (e.g. ' hrs')\n */\nfunction MetricsGroup({ group, data }) {\n  const isList = Array.isArray(data);\n\n  return (\n    <Card className=\"timesheet-summary-card\" size=\"small\">\n      {has(group.title) && (\n        group.plainHeader ? (\n          <Text type=\"secondary\" style={{ fontSize: 12, fontWeight: 600 }}>{group.title}</Text>\n        ) : (\n          <div className=\"timesheet-summary-card__head\">\n            <Title level={5} style={{ margin: 0 }}>{group.title}</Title>\n            {group.headerExtra}\n          </div>\n        )\n      )}\n      {!isList && (\n        <div className=\"timesheet-summary-card__metrics\">\n          {(group.rows ?? []).map((row) => (\n            <div key={row.key} className=\"timesheet-summary-card__metric-row\">\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                {row.label} {row.sublabel && <span style={{ fontSize: 11 }}>{row.sublabel}</span>}\n              </Text>\n              <Text strong style={{ fontSize: 13, whiteSpace: 'nowrap', color: row.valueColor }}>\n                {formatMetricValue(read(data ?? {}, row.key), row, group)}\n              </Text>\n            </div>\n          ))}\n        </div>\n      )}\n      {isList && data.length > 0 && (\n        <div className=\"timesheet-summary-card__weekly\">\n          {data.map((item, i) => (\n            <div key={i} className=\"timesheet-summary-card__week-row\">\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                {group.listRows?.itemLabel ? group.listRows.itemLabel(item, i) : `Row ${i + 1}`}\n              </Text>\n              <Text strong style={{ fontSize: 12 }}>\n                {formatMetricValue(read(item, group.listRows?.itemValueKey), group.listRows, group)}\n              </Text>\n            </div>\n          ))}\n        </div>\n      )}\n    </Card>\n  );\n}\n\n/**\n * Bars variant — full-width solid-colour rows (label left, value right), e.g.\n * Timesheet's Standard/Overtime/Leave/Holiday hour breakdown.\n *   group.rows        -> [{ key, label, color, bg, suffix?, fallback? }]\n *   group.title        -> optional header text (omit to skip the head row)\n *   group.headerExtra   -> optional node next to the title (e.g. a status pill);\n *                          shows the head row on its own even without a title\n */\nfunction BarsGroup({ group, data }) {\n  return (\n    <Card className=\"timesheet-summary-card\" size=\"small\">\n      {(has(group.title) || group.headerExtra) && (\n        <div className=\"timesheet-summary-card__head\">\n          {has(group.title) && <Title level={5} style={{ margin: 0 }}>{group.title}</Title>}\n          {group.headerExtra}\n        </div>\n      )}\n      <div className=\"timesheet-summary-card__bars\">\n        {(group.rows ?? []).map((row) => (\n          <div key={row.key} className=\"timesheet-summary-card__bar\" style={{ background: row.bg }}>\n            <Text style={{ fontSize: 12, color: row.color, fontWeight: 500 }}>{row.label}</Text>\n            <Text strong style={{ fontSize: 13, color: row.color }}>\n              {formatMetricValue(read(data ?? {}, row.key), row, group)}\n            </Text>\n          </div>\n        ))}\n      </div>\n    </Card>\n  );\n}\n\n/**\n * Kpi variant — a row of small stat tiles (icon badge + label + value +\n * optional sub-text), each tinted by `tone`. Unlike the other variants, `data`\n * here is an array the PAGE already fully computed (icons, labels, formatted\n * values, tones) — the same shape Finance's FinanceKpiRow's `items` prop\n * always took — so this is a pure renderer, no field-mapping. Pass\n * `loading` (via the DynamicCards prop, not cardConfig) to show the skeleton\n * state instead, e.g. on first paint before the summary has loaded.\n *   item: { key, label, value, icon?, tone?, sub? }\n *   group.compact -> smaller tiles (matches finance-kpi-row--compact)\n */\nfunction KpiGroup({ group, data }) {\n  const items = Array.isArray(data) ? data : [];\n  const rowClass = `finance-kpi-row${group.compact ? ' finance-kpi-row--compact' : ''}`;\n\n  if (group.loading) {\n    const count = items.length || 4;\n    return (\n      <div className={rowClass}>\n        {Array.from({ length: count }, (_, i) => (\n          <div className=\"finance-kpi fin-kpi--skeleton\" key={i}>\n            <span className=\"fin-skeleton fin-skeleton--label\" />\n            <span className=\"fin-skeleton fin-skeleton--value\" />\n          </div>\n        ))}\n      </div>\n    );\n  }\n\n  return (\n    <div className={rowClass}>\n      {items.map((item) => (\n        <div className={`finance-kpi fin-kpi--${item.tone ?? 'neutral'}`} key={item.key ?? item.label}>\n          {item.icon ? <span className=\"fin-kpi__icon\">{item.icon}</span> : null}\n          <span className=\"fin-kpi__body\">\n            <span className=\"finance-kpi__label\">{item.label}</span>\n            <strong className=\"finance-kpi__value\">{item.value}</strong>\n            {item.sub ?? item.hint ? <span className=\"finance-kpi__hint\">{item.sub ?? item.hint}</span> : null}\n          </span>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// A note counts as \"resolved\" when its status field (group.pillKey, default\n// 'status') reads 'resolved' — the same field already shown as the note's pill.\nfunction isResolvedStatus(group, item) {\n  return lc(read(item, group.pillKey || 'status')) === 'resolved';\n}\n\nfunction hasReminderDate(group, item) {\n  return has(group.dateKey ? formatDate(read(item, group.dateKey)) : null);\n}\n\nfunction isTaggedStickyNote(group, item) {\n  const status = lc(read(item, group.pillKey || 'status'));\n  if (status === 'tagged' || status === 'tag user' || status === 'tagged user') return true;\n\n  const receiver = item?.receiver ?? item?.receivers ?? item?.receiverId ?? item?.receiverName ?? item?.taggedUser;\n  if (Array.isArray(receiver)) return receiver.length > 0;\n  if (receiver && typeof receiver === 'object') return Object.keys(receiver).length > 0;\n  if (has(receiver)) return true;\n\n  const text = `${read(item, group.headingKey || 'title') ?? ''} ${read(item, group.bodyKey || 'notes') ?? ''}`;\n  return /(^|\\s)@[^\\s]+/.test(text);\n}\n\nfunction stickyCardType(group, item, i) {\n  if (isResolvedStatus(group, item)) return 'gray';\n  if (isTaggedStickyNote(group, item)) return 'blue';\n  if (hasReminderDate(group, item)) return 'peach';\n\n  const colorName = group.colorBy ? read(item, group.colorBy) : null;\n  return (\n    mappedColor(group, colorName) ||\n    (group.color && group.color !== 'auto'\n      ? group.color\n      : STICKY_PALETTE[i % STICKY_PALETTE.length])\n  );\n}\n\n// group.dateRange (set by the page, e.g. a \"Last 30 Days\" picker) is\n// { start: Date, end: Date } or null/undefined for \"all time\". Filters by the\n// note's footerRightKey field (default 'createdAt'), inclusive on both ends.\nfunction inDateRange(group, item) {\n  const { start, end } = group.dateRange || {};\n  if (!start || !end) return true;\n  const raw = read(item, group.footerRightKey || 'createdAt');\n  if (!has(raw)) return true;\n  const d = new Date(raw);\n  if (isNaN(d)) return true;\n  return d >= start && d <= end;\n}\n\n/**\n * Map one API record to a sticky note, using the *Key fields from the group\n * config. Every field is optional — leave a key out and that part won't show.\n *   pillKey / headingKey / bodyKey / footerLeftKey   -> plain text\n *   footerRightKey / dateKey                          -> formatted as a date\n * Colour priority:\n *   colorMap[<colorBy field value, e.g. status>]  ->  fixed `color`  ->  auto cycle\n */\nfunction toStickyNote(item, group, i) {\n  const reminder = group.dateKey ? formatDate(read(item, group.dateKey)) : null;\n  return {\n    type: stickyCardType(group, item, i),\n    pill: group.pillKey ? read(item, group.pillKey) : null,\n    heading: group.headingKey ? read(item, group.headingKey) : null,\n    body: group.bodyKey ? read(item, group.bodyKey) : null,\n    footerLeft: group.footerLeftKey ? read(item, group.footerLeftKey) : null,\n    footerRight: group.footerRightKey ? formatDate(read(item, group.footerRightKey)) : null,\n    dot: reminder ? '#f97316' : null,   // a reminder date gets the orange dot\n    date: reminder,\n  };\n}\n\n/**\n * Sticky-note body text. The card is a fixed height (see dynamicCard.css) and the\n * body is clamped to `bodyLines` lines with a CSS ellipsis. We measure the node\n * and ONLY when the text is actually clipped wrap it in a hover Popover that\n * shows the full content. Re-measures on resize (column width changes clamping).\n */\nfunction StickyNoteBody({ text, lines, style }) {\n  const ref = useRef(null);\n  const [clipped, setClipped] = useState(false);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    let raf = 0;\n    // Measure on the next frame so fonts / flex layout have settled first.\n    const check = () => {\n      raf = requestAnimationFrame(() => {\n        const next = el.scrollHeight - el.clientHeight > 1;\n        // Bail if unchanged — without this, a value that keeps recomputing to\n        // the same boolean would still re-run the effect below on every tick.\n        setClipped((prev) => (prev === next ? prev : next));\n      });\n    };\n    check();\n    const ro = new ResizeObserver(check);\n    ro.observe(el);\n    return () => { cancelAnimationFrame(raf); ro.disconnect(); };\n  }, [text, lines]);\n\n  const className = `sticky-note-body${lines ? ` clamp-${lines}` : ''}`;\n  const body = <div ref={ref} className={className} style={style}>{text}</div>;\n\n  // Always wrap in the SAME Popover, whether clipped or not — swapping the\n  // wrapper in/out based on `clipped` changes the observed div's effective\n  // layout width, which can flip the clipped measurement back and forth and\n  // re-trigger the ResizeObserver forever. `open={false}` keeps it inert\n  // (no hover popover) when the text isn't actually clipped.\n  return (\n    <Popover\n      trigger=\"hover\"\n      placement=\"topLeft\"\n      overlayClassName=\"sticky-note-popover\"\n      content={clipped ? <div className=\"sticky-note-popover-content\">{text}</div> : null}\n      open={clipped ? undefined : false}\n    >\n      {body}\n    </Popover>\n  );\n}\n\n/**\n * Sticky Notes section — same look as the stand-alone StickyNotesCard, but\n * rendered here so the whole dashboard is driven by DynamicCards alone.\n */\nfunction StickyGroup({ group }) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const openAddNote = () => navigate('/popup/sticky-notes', {\n    state: {\n      background: location,\n      selectedIds: [],\n      selectedRecords: [],\n      // 'general' is the notesFor category the notes collection accepts for a\n      // dashboard-level note with no related job/candidate/submission record —\n      // NOT group.moduleName (that's the dashboard-card key, e.g. \"stickyNotes\").\n      moduleName: 'general',\n      popupContext: {},\n    },\n  });\n  const editNote = (item) => navigate('/popup/sticky-notes', {\n    state: {\n      background: location,\n      selectedIds: [],\n      selectedRecords: [],\n      moduleName: 'general',\n      popupContext: {\n        editingNoteId: item._id ?? item.id,\n        editingHeading: item.title,\n        editingComments: item.notes,\n        // A live dayjs instance can't survive router state (history.pushState\n        // structurally clones it, stripping its prototype/methods and\n        // crashing the DatePicker) — pass the raw ISO string instead and let\n        // DynamicPopup convert it to dayjs for date-picker fields.\n        editingTargetDate: item.reminder?.time || undefined,\n      },\n    },\n  });\n  // PUT /notes/{id}/resolve. Drop the note from view optimistically, then\n  // revert (with a toast) if the call fails.\n  const [resolvedIds, setResolvedIds] = useState(new Set());\n  const resolveNote = async (item) => {\n    const noteId = item._id ?? item.id;\n    setResolvedIds((prev) => new Set(prev).add(noteId));\n    try {\n      await resolveStickyNote(noteId);\n      message.success('Note resolved');\n    } catch {\n      message.error('Failed to resolve note');\n      setResolvedIds((prev) => {\n        const next = new Set(prev);\n        next.delete(noteId);\n        return next;\n      });\n    }\n  };\n  // Sticky notes default to 2 columns; `layout`/`columns`/`maxCount` override.\n  const { span, maxCount } = resolveLayout(group, 2);\n  // A note's name = its colorBy field (e.g. status), else its heading.\n  // Keep the original index so the auto colour-cycle stays stable after hiding.\n  const noteName = item =>\n    group.colorBy ? read(item, group.colorBy)\n    : group.headingKey ? read(item, group.headingKey)\n    : null;\n  // Everything except the To-do/Resolved split and the display cap: dropped\n  // resolved-this-session notes, hidden-by-config notes, and out-of-range notes.\n  const visible = (Array.isArray(group.list) ? group.list : [])\n    .filter(item => !resolvedIds.has(item._id ?? item.id))\n    .map((item, i) => ({ item, _i: i }))\n    .filter(({ item, _i }) => !isHidden(group, noteName(item), _i))\n    .filter(({ item }) => inDateRange(group, item));\n\n  // `showTabs` (opt-in, e.g. the full \"View all\" page) splits notes into a\n  // To-do / Resolved Notes tab pair by status; the dashboard mini-card ignores\n  // it and shows everything mixed together, same as before.\n  const [activeTab, setActiveTab] = useState('todo');\n  const todoEntries = visible.filter(({ item }) => !isResolvedStatus(group, item));\n  const resolvedEntries = visible.filter(({ item }) => isResolvedStatus(group, item));\n  const tabbed = group.showTabs;\n  const currentEntries = tabbed ? (activeTab === 'resolved' ? resolvedEntries : todoEntries) : visible;\n\n  // Pagination only applies to the tabbed (\"View all\") layout — the dashboard\n  // mini-card keeps its plain maxCount cap instead.\n  const [pageSize, setPageSize] = useState(group.pageSize || 12);\n  const [page, setPage] = useState(1);\n  useEffect(() => { setPage(1); }, [activeTab, group.dateRange]);\n  const totalPages = Math.max(1, Math.ceil(currentEntries.length / pageSize));\n  useEffect(() => { setPage(p => Math.min(p, totalPages)); }, [totalPages]);\n\n  const shown = tabbed\n    ? currentEntries.slice((page - 1) * pageSize, page * pageSize)\n    : capTo(visible, maxCount);\n\n  return (\n    <Card\n      className=\"sticky-card\"\n      style={sx(group, 'section')}\n      title={sectionTitle(group)}\n      extra={sectionExtra(group,\n        <div className=\"sticky-card-actions\">\n          {group.headerExtra}\n          <Tooltip title=\"Add note\">\n            <Button type=\"text\" icon={<PlusOutlined />} size=\"small\" onClick={openAddNote} />\n          </Tooltip>\n          {has(group.viewAllUrl) && (\n            <Button\n              type=\"link\"\n              size=\"small\"\n              onClick={() => navigate(group.viewAllUrl, {\n                // Hand the full-page route everything it needs to re-fetch the\n                // SAME list (module + its API request) — minus the dashboard cap.\n                state: {\n                  moduleName: group.moduleName,\n                  title: group.title,\n                  request: group.request,\n                },\n              })}\n            >\n              View all\n            </Button>\n          )}\n        </div>\n      )}\n    >\n      {tabbed && (\n        <DynamicTabs\n          activeKey={activeTab}\n          onChange={setActiveTab}\n          tabs={[\n            { key: 'todo', title: 'To-do', count: todoEntries.length },\n            { key: 'resolved', title: 'Resolved Notes', count: resolvedEntries.length },\n          ]}\n        />\n      )}\n      {shown.length === 0 ? (\n        <Empty description=\"No notes found\" />\n      ) : (\n      <div className={tabbed ? 'sticky-notes-scroll' : undefined}>\n      <Row gutter={[12, 12]}>\n        {shown.map(({ item, _i }) => {\n          const n = toStickyNote(item, group, _i);\n          const skin = cardSkin(group, n.type);\n          return (\n            <Col key={_i} xs={24} sm={24} md={span >= 12 ? 12 : span * 2} lg={span} xl={span}>\n              <div className={`sticky-note ${skin.className}`.trim()} style={skin.style}>\n\n                <Space size={4} className=\"sticky-note-hover-actions\">\n                  <Tooltip title=\"Edit\">\n                    <Button\n                      type=\"text\"\n                      size=\"small\"\n                      icon={<EditOutlined />}\n                      onClick={() => editNote(item)}\n                    />\n                  </Tooltip>\n                  <Tooltip title=\"Resolve\">\n                    <Button\n                      type=\"text\"\n                      size=\"small\"\n                      icon={<CheckCircleOutlined />}\n                      onClick={() => resolveNote(item)}\n                    />\n                  </Tooltip>\n                </Space>\n\n                <Space size={8} align=\"center\" className=\"sticky-note-pill-row\">\n                  {has(n.pill) && (\n                    <Tag style={sx(group, 'stickyPill')}>\n                      {n.dot && <span className=\"sticky-note-dot\" style={{ background: n.dot }} />}\n                      {n.pill}\n                    </Tag>\n                  )}\n                  {n.date && <Text className=\"sticky-note-date\" style={sx(group, 'stickyDate')}>{n.date}</Text>}\n                </Space>\n\n                {has(n.heading) && <Text strong className=\"sticky-note-heading\" style={sx(group, 'stickyHeading')}>{n.heading}</Text>}\n                {has(n.body) && <StickyNoteBody text={n.body} lines={group.bodyLines} style={sx(group, 'stickyBody')} />}\n\n                <Row justify=\"space-between\" align=\"middle\" className=\"sticky-note-footer\" style={sx(group, 'stickyFooter')}>\n                  <Col><Text style={sx(group, 'stickyFooterText')}>{n.footerLeft}</Text></Col>\n                  <Col><Text style={sx(group, 'stickyFooterText')}>{n.footerRight}</Text></Col>\n                </Row>\n\n              </div>\n            </Col>\n          );\n        })}\n      </Row>\n      </div>\n      )}\n      {tabbed && currentEntries.length > 0 && (\n        <div className=\"sticky-notes-pagination\">\n          <CustomPagination\n            current={page}\n            pageSize={pageSize}\n            total={currentEntries.length}\n            onChange={setPage}\n            onPageSizeChange={setPageSize}\n          />\n        </div>\n      )}\n    </Card>\n  );\n}\n\n/**\n * Optional outer \"frame\" around a group — an opt-in titled card with a View-all\n * link and (optionally) a footer strip. Turn it on per module in the config:\n *   frame: true            -> wrap the group in this outer card\n *   frameTitle: 'Onboarding'-> the heading text\n *   frameClassName: 'x'    -> class on the outer card (styled in CSS; also drives\n *                             the footer class `<frameClassName>-footer`)\n *   viewAll: true | 'text' -> show a View-all link in the header\n *   footer: true           -> render the footer strip\n * The inner group renders WITHOUT its own title, so there's no double header.\n */\nfunction FrameCard({ group, children }) {\n  const cls = group.frameClassName || 'dyn-frame';\n  const extra = group.viewAll\n    ? <a className=\"dyn-frame-view-all\">{typeof group.viewAll === 'string' ? group.viewAll : 'View all'}</a>\n    : undefined;\n  return (\n    <Card className={cls} title={group.frameTitle} extra={extra}>\n      {children}\n      {group.footer && <div className={`${cls}-footer`} />}\n    </Card>\n  );\n}\n\n// Render a single resolved group (config + already-extracted data).\nfunction GroupView({ group, data }) {\n  const baseTitle = group.variant === 'sticky' ? stripTrailingCounts(group.title) : group.title;\n  const stickyTitle = group.variant === 'sticky' && has(group.totalCount)\n    ? `${baseTitle} (${Number(group.totalCount).toLocaleString()})`\n    : baseTitle;\n  const resolvedGroup = stickyTitle === group.title ? group : { ...group, title: stickyTitle };\n  // A framed group never renders its own inner title ? the frame owns the header.\n  const inner = resolvedGroup.frame ? { ...resolvedGroup, title: undefined } : resolvedGroup;\n  const content =\n    inner.variant === 'sticky'\n      ? <StickyGroup group={{ ...inner, list: Array.isArray(data) ? data : [] }} />\n      : inner.variant === 'counts'\n        ? <CountsGroup group={inner} items={countsToItems(data)} />\n        : inner.variant === 'submission'\n          ? <SubmissionGroup group={inner} data={data} />\n          : inner.variant === 'assessment'\n            ? <AssessmentGroup group={inner} data={data} />\n            : inner.variant === 'metrics'\n              ? <MetricsGroup group={inner} data={data} />\n              : inner.variant === 'bars'\n                ? <BarsGroup group={inner} data={data} />\n                : inner.variant === 'kpi'\n                  ? <KpiGroup group={inner} data={data} />\n                  : <StatGroup group={{ ...inner, list: Array.isArray(data) ? data : [] }} />;\n\n  return resolvedGroup.frame ? <FrameCard group={resolvedGroup}>{content}</FrameCard> : content;\n}\n\n/**\n * ModuleCards — API-driven mode. Give it a moduleName, it looks the config up\n * in MODULE_CONFIG, calls the ONE common /dashboard/cards endpoint, then renders\n * the response with the same sticky/counts/list logic used by the static mode.\n */\nfunction ModuleCards({ moduleName, title, maxCount, layout, columns, request, viewAll = true, staticData, showTabs, dateRange, headerExtra, rows, loading: loadingOverride }) {\n  const base = getModuleConfig()[moduleName];\n  // Props passed from the page override the matching keys in cardConfig.js.\n  // Memoised so the fetch effect below doesn't re-run on every render.\n  // `request` is stringified for the dep array so a fresh object (e.g. one\n  // coming from router navigation state) doesn't re-trigger the effect.\n  const requestKey = request ? JSON.stringify(request) : '';\n  // `rows` stringified the same way as `request` — it's a page-computed array\n  // (e.g. a label that varies per month), so a fresh-but-equal array on every\n  // render must not be treated as a config change.\n  const rowsKey = rows ? JSON.stringify(rows) : '';\n  const config = useMemo(() => {\n    if (!base) return base;\n    // `loading` here is a page-controlled UI flag (e.g. the 'kpi' variant's\n    // skeleton state) — unrelated to this component's OWN fetch-loading below.\n    // `rows` lets a page override cardConfig's static row labels/order (e.g.\n    // \"Standard\" vs \"Standard / Supplementary\" depending on which month is\n    // being viewed) without forking the whole module config.\n    const overrides = { title, maxCount, layout, columns, showTabs, dateRange, headerExtra, rows, loading: loadingOverride };\n    // moduleName is kept on the config so children (e.g. the sticky \"View all\"\n    // link) can forward it to the full-page route.\n    const merged = { ...base, moduleName };\n    for (const k in overrides) {\n      if (has(overrides[k])) merged[k] = overrides[k];\n    }\n    // Merge a request override (e.g. a larger limit on the \"View all\" page).\n    if (request) {\n      merged.request = {\n        ...base.request,\n        ...request,\n        params: { ...base.request?.params, ...request.params },\n        body: { ...base.request?.body, ...request.body },\n      };\n    }\n    // Let a page suppress the \"View all\" link (so the full page doesn't show\n    // a link back to itself).\n    if (!viewAll) merged.viewAllUrl = undefined;\n    return merged;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [base, title, maxCount, layout, columns, requestKey, viewAll, showTabs, dateRange, headerExtra, rowsKey, loadingOverride]);\n  // One state bag tagged with the module it belongs to, so we never call\n  // setState synchronously inside the effect (only in the async callbacks).\n  const [result, setResult] = useState({ moduleName: null, resp: null, error: null });\n\n  // Bump on config.refreshEvent (e.g. a popup dispatches it after a successful\n  // save) to force the fetch effect below to re-run — closing a popup returns\n  // to this same mounted component, so nothing else would trigger a refetch.\n  const [refreshTick, setRefreshTick] = useState(0);\n  useEffect(() => {\n    if (!config?.refreshEvent) return undefined;\n    const bump = () => setRefreshTick((t) => t + 1);\n    window.addEventListener(config.refreshEvent, bump);\n    return () => window.removeEventListener(config.refreshEvent, bump);\n  }, [config?.refreshEvent]);\n\n  useEffect(() => {\n    if (!config) return;\n\n    // If a parent already has count data, convert and use it.\n    if (staticData !== undefined) {\n      const resp = dynamicCommonCountToFlatData(staticData, config);\n      setResult({ moduleName, resp, error: null });\n      return;\n    }\n\n    if (config.dynamicCommonCount) {\n      let alive = true;\n      getDynamicCommonCount(config.dynamicCommonCount)\n        .then(json => {\n          if (alive) setResult({ moduleName, resp: dynamicCommonCountToFlatData(json, config), error: null });\n        })\n        .catch(err => { if (alive) setResult({ moduleName, resp: null, error: err }); });\n      return () => { alive = false; };\n    }\n\n    // For non-count modules (e.g. stickyNotes), fetch individually.\n    if (!config.request) return;\n    let alive = true;\n    getDashboardCards(moduleName, config.request)\n      .then(json => { if (alive) setResult({ moduleName, resp: json, error: null }); })\n      .catch(err => { if (alive) setResult({ moduleName, resp: null, error: err }); });\n    return () => { alive = false; };\n  }, [moduleName, config, staticData, refreshTick]);\n\n  // Still loading until the result we hold is for THIS module.\n  const loading = result.moduleName !== moduleName;\n  const error = loading ? null : result.error;\n  const resp = loading ? null : result.resp;\n\n  if (!config) {\n    return <Empty description={`Unknown dashboard module: ${moduleName}`} />;\n  }\n  if (loading) {\n    return (\n      <Card className=\"dyn-card-section\" style={sx(config, 'section')} title={sectionTitle(config)}>\n        <div style={{ textAlign: 'center', padding: 24 }}><Spin /></div>\n      </Card>\n    );\n  }\n  if (error) {\n    return (\n      <Card className=\"dyn-card-section\" style={sx(config, 'section')} title={sectionTitle(config)}>\n        <Empty description={`Failed to load: ${error.message}`} />\n      </Card>\n    );\n  }\n\n  const data = getPath(resp, config.listPath);\n  const stickyCounts = config.variant === 'sticky' ? getStickyCountBreakdown(resp, data) : null;\n  const group = config.variant === 'sticky'\n    ? { ...config, ...stickyCounts }\n    : config;\n\n  return <GroupView group={group} data={data} />;\n}\n\n/**\n * DynamicCards — give it a moduleName and it renders that dashboard widget LIVE\n * from the common API. Any of these props override the config in cardConfig.js:\n *   title    -> section heading\n *   layout   -> 'COLSxROWS' grid, e.g. '4x2' (4 wide, max 8 cards), '3x3', '2x4'\n *   columns  -> just the column count (no card cap)\n *   maxCount -> hard cap on how many cards to show\n *\n *   <DynamicCards moduleName=\"jobsCount\" layout=\"4x2\" />\n *   <DynamicCards moduleName=\"stickyNotes\" title=\"My Notes\" maxCount={6} />\n */\nexport default function DynamicCards({ moduleName, title, layout, columns, maxCount, request, viewAll, staticData, showTabs, dateRange, headerExtra, rows, loading }) {\n  if (!moduleName) {\n    return <Empty description=\"DynamicCards: a moduleName prop is required\" />;\n  }\n\n  return (\n    <div className=\"dyn-cards\">\n      <ModuleCards\n        moduleName={moduleName}\n        title={title}\n        layout={layout}\n        columns={columns}\n        maxCount={maxCount}\n        request={request}\n        viewAll={viewAll}\n        staticData={staticData}\n        showTabs={showTabs}\n        dateRange={dateRange}\n        headerExtra={headerExtra}\n        rows={rows}\n        loading={loading}\n      />\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { Popover, Tree, Input, Button, Spin, Empty, Badge, Typography } from 'antd';\nimport { DownOutlined, FilterOutlined } from '@ant-design/icons';\nimport { getUserHierarchyTree } from '../../services/dashboardApi';\n\nconst { Text } = Typography;\n\n// Map the server's tree onto antd's {key,title,children} shape. The server has\n// already scoped and nested it  , so there is no tree-building to do here.\nfunction toTreeData(nodes) {\n  return (nodes ?? []).map((node) => ({\n    key: node.userId,\n    title: node.isSelf ? `${node.name} (You)` : node.name,\n    // Kept for search, which matches on name or email.\n    searchText: `${node.name} ${node.email ?? ''}`.toLowerCase(),\n    children: toTreeData(node.children),\n  }));\n}\n\n// Keep a node when it matches, or when any descendant does — so a match deep in\n// the tree stays reachable through its ancestors rather than being orphaned.\nfunction filterTree(nodes, term) {\n  const out = [];\n  for (const node of nodes) {\n    const children = filterTree(node.children ?? [], term);\n    if (node.searchText.includes(term) || children.length > 0) {\n      out.push({ ...node, children });\n    }\n  }\n  return out;\n}\n\nfunction collectKeys(nodes, acc = []) {\n  for (const node of nodes) {\n    acc.push(node.key);\n    collectKeys(node.children ?? [], acc);\n  }\n  return acc;\n}\n\n/**\n * A \"Filter by\" control: a checkbox tree of the account's users, nested by\n * reporting manager. Used by the dashboard to scope its cards/calendar to a\n * chosen set of users.\n *\n * Checking a manager selects their whole subtree. The backend expands and\n * re-checks that itself, so this is a convenience rather than the security\n * boundary — but it does mean what the user sees ticked is what gets counted.\n */\nexport default function HierarchyUserFilter({ value = [], onChange }) {\n  const [tree, setTree] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n  const [search, setSearch] = useState('');\n  const [open, setOpen] = useState(false);\n\n  useEffect(() => {\n    let alive = true;\n    getUserHierarchyTree()\n      .then((data) => {\n        if (alive) setTree(toTreeData(data?.users));\n      })\n      .catch((err) => {\n        if (alive) setError(err);\n      })\n      .finally(() => {\n        if (alive) setLoading(false);\n      });\n    return () => {\n      alive = false;\n    };\n  }, []);\n\n  const term = search.trim().toLowerCase();\n  const visible = useMemo(\n    () => (term && tree ? filterTree(tree, term) : tree),\n    [tree, term],\n  );\n\n  // While searching, expand everything so matches buried under a collapsed\n  // manager are actually visible.\n  const expandedProps = term ? { expandedKeys: collectKeys(visible ?? []) } : {};\n\n  const content = (\n    <div style={{ width: 280 }}>\n      <Input.Search\n        placeholder=\"Search users\"\n        allowClear\n        value={search}\n        onChange={(e) => setSearch(e.target.value)}\n        style={{ marginBottom: 8 }}\n      />\n\n      {loading && (\n        <div style={{ padding: 24, textAlign: 'center' }}>\n          <Spin size=\"small\" />\n        </div>\n      )}\n\n      {error && <Empty description=\"Could not load users\" />}\n\n      {!loading && !error && (visible?.length ? (\n        <div style={{ maxHeight: 280, overflow: 'auto' }}>\n          <Tree\n            checkable\n            selectable={false}\n            defaultExpandAll\n            treeData={visible}\n            checkedKeys={value}\n            // antd omits half-checked ancestors from the first argument, so read\n            // checkedNodes instead to get the fully-expanded id list — that is what\n            // makes \"check a manager => their whole team counts\" true on the wire.\n            onCheck={(_keys, info) => onChange(info.checkedNodes.map((n) => n.key))}\n            {...expandedProps}\n          />\n        </div>\n      ) : (\n        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=\"No users\" />\n      ))}\n\n      {value.length > 0 && (\n        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 8, paddingTop: 8, borderTop: '1px solid #f0f0f0' }}>\n          <Text type=\"secondary\">{value.length} selected</Text>\n          <Button type=\"link\" size=\"small\" onClick={() => onChange([])}>\n            Clear\n          </Button>\n        </div>\n      )}\n    </div>\n  );\n\n  return (\n    <Popover\n      content={content}\n      trigger=\"click\"\n      placement=\"bottomRight\"\n      open={open}\n      onOpenChange={setOpen}\n    >\n      <Badge count={value.length} size=\"small\" offset={[-4, 4]}>\n        <Button icon={<FilterOutlined />}>\n          Filter by <DownOutlined style={{ fontSize: 10 }} />\n        </Button>\n      </Badge>\n    </Popover>\n  );\n}\n","// Field-level \"force a value based on who is submitting\" rules.\n//\n// This is the FRONTEND half of an admin-configured feature (formGroupConfig →\n// field.autoValueRules), e.g. a submission's \"Submit Source\" that must read\n// External when an employer-type user submits and Internal for everyone else.\n//\n// It mirrors the backend exactly (models.AutoValueRule.Matches +\n// applyAutoValueRules in moduleWriteOrchestrator.go). The backend is the\n// authority — it re-evaluates these rules from the auth token on every\n// create/update, so a request that bypasses the UI is still corrected. This copy\n// exists purely so the user SEES the forced value while filling the form.\n//\n// Nothing here special-cases a module, field, role or value: which roleId/userId\n// maps to which value is entirely admin data.\n\n// autoValueFor evaluates a field's rules against the acting user's identity\n// ({roleId, userId}). whenRoleId and whenUserId are OR-ed; a rule with neither\n// set never fires. First matching rule wins — same as the backend.\nexport function autoValueFor(field, identity = {}) {\n  const rules = Array.isArray(field?.autoValueRules) ? field.autoValueRules : [];\n  for (const rule of rules) {\n    const roles = Array.isArray(rule?.whenRoleId) ? rule.whenRoleId.map(Number) : [];\n    const users = Array.isArray(rule?.whenUserId) ? rule.whenUserId.map(Number) : [];\n    const roleHit = identity.roleId !== undefined && roles.includes(identity.roleId);\n    const userHit = identity.userId !== undefined && users.includes(identity.userId);\n    if (roleHit || userHit) return { matched: true, value: rule.value };\n  }\n  return { matched: false, value: undefined };\n}\n\nexport default autoValueFor;\n","// ─────────────────────────────────────────────────────────────────────────\n// duplicateRecord — the client half of the staged duplicate check.\n//\n// The backend (POST /v1/module/duplicate-check) decides WHETHER a record is a\n// duplicate, entirely from the module's configured stages. This module decides\n// only how to SAY it, and it takes every word from config too:\n//\n//   automations.duplicateCheck.message  → the sentence, with {tokens}\n//   automations.duplicateCheck.policy   → \"prompt\" (offer to update) | \"block\"\n//   automations.duplicateCheck.displayFields → which keys name the record\n//\n// Nothing here knows a module, a field, or how long \"recently\" is.\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * describeAge — \"how stale is the existing record?\", in words.\n *\n * The requirement asks for exactly this: \"in the error message we need to show\n * last updated date — for example 60 days back the same candidate is updated,\n * like that — so we can get a proper idea that the candidate already was there\n * with the date.\"\n *\n * A bare date (\"07 Aug 2026\") makes the reader do the arithmetic; the elapsed\n * time is the part that carries the decision, so both are offered and the\n * caller's template chooses.\n */\nexport function describeAge(daysAgo) {\n  // null/undefined/'' must NOT fall through to Number()'s 0, which would render\n  // a record with no timestamp at all as \"updated today\" — a confident false\n  // statement about exactly the fact the user is being asked to judge.\n  if (daysAgo === null || daysAgo === undefined || daysAgo === '') return '';\n  const days = Number(daysAgo);\n  if (!Number.isFinite(days) || days < 0) return '';\n  if (days === 0) return 'today';\n  if (days === 1) return 'yesterday';\n  if (days < 30) return `${days} days ago`;\n  if (days < 60) return 'about a month ago';\n  if (days < 365) return `about ${Math.round(days / 30)} months ago`;\n  const years = Math.floor(days / 365);\n  return years === 1 ? 'over a year ago' : `over ${years} years ago`;\n}\n\n/**\n * describeRecord — a human label for the matched record, built from whichever\n * of the configured display fields actually carry a value.\n */\nexport function describeRecord(record, displayFields) {\n  const keys = Array.isArray(displayFields) && displayFields.length\n    ? displayFields\n    : Object.keys(record ?? {});\n  const parts = keys\n    .map((key) => record?.[key])\n    .map((v) => (v === null || v === undefined ? '' : String(v).trim()))\n    .filter(Boolean);\n  return parts.join(' · ');\n}\n\n/**\n * fillTemplate — {token} substitution. An unknown token is left INTACT so a\n * typo in admin config is visible rather than silently blanking the sentence.\n */\nexport function fillTemplate(template, tokens = {}) {\n  if (!template) return '';\n  return String(template).replace(\n    /\\{(\\w+)\\}/g,\n    (match, key) => (tokens[key] === undefined ? match : String(tokens[key])),\n  );\n}\n\n/**\n * duplicateTokens — everything a configured message may reference.\n */\nexport function duplicateTokens(result, displayFields) {\n  const name = describeRecord(result?.record, displayFields);\n  const age = describeAge(result?.updatedDaysAgo);\n  return {\n    name: name || 'an existing record',\n    age: age || 'previously',\n    days: Number.isFinite(Number(result?.updatedDaysAgo)) ? String(result.updatedDaysAgo) : '',\n    updatedOn: result?.updatedAt ? String(result.updatedAt).slice(0, 10) : '',\n    stage: result?.stage ?? '',\n    weight: result?.weight ?? '',\n  };\n}\n\n// Default wording, used until an admin writes their own. Deliberately states\n// BOTH the identity and the age, because those are the two things that let\n// someone decide whether this really is the same person.\nexport const DEFAULT_DUPLICATE_MESSAGE =\n  'We already have {name} on file \\u2014 last updated {age}. '\n  + 'You can carry on and update that record with what you\\u2019ve just entered, '\n  + 'or go back and check first.';\n\nexport const DEFAULT_BLOCK_MESSAGE =\n  'We already have {name} on file \\u2014 last updated {age}. '\n  + 'Please open that record and update it, rather than adding a second copy.';\n\n/**\n * duplicateMessage — the finished sentence for a result.\n */\nexport function duplicateMessage(result, cfg = {}) {\n  const tokens = duplicateTokens(result, cfg.displayFields);\n  const isBlock = (result?.policy ?? cfg.policy) === 'block';\n  const template = result?.message\n    || cfg.message\n    || (isBlock ? DEFAULT_BLOCK_MESSAGE : DEFAULT_DUPLICATE_MESSAGE);\n  return fillTemplate(template, tokens);\n}\n\n/**\n * duplicateBlocks — should the create be refused outright?\n *\n * The response's own policy wins (it comes from the module config the backend\n * actually applied); the caller's config is only a fallback for a backend that\n * predates the field. Default is \"prompt\", so a misconfiguration inconveniences\n * rather than blocks.\n */\nexport function duplicateBlocks(result, cfg = {}) {\n  if (!result?.duplicate) return false;\n  return (result.policy ?? cfg.policy ?? 'prompt') === 'block';\n}\n\n/**\n * duplicateFacts — the matched record as scannable label/value pairs.\n *\n * The prose sentence carries the same information, but a reader deciding \"is\n * this the same person?\" should not have to parse it out of a paragraph. The\n * facts that settle it are WHO and HOW STALE, so those are surfaced; whatever\n * else the module chose to display comes with them.\n *\n * Labels are derived from the key itself (\"firstName\" → \"First name\"), so a\n * module that adds a display field gets a sensible label with no extra config.\n */\nexport function duplicateFacts(result, displayFields) {\n  const record = result?.record ?? {};\n  const keys = Array.isArray(displayFields) && displayFields.length\n    ? displayFields\n    : Object.keys(record);\n\n  const facts = keys\n    .map((key) => ({ label: humanizeKey(key), value: record[key] }))\n    .filter((f) => f.label && f.value !== undefined && f.value !== null && String(f.value).trim() !== '');\n\n  const age = describeAge(result?.updatedDaysAgo);\n  if (age) facts.push({ label: 'Last updated', value: age });\n  return facts;\n}\n\n// humanizeKey — \"firstName\" / \"contact_number\" → \"First name\".\n// Only the first word is capitalised: these are labels in a list, not titles.\nfunction humanizeKey(key) {\n  const words = String(key ?? '')\n    .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n    .replace(/[_\\-.]+/g, ' ')\n    .trim()\n    .toLowerCase();\n  return words ? words.charAt(0).toUpperCase() + words.slice(1) : '';\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// useDuplicateCheck — \"have we got this person already?\", asked at the moment\n// it is useful.\n//\n// WHEN IT RUNS\n//   • right after a résumé has been read and the form filled in, because that\n//     is the first time an email and phone number exist to check;\n//   • again on submit, as the authoritative gate.\n//\n// WHAT IT SHOWS\n// A dialog naming the existing record and how long ago it was touched, with the\n// two things a user can actually do: open that record and update it (the new\n// file is kept as another version), or go back and look again. Every word comes\n// from the module's own config — see components/form/duplicateRecord.js.\n//\n// It FAILS OPEN. A check that cannot run (offline, a backend that predates the\n// endpoint, a module with no stages configured) must never stop someone\n// creating a legitimate record.\n// ─────────────────────────────────────────────────────────────────────────\nimport { useCallback, useRef, useState } from 'react';\nimport { checkDuplicateRecord } from '../../services/uniqueValidationApi';\nimport { duplicateMessage, duplicateBlocks, duplicateFacts } from './duplicateRecord';\nimport { openFormDecision, openFormNotice } from './formDecisionDialog';\n\n/**\n * @param {object}   opts\n * @param {object}   opts.form        the antd form instance\n * @param {string}   opts.moduleName  module being created\n * @param {string}  [opts.recordId]   set on EDIT, so a record never matches itself\n * @param {object}  [opts.config]     { message, policy, displayFields } fallback\n * @param {function}[opts.onUseExisting] called with the matched id when the user\n *                                       chooses to update the existing record\n */\nexport default function useDuplicateCheck({\n  form,\n  moduleName,\n  recordId,\n  config = {},\n  onUseExisting,\n} = {}) {\n  const [checking, setChecking] = useState(false);\n  // Remembers a match the user has already accepted, so submitting after\n  // choosing \"update the existing one\" does not ask the same question twice.\n  const acknowledged = useRef(null);\n\n  /**\n   * check — ask the backend.\n   *\n   * `payload` overrides the form's own values. That matters right after a\n   * résumé is read: the parsed email and phone exist in the RESPONSE and are\n   * not on the form yet, so checking the form would ask about a blank page.\n   */\n  const check = useCallback(async (payload) => {\n    if (!moduleName) return { duplicate: false };\n    setChecking(true);\n    try {\n      return await checkDuplicateRecord({\n        module: moduleName,\n        payload: payload ?? form.getFieldsValue(true) ?? {},\n        excludeId: recordId,\n      });\n    } finally {\n      setChecking(false);\n    }\n  }, [form, moduleName, recordId]);\n\n  /**\n   * prompt — run the check and, if something matches, ask.\n   *\n   * Resolves to:\n   *   'clear'    nothing matched — carry on\n   *   'existing' the user chose to update the record we already have\n   *   'blocked'  the module is set to refuse, or the user backed out\n   */\n  const prompt = useCallback(async ({ reason, payload, carry } = {}) => {\n    const result = await check(payload);\n    if (!result?.duplicate) {\n      acknowledged.current = null;\n      return 'clear';\n    }\n    if (acknowledged.current && acknowledged.current === result.id) return 'existing';\n\n    const body = duplicateMessage(result, config);\n    // The two things that actually decide the answer — WHO matched and HOW OLD\n    // that record is — are shown as facts rather than left inside the sentence.\n    const facts = duplicateFacts(result, config.displayFields);\n    // A stage-1 hit (email or phone) is near proof; a stage-2 hit (name only)\n    // is a maybe. Saying which stops both being read with the same weight.\n    const heading = result.weight === 'weak'\n      ? 'This might be someone you already have'\n      : 'You already have this person on file';\n\n    if (duplicateBlocks(result, config)) {\n      await openFormNotice({ tone: 'duplicate', title: heading, facts, body });\n      return 'blocked';\n    }\n\n    const useExisting = await openFormDecision({\n      tone: 'duplicate',\n      title: heading,\n      facts,\n      body,\n      // Naming the OUTCOMES rather than \"OK\"/\"Cancel\": the choice is between\n      // two different results, and neither is obviously the default.\n      okText: 'Open their record',\n      cancelText: 'Let me check first',\n      // Says what happens to the FILE, because that is the thing the user has\n      // just spent effort on and the thing they will assume is lost.\n      footnote: carry?.files\n        ? 'We\\u2019ll take you to their record with the r\\u00e9sum\\u00e9 you just uploaded already '\n          + 'attached \\u2014 save there to keep it. The one already on file is kept too, as an '\n          + 'earlier version. Nothing on this form has been filled in.'\n        : 'Everything already on their record is kept. Nothing on this form has been filled in.',\n    });\n\n    if (!useExisting) return 'blocked';\n    acknowledged.current = result.id ?? true;\n    // The whole result is handed over, because it carries `editRoute` — the\n    // configured path for opening the matched record. The caller must never\n    // derive that path; see DuplicateCheckStrategy.EditRoute.\n    // `carry` travels through untouched — today the file the user just\n    // uploaded, so it arrives with them at the existing record instead of\n    // having to be found and attached again.\n    onUseExisting?.(result.id, result, reason, carry);\n    return 'existing';\n  }, [check, config, onUseExisting]);\n\n  return { prompt, check, checking, acknowledgedId: acknowledged };\n}\n","// =============================================================================\n// The display name of an ALREADY-STORED file\n// -----------------------------------------------------------------------------\n// Legacy candidate schemas are NOT uniform about where a file's original name\n// lives, and the fileFieldMaps config says so out loud:\n//\n//   passport       passportUploadName          ← \"upload name\"\n//   alternateVisa  alternateVisaUploadName     ← \"upload name\"\n//   visa           visaUniqueName              ← \"UNIQUE name\" holds the\n//                                                 ORIGINAL name here\n//   resume         uploadedFileName\n//\n// Matching only on `*UploadName` therefore found nothing for a visa, the name\n// resolved to empty, and the form fell back to the literal string \"file\" — so a\n// submission prefilled from a candidate showed Passport and Alternate Visa\n// correctly and the Visa as an anonymous \"file\". The user could not tell what\n// had been attached, or whether it was the right document.\n//\n// Ordering matters as much as the keys. `*CopyUniqueName` holds the SANITISED\n// name (\"Resume_of_Vinoth_Satti.doc\"), so it is consulted last: it is better\n// than \"file\", but it is not what the user uploaded.\n// =============================================================================\n\n/** Suffix groups, best first. Each is matched case-insensitively. */\nconst NAME_KEY_SUFFIXES = [\n  // The original filename, under the two names the schemas give it.\n  ['uploadname', 'uploadedfilename', 'originalname', 'filename'],\n  // visa reuses \"unique name\" for the original — but NOT the \"copy unique\n  // name\", which is the sanitised form and is handled in the next group.\n  ['uniquename'],\n];\n\nconst SANITISED_SUFFIX = 'copyuniquename';\n\nfunction suffixMatch(key, suffixes, { excludeSanitised = false } = {}) {\n  const lower = String(key).toLowerCase();\n  if (excludeSanitised && lower.endsWith(SANITISED_SUFFIX)) return false;\n  return suffixes.some((suffix) => lower.endsWith(suffix));\n}\n\n/**\n * storedFileName — the name to show for a stored file container.\n *\n * Returns '' when the object carries no usable name, so the caller decides what\n * to do about that rather than being handed a placeholder that looks like data.\n */\nexport function storedFileName(value) {\n  if (!value || typeof value !== 'object') return '';\n\n  const direct = value.uploadedFileName ?? value.name;\n  if (typeof direct === 'string' && direct.trim()) return direct.trim();\n\n  const entries = Object.entries(value)\n    .filter(([, v]) => typeof v === 'string' && v.trim());\n\n  for (const suffixes of NAME_KEY_SUFFIXES) {\n    const hit = entries.find(([k]) => suffixMatch(k, suffixes, { excludeSanitised: true }));\n    if (hit) return hit[1].trim();\n  }\n  // Last resort: the sanitised copy name. Underscored and not what was\n  // uploaded, but it names the document, which \"file\" does not.\n  const sanitised = entries.find(([k]) => String(k).toLowerCase().endsWith(SANITISED_SUFFIX));\n  return sanitised ? sanitised[1].trim() : '';\n}\n\n/**\n * storedFileUrl — the storage location of a stored file container, under any of\n * the names the legacy schemas use.\n */\nexport function storedFileUrl(value) {\n  if (!value || typeof value !== 'object') return '';\n  const direct = value.location ?? value.url;\n  if (typeof direct === 'string' && direct.trim()) return direct.trim();\n  const hit = Object.entries(value).find(([k, v]) => (\n    typeof v === 'string' && v.trim() && String(k).toLowerCase().endsWith('copylocation')\n  ));\n  return hit ? hit[1].trim() : '';\n}\n","// const BASE_URL = 'http://192.168.1.66/submissionsapi/v1';\n// // const AUTH_URL = 'http://192.168.1.66/authapi/v1';\n// const JOBS_URL = 'http://192.168.1.66/jobsapi/v1';\n// // export const AUTH_URL = 'http://192.168.0.127:9009/authapi/v1';\n// export const AUTH_URL = 'http://192.168.1.66/authapi/v1';\n// export const SUBMISSIONS_URL = BASE_URL;\n\nimport { AUTH_URL, JOBS_URL, CANDIDATES_URL, SUBMISSIONS_URL, PYOPS_URL } from './apiConfig';\nimport { fetchJsonWithAuth as coreFetchJsonWithAuth, ensureToken as coreEnsureToken, logout as coreLogout } from './authApi';\nimport { fetchFormGroupsCached, invalidateFormGroupsCache } from './formGroupsCache';\nimport { getBaseModuleName } from '../utils/modulePath';\n\n\nconst AUTH_TOKEN_KEY = 'authToken';\nconst AUTH_USER_KEY = 'authUser';\nconst AUTH_LOGIN_SESSION_KEY = 'authLoginSession';\nconst LOGIN_STORAGE_KEYS = [\n  'access_token',\n  'refresh_token',\n  'id_token',\n  'token_type',\n  'expires_in',\n  'refresh_expires_in',\n  'menu',\n  'footermenu',\n  'menuPermission',\n  'default_values',\n  'roleId',\n  'companyName',\n  'preferred_Username',\n  'user_Email',\n  'userName',\n  'userId',\n  'tenantId',\n  'businessId',\n  'businessUnitId',\n  'activeKey',\n  'ct_project_id',\n  'ct_project_name',\n];\n\nconst CT_PROJECT_ID_KEY = 'ct_project_id';\nconst CT_PROJECT_NAME_KEY = 'ct_project_name';\n\nconst TEST_FLOW_MODULE = 'test-flows';\nconst TEST_FLOW_FIELDS = [\n  { value: 'module',      label: 'Module',      isVisible: true, type: 'text'   },\n  { value: 'flow',        label: 'Flow',        isVisible: true, type: 'text'   },\n  { value: 'step_order',  label: 'Step Order',  isVisible: true, type: 'number' },\n  { value: 'keyword',     label: 'Action',      isVisible: true, type: 'text'   },\n  { value: 'description', label: 'Description', isVisible: true, type: 'text'   },\n  { value: 'target',      label: 'Key',         isVisible: true, type: 'text'   },\n  { value: 'tags',        label: 'Tags',        isVisible: true, type: 'text'   },\n  { value: 'value',       label: 'Value',       isVisible: true, type: 'text'   },\n  { value: 'expected',    label: 'Expected',    isVisible: true, type: 'text'   },\n];\n\nconst LMS_FLOW_MODULE = 'lms-flows';\nconst LMS_FLOW_FIELDS = [\n  { value: 'module',      label: 'Module',      isVisible: true, type: 'text'   },\n  { value: 'flow',        label: 'Flow',        isVisible: true, type: 'text'   },\n  { value: 'step_order',  label: 'Step Order',  isVisible: true, type: 'number' },\n  { value: 'keyword',     label: 'Action',      isVisible: true, type: 'text'   },\n  { value: 'description', label: 'Description', isVisible: true, type: 'text'   },\n  { value: 'target',      label: 'Key',         isVisible: true, type: 'text'   },\n  { value: 'tags',        label: 'Tags',        isVisible: true, type: 'text'   },\n  { value: 'value',       label: 'Value',       isVisible: true, type: 'text'   },\n  { value: 'expected',    label: 'Expected',    isVisible: true, type: 'text'   },\n];\n\n// In-flight login promise — prevents multiple simultaneous login calls\nlet loginPromise = null;\nlet refreshPromise = null;\n\nfunction extractToken(json) {\n  return (\n    json?.token ??\n    json?.access_token ??\n    json?.accessToken ??\n    json?.jwt ??\n    json?.data?.token ??\n    json?.data?.access_token ??\n    json?.data?.accessToken ??\n    json?.data?.jwt\n  );\n}\n\nfunction extractUser(json) {\n  return json?.user ?? json?.data?.user ?? json?.data?.profile ?? null;\n}\n\nfunction decodeJwtPayload(token) {\n  if (!token || typeof token !== 'string') return null;\n\n  try {\n    const payload = token.split('.')[1];\n    if (!payload) return null;\n\n    const normalizedPayload = payload.replace(/-/g, '+').replace(/_/g, '/');\n    const decodedPayload = atob(normalizedPayload.padEnd(Math.ceil(normalizedPayload.length / 4) * 4, '='));\n    return JSON.parse(decodedPayload);\n  } catch (error) {\n    console.error('Unable to decode login token:', error);\n    return null;\n  }\n}\n\nfunction setLocalStorageJson(key, value) {\n  if (value === undefined || value === null) return;\n  localStorage.setItem(key, JSON.stringify(value));\n}\n\nfunction getLoginMenus(json, data) {\n  return data?.menus ?? json?.menus ?? {\n    menu: data?.menu ?? json?.menu,\n    footermenu: data?.footermenu ?? json?.footermenu,\n  };\n}\n\nfunction persistLoginResponse(json, token, user) {\n  // Keep role/menu state tied to the current login only. Clearing these first\n  // prevents stale menu data from a previous user from leaking into the next\n  // session when a response omits one of the optional menu fields.\n  ['menu', 'footermenu', 'menuPermission', 'default_values', 'activeKey'].forEach((key) => {\n    localStorage.removeItem(key);\n  });\n\n  const data = json?.data ?? json;\n  const tokenPayload = decodeJwtPayload(token) ?? {};\n  const menus = getLoginMenus(json, data);\n  const userName = (\n    user?.userName ??\n    user?.name ??\n    data?.userName ??\n    data?.name ??\n    tokenPayload.userName ??\n    tokenPayload.name ??\n    tokenPayload.preferred_username ??\n    tokenPayload.email\n  );\n  const preferredUsername = (\n    user?.preferred_Username ??\n    user?.preferred_username ??\n    data?.preferred_Username ??\n    data?.preferred_username ??\n    tokenPayload.preferred_Username ??\n    tokenPayload.preferred_username ??\n    tokenPayload.email ??\n    userName\n  );\n  const userEmail = user?.email ?? data?.email ?? tokenPayload.email ?? preferredUsername;\n\n  localStorage.setItem('access_token', token);\n  if (data?.refresh_token) localStorage.setItem('refresh_token', data.refresh_token);\n  if (data?.id_token !== undefined) localStorage.setItem('id_token', data.id_token);\n  if (data?.token_type) localStorage.setItem('token_type', data.token_type);\n  if (data?.expires_in !== undefined) localStorage.setItem('expires_in', String(data.expires_in));\n  if (data?.refresh_expires_in !== undefined) localStorage.setItem('refresh_expires_in', String(data.refresh_expires_in));\n  if (userName) localStorage.setItem('userName', userName);\n  if (preferredUsername) localStorage.setItem('preferred_Username', preferredUsername);\n  if (userEmail) localStorage.setItem('user_Email', userEmail);\n  if (data?.roleId ?? tokenPayload.role_id) localStorage.setItem('roleId', data?.roleId ?? tokenPayload.role_id);\n  if (data?.companyName) localStorage.setItem('companyName', data.companyName);\n  if (tokenPayload.userId !== undefined) localStorage.setItem('userId', String(tokenPayload.userId));\n  if (tokenPayload.tenantId) localStorage.setItem('tenantId', tokenPayload.tenantId);\n  if (tokenPayload.businessId) localStorage.setItem('businessId', tokenPayload.businessId);\n  if (tokenPayload.businessUnitId) localStorage.setItem('businessUnitId', tokenPayload.businessUnitId);\n\n  setLocalStorageJson('menu', menus.menu);\n  setLocalStorageJson('footermenu', menus.footermenu);\n  setLocalStorageJson('menuPermission', data?.menuPermission);\n  setLocalStorageJson('default_values', data?.default_values);\n}\n\nexport function getStoredToken() {\n  // localStorage is shared across tabs/windows for the same origin.\n  // sessionStorage is tab-scoped, so using it as an auth prerequisite makes\n  // a newly opened window appear logged out even when the token is valid.\n  return localStorage.getItem(AUTH_TOKEN_KEY);\n}\n\nexport async function getGroupedVendorHotlist({ jobId, limit = 10, offset = 0, sortBy = 'new', type = 'myVendor' }) {\n  const json = await fetchJsonWithAuth(JOBS_URL, '/vendor/hotlist', {\n    method: 'POST',\n    body: JSON.stringify({ jobId, limit, offset, sortBy, type }),\n  });\n  return json;\n}\n\nexport async function getBulkMailDetails(jobId) {\n  const json = await fetchJsonWithAuth(CANDIDATES_URL, `/get-bulkmail-details?jobId=${encodeURIComponent(jobId)}`);\n  return json.data ?? json;\n}\n\nexport async function formatMailContentForMail(contents, subject = '') {\n  const input = String(contents ?? '').trim();\n  if (!input) return '';\n\n  const json = await fetchJsonWithAuth(PYOPS_URL, '/format-mail-content', {\n    method: 'POST',\n    body: JSON.stringify({ contents: input, subject: String(subject ?? '') }),\n  });\n\n  if (json?.status === false) {\n    throw new Error(json?.error || 'Unable to format mail content');\n  }\n\n  return String(json?.html ?? json?.contents ?? json?.data?.html ?? json?.data?.contents ?? '').trim();\n}\n\n// Backward-compatible export for any host code that imported the previous name.\n// It now formats the existing mail body rather than generating/re-writing a JD.\nexport async function formatJobDescriptionForMail(contents, subject = '') {\n  return formatMailContentForMail(contents, subject);\n}\n\nexport async function sendBulkMail({ jobId, toMail, ccMail, bccMail, subject, contents, attachments = [] }) {\n  const tenantId = localStorage.getItem('tenantId') || '93c782a4aa626175e5d11afa';\n  const businessId = localStorage.getItem('businessId') || '83c782a4aa626175e5d11afa';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '63b57588fd768a839dbc0f63';\n\n  const formData = new FormData();\n  formData.append('json', JSON.stringify({\n    schemaVersion: 1,\n    tenantId,\n    businessId,\n    businessUnitId,\n    jobId,\n    toMail,\n    ccMail,\n    bccMail,\n    contents,\n    subject,\n  }));\n\n  // Dynamic document placeholders are resolved to File objects by the mail\n  // composer. Append them as multipart files so they are sent as real email\n  // attachments instead of being rendered as text inside the mail body.\n  (attachments ?? []).forEach((file) => {\n    if (file instanceof File) formData.append('attachments', file, file.name);\n  });\n\n  // Exclude Content-Type so the browser sets multipart/form-data with the correct boundary\n  const allHeaders = await authHeaders();\n  const { 'Content-Type': _ct, ...headersWithoutContentType } = allHeaders;\n\n  let res = await fetch(`${CANDIDATES_URL}/send-bulkmail`, {\n    method: 'POST',\n    headers: headersWithoutContentType,\n    body: formData,\n  });\n\n  if (res.status === 401) logout();\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  const text = await res.text();\n  return text ? JSON.parse(text) : {};\n}\n\n\nexport function logout() {\n  coreLogout();\n}\n\n// ---- Role helpers ----\n// The login response carries the role NAME in `data.roleId`\n// (persistLoginResponse stores it in localStorage['roleId']). The access-token\n// claims only have a numeric `role_id`, so the stored role NAME is the reliable\n// signal for the tester check. JWT roles are kept as a fallback.\nexport function getCurrentRoleName() {\n  return String(localStorage.getItem('roleId') ?? '').trim().toLowerCase();\n}\n\nexport function getUserRoles() {\n  const token = localStorage.getItem(AUTH_TOKEN_KEY);\n  const payload = decodeJwtPayload(token);\n\n  const roles = new Set();\n\n  const stored = getCurrentRoleName();\n  if (stored) roles.add(stored);\n\n  if (payload) {\n    (payload?.realm_access?.roles ?? []).forEach((role) => roles.add(role));\n    Object.values(payload?.resource_access ?? {}).forEach((client) => {\n      (client?.roles ?? []).forEach((role) => roles.add(role));\n    });\n    [payload?.role, payload?.roleName, payload?.role_name].forEach((role) => {\n      if (role) roles.add(role);\n    });\n  }\n\n  return Array.from(roles).map((role) => String(role).toLowerCase());\n}\n\nexport function isTester() {\n  return getCurrentRoleName() === 'tester' || getUserRoles().includes('tester');\n}\n\nfunction isEnabledPermission(value) {\n  return value === true || value === 1 || value === '1';\n}\n\nexport function hasAllJobsPermission() {\n  try {\n    const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    if (!permissions || typeof permissions !== 'object') return false;\n\n    const jobsKey = Object.keys(permissions).find((key) => {\n      const normalized = String(key).trim().toLowerCase();\n      return normalized === 'job' || normalized === 'jobs';\n    });\n    const jobsPermissions = jobsKey ? permissions[jobsKey] : null;\n    if (!jobsPermissions || typeof jobsPermissions !== 'object') return false;\n\n    return isEnabledPermission(\n      jobsPermissions.all_jobs\n      ?? jobsPermissions.allJobs\n      ?? jobsPermissions.alljobs,\n    );\n  } catch {\n    return false;\n  }\n}\n\nexport function resolveJobListScope(requestedScope = '') {\n  const scope = String(requestedScope ?? '').trim();\n\n  // Preserve the tab the user actually selected. The API is authoritative\n  // for access control and already narrows an unauthorised allJobs request to\n  // My Jobs. Re-checking permissions from localStorage here is unreliable:\n  // login payloads differ across deployments, so a user whose API response\n  // legitimately contains the All Jobs tab could still have that request\n  // silently rewritten to myJobs by stale or differently-shaped cached data.\n  if (scope === 'myJobs' || scope === 'allJobs' || scope === 'fulfilled') return scope;\n\n  // With no explicit tab, let the API choose the permission-aware default.\n  return '';\n}\n\nfunction isJobsModule(module) {\n  const baseModule = String(getBaseModuleName(module) ?? '').trim().toLowerCase();\n  return baseModule === 'job' || baseModule === 'jobs';\n}\n\n// ---- Selected project context (carried through the tester flow) ----\nexport function setSelectedProject(project) {\n  if (!project) return;\n  localStorage.setItem(CT_PROJECT_ID_KEY, String(project.id));\n  localStorage.setItem(CT_PROJECT_NAME_KEY, String(project.name));\n}\n\nexport function getSelectedProject() {\n  const id = localStorage.getItem(CT_PROJECT_ID_KEY);\n  const name = localStorage.getItem(CT_PROJECT_NAME_KEY);\n  if (!id || !name) return null;\n  return { id: Number(id), name };\n}\n\nexport function clearSelectedProject() {\n  localStorage.removeItem(CT_PROJECT_ID_KEY);\n  localStorage.removeItem(CT_PROJECT_NAME_KEY);\n}\n\nexport async function login(credentials) {\n  if (loginPromise) return loginPromise;\n\n  loginPromise = fetch(`${AUTH_URL}/login`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify(credentials),\n  })\n    .then(async (res) => {\n      const json = await res.json();\n      if (!res.ok) {\n        const error = new Error(json?.message ?? json?.error ?? `Login failed: ${res.status}`);\n        error.status = res.status;\n        throw error;\n      }\n\n      const token = extractToken(json);\n      if (!token) throw new Error('No token in login response');\n      const user = extractUser(json);\n\n      localStorage.setItem(AUTH_TOKEN_KEY, token);\n      sessionStorage.setItem(AUTH_LOGIN_SESSION_KEY, '1');\n      if (user) localStorage.setItem(AUTH_USER_KEY, JSON.stringify(user));\n      persistLoginResponse(json, token, user);\n\n      return { token, user, response: json };\n    })\n    .finally(() => {\n      loginPromise = null;\n    });\n\n  return loginPromise;\n}\n\n\nfunction tokenExpiresSoon(token, skewSeconds = 30) {\n  const payload = decodeJwtPayload(token);\n  const exp = Number(payload?.exp);\n  if (!Number.isFinite(exp) || exp <= 0) return false;\n  return (exp * 1000) <= (Date.now() + (skewSeconds * 1000));\n}\n\nfunction persistRefreshedAccessToken(json) {\n  const token = extractToken(json);\n  if (!token) return '';\n\n  localStorage.setItem(AUTH_TOKEN_KEY, token);\n  localStorage.setItem('access_token', token);\n\n  const data = json?.data ?? json;\n  const expiresIn = data?.expires_in ?? data?.accessTokenExpiresIn;\n  if (expiresIn !== undefined) localStorage.setItem('expires_in', String(expiresIn));\n\n  window.dispatchEvent(new Event('auth:token-refreshed'));\n  return token;\n}\n\nasync function refreshAccessToken() {\n  if (refreshPromise) return refreshPromise;\n\n  const refreshToken = String(localStorage.getItem('refresh_token') ?? '').trim();\n  if (!refreshToken) {\n    const error = new Error('Session expired');\n    error.status = 401;\n    throw error;\n  }\n\n  refreshPromise = fetch(`${AUTH_URL}/generate-refresh-token`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ refresh_token: refreshToken }),\n  })\n    .then(async (res) => {\n      let json = {};\n      try {\n        json = await res.json();\n      } catch {\n        json = {};\n      }\n\n      if (!res.ok) {\n        const error = new Error(json?.error ?? json?.message ?? `Token refresh failed: ${res.status}`);\n        error.status = res.status;\n        throw error;\n      }\n\n      const token = persistRefreshedAccessToken(json);\n      if (!token) {\n        const error = new Error('Token refresh response did not contain an access token');\n        error.status = 401;\n        throw error;\n      }\n      return token;\n    })\n    .finally(() => {\n      refreshPromise = null;\n    });\n\n  return refreshPromise;\n}\n\nasync function ensureToken() {\n  return coreEnsureToken();\n}\n\nasync function authHeaders() {\n  const token = await ensureToken();\n  return {\n    'Content-Type': 'application/json',\n    'Authorization': `Bearer ${token}`,\n  };\n}\n\nexport async function fetchJsonWithAuth(baseUrl, path, options = {}) {\n  return coreFetchJsonWithAuth(baseUrl, path, options);\n}\n\nexport async function apiGetWithAuth(baseUrl, path) {\n  const json = await fetchJsonWithAuth(baseUrl, path);\n  return json.data ?? json;\n}\n\nasync function apiGet(path) {\n  return apiGetWithAuth(SUBMISSIONS_URL, path);\n}\n\nasync function authapiGet(path) {\n  return apiGetWithAuth(AUTH_URL, path);\n}\n\nasync function authapiPost(path, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, path, {\n    method: 'POST',\n    body: JSON.stringify(payload),\n  });\n  return json.data ?? json;\n}\n\nasync function authapiPut(path, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, path, {\n    method: 'PUT',\n    body: JSON.stringify(payload),\n  });\n  return json.data ?? json;\n}\n\n/**\n * Fetch available filter fields for a module.\n * Returns: [{ label, value, type }, ...]\n */\nexport async function getDropdownFields(module) {\n  if (module === TEST_FLOW_MODULE) return TEST_FLOW_FIELDS;\n  if (module === LMS_FLOW_MODULE) return LMS_FLOW_FIELDS;\n\n  // Dot-notation names (\"job.client\") target nested data client-side; the\n  // backend only knows the base module.\n  return apiGet(`/filter-dropdown-fields?module=${encodeURIComponent(getBaseModuleName(module))}`);\n}\n\nexport async function getFieldConfig(module, { configType, userId, roleId } = {}) {\n  if (module === TEST_FLOW_MODULE) return TEST_FLOW_FIELDS;\n  if (module === LMS_FLOW_MODULE) return LMS_FLOW_FIELDS;\n\n  const params = new URLSearchParams({ module: getBaseModuleName(module) });\n  if (configType) params.set('configType', configType);\n  if (userId != null) params.set('userId', String(userId));\n  if (roleId != null) params.set('roleId', String(roleId));\n  return authapiGet(`/admin/field-config?${params}`);\n}\n\n\nexport async function getTestingOptions(type) {\n  return authapiGet(`/testing-modules?type=${encodeURIComponent(type)}`);\n}\n\nexport async function addTestingOption({ name, type }) {\n  return authapiPost('/testing-modules', { name, type });\n}\n\nexport async function addTestFlow(payload) {\n  return authapiPost('/test-flows', payload);\n}\n\nexport async function getTestFlows({\n  limit = 10,\n  offset = 0,\n  search = '',\n  module = '',\n  keyword = '',\n  tags = '',\n  active,\n} = {}) {\n  const params = new URLSearchParams({\n    limit: String(limit),\n    offset: String(offset),\n  });\n  if (search) params.append('search', search);\n  if (module) params.append('module', module);\n  if (keyword) params.append('keyword', keyword);\n  if (tags) params.append('tags', tags);\n  if (active !== undefined && active !== null && active !== '') {\n    params.append('active', String(active));\n  }\n\n  return authapiGet(`/test-flows?${params.toString()}`);\n}\n\n// =====================================================================\n// Common Test Automation (znxt_test_automation)\n// Hierarchy: Project -> Module -> Submodule -> Test Flow\n// =====================================================================\n\n// ---- Projects ----\nexport async function getCTProjects({ activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/projects${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTProject(projectname) {\n  return authapiPost('/ct/projects', { projectname });\n}\n\nexport async function setCTProjectStatus(id, active) {\n  return authapiPut('/ct/projects/status', { id, active });\n}\n\n// ---- Modules ----\nexport async function getCTModules({ project = '', activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (project) params.append('project', project);\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/modules${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTModule({ project, modulename }) {\n  return authapiPost('/ct/modules', { project, modulename });\n}\n\nexport async function setCTModuleStatus(id, active) {\n  return authapiPut('/ct/modules/status', { id, active });\n}\n\n// ---- Submodules ----\nexport async function getCTSubmodules({ project = '', module = '', activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (project) params.append('project', project);\n  if (module) params.append('module', module);\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/submodules${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTSubmodule({ project, modulename, submodulename }) {\n  return authapiPost('/ct/submodules', { project, modulename, submodulename });\n}\n\nexport async function setCTSubmoduleStatus(id, active) {\n  return authapiPut('/ct/submodules/status', { id, active });\n}\n\n// ---- Test Flows ----\nexport async function getCTFlows({\n  project = '',\n  module = '',\n  submodule = '',\n  product_parent_ID = '',\n  module_parent_ID = '',\n  submodule_parent_ID = '',\n  actions = '',\n  search = '',\n  active,\n  limit = 1000,\n  offset = 0,\n} = {}) {\n  const params = new URLSearchParams({\n    limit: String(limit),\n    offset: String(offset),\n  });\n  const productParentID = product_parent_ID || project;\n  const moduleParentID = module_parent_ID || module;\n  const submoduleParentID = submodule_parent_ID || submodule;\n  if (productParentID) params.append('product_parent_ID', productParentID);\n  if (moduleParentID) params.append('module_parent_ID', moduleParentID);\n  if (submoduleParentID) params.append('submodule_parent_ID', submoduleParentID);\n  if (actions) params.append('actions', actions);\n  if (search) params.append('search', search);\n  if (active !== undefined && active !== null && active !== '') {\n    params.append('active', String(active));\n  }\n  return authapiGet(`/ct/flows?${params.toString()}`);\n}\n\nexport async function addCTFlow(payload) {\n  return authapiPost('/ct/flows', payload);\n}\n\nexport async function getCTNextStep({\n  project,\n  module,\n  submodule,\n  product_parent_ID,\n  module_parent_ID,\n  submodule_parent_ID,\n}) {\n  const params = new URLSearchParams({\n    product_parent_ID: String(product_parent_ID || project),\n    module_parent_ID: String(module_parent_ID || module),\n    submodule_parent_ID: String(submodule_parent_ID || submodule),\n  });\n  return authapiGet(`/ct/flows/next-step?${params.toString()}`);\n}\n\nexport async function addLmsFlow(payload) {\n  return authapiPost('/lms-flows', payload);\n}\n\nexport async function getLmsFlows({\n  limit = 10,\n  offset = 0,\n  search = '',\n  module = '',\n  keyword = '',\n  tags = '',\n  active,\n} = {}) {\n  const params = new URLSearchParams({\n    limit: String(limit),\n    offset: String(offset),\n  });\n  if (search) params.append('search', search);\n  if (module) params.append('module', module);\n  if (keyword) params.append('keyword', keyword);\n  if (tags) params.append('tags', tags);\n  if (active !== undefined && active !== null && active !== '') {\n    params.append('active', String(active));\n  }\n\n  return authapiGet(`/lms-flows?${params.toString()}`);\n}\n\nexport async function getModuleDataList(module, limit = 10, offset = 0, options = {}) {\n  const {\n    scope = '',\n    sort = '',\n    sortDir = '',\n    search = '',\n    filters = [],\n    queryParams = {},\n  } = options;\n\n  if (module === TEST_FLOW_MODULE) {\n    const data = await getTestFlows({ limit, offset });\n    const rows = Array.isArray(data?.items) ? data.items : [];\n    const total = Number(data?.total) || 0;\n\n    return {\n      items: rows,\n      total,\n      limit,\n      offset,\n      tabs: [{ key: 'all', title: 'Test Cases', count: total }],\n    };\n  }\n\n  if (module === LMS_FLOW_MODULE) {\n    const data = await getLmsFlows({ limit, offset });\n    const rows = Array.isArray(data?.items) ? data.items : [];\n    const total = Number(data?.total) || 0;\n\n    return {\n      items: rows,\n      total,\n      limit,\n      offset,\n      tabs: [{ key: 'all', title: 'LMS Cases', count: total }],\n    };\n  }\n\n  const params = new URLSearchParams({\n    module: getBaseModuleName(module),\n    limit: String(limit),\n    offset: String(offset),\n  });\n  // The shared Jobs page uses the singular module name (`job`) while some\n  // consumers use `jobs`. Both names target the same backend module and must\n  // go through the same permission-aware My Jobs / All Jobs scope resolver.\n  const normalizedScope = isJobsModule(module)\n    ? resolveJobListScope(scope)\n    : String(scope ?? '').trim();\n  if (normalizedScope) params.set('scope', normalizedScope);\n  if (sort) params.set('sort', sort);\n  if (sortDir) params.set('sortDir', sortDir);\n  // Server-side quick search across visible + lookup-resolved fields\n  // (job title, client name, location, ...) — see /module-data-list.\n  if (String(search ?? '').trim()) params.set('search', String(search).trim());\n\n  const conditions = toFilterConditions(filters.filter((f) => f?.field));\n  if (conditions.length) {\n    params.set('filters', JSON.stringify(conditions));\n  }\n\n  Object.entries(queryParams ?? {}).forEach(([key, value]) => {\n    if (value !== null && value !== undefined && String(value).trim() !== '') {\n      params.set(key, String(value));\n    }\n  });\n\n  const json = await fetchJsonWithAuth(AUTH_URL, `/module-data-list?${params.toString()}`);\n\n  const responseData = getResponseRows(json);\n  const hasObjectSkills = responseData.some((record) => hasObjectSkillItems(record));\n  const hasDiceCandidates = responseData.some((record) => hasDiceSource(record));\n\n  if (hasObjectSkills || hasDiceCandidates) {\n    try {\n      const { transformDiceResponseToInternalFormat } = await import('./diceCandidateMapper');\n      const transformed = transformDiceResponseToInternalFormat(json, json);\n      const transformedData = transformed?.data?.data ?? [];\n      // const total = extractResponseTotal(json, scope || 'internal')\n      //   || extractResponseTotal(transformed, scope || 'internal')\n      const total = extractResponseTotal(json, normalizedScope)\n        || extractResponseTotal(transformed, normalizedScope)\n        || transformedData.length;\n\n      return {\n        items: transformedData,\n        total,\n        limit,\n        offset,\n        tabs: transformed?.data?.tabs ?? json?.tabs ?? json?.data?.tabs ?? [],\n        fields: transformed?.data?.fields ?? json?.fields ?? json?.data?.fields ?? [],\n        tabField: transformed?.data?.tabField ?? json?.tabField ?? json?.data?.tabField ?? '',\n        actionRules: transformed?.data?.actionRules ?? json?.data?.actionRules ?? [],\n        actions: transformed?.data?.actions ?? json?.data?.actions ?? [],\n        columnActions: transformed?.data?.columnActions ?? json?.data?.columnActions ?? [],\n      };\n    } catch (error) {\n      console.error('[getModuleDataList] Dice transformation failed:', error);\n    }\n  }\n  \n  return json;\n}\n\nfunction getResponseRows(response) {\n  const payload = response?.data ?? response;\n  const rows = Array.isArray(payload)\n    ? payload\n    : payload?.rows\n    ?? payload?.records\n    ?? payload?.items\n    ?? payload?.list\n    ?? payload?.data\n    ?? response?.items\n    ?? response?.records\n    ?? [];\n\n  return Array.isArray(rows) ? rows : [];\n}\n\nfunction firstFiniteNumber(...values) {\n  for (const value of values) {\n    const number = Number(value);\n    if (Number.isFinite(number)) return number;\n  }\n\n  return undefined;\n}\n\nfunction extractResponseTotal(response, scope = '') {\n  const payload = response?.data ?? response;\n  const rows = getResponseRows(response);\n  const responseCount = response?.count;\n  const payloadCount = payload?.count;\n  const normalizedScope = String(scope ?? '').trim().toLowerCase();\n\n  if (responseCount && typeof responseCount === 'object') {\n    const total = firstFiniteNumber(\n      normalizedScope ? responseCount[normalizedScope] : undefined,\n      responseCount.total,\n      responseCount.searchCount,\n      responseCount.count,\n    );\n    if (total !== undefined) return total;\n  }\n\n  if (payloadCount && typeof payloadCount === 'object') {\n    const total = firstFiniteNumber(\n      normalizedScope ? payloadCount[normalizedScope] : undefined,\n      payloadCount.total,\n      payloadCount.searchCount,\n      payloadCount.count,\n    );\n    if (total !== undefined) return total;\n  }\n\n  return firstFiniteNumber(\n    response?.total,\n    typeof responseCount !== 'object' ? responseCount : undefined,\n    response?.totalCount,\n    payload?.total,\n    typeof payloadCount !== 'object' ? payloadCount : undefined,\n    payload?.totalCount,\n    rows.length,\n  ) ?? 0;\n}\n\nfunction hasObjectSkillItems(record) {\n  const skills = record?.skills ?? record?.technicalSkills ?? record?.primarySkills;\n  if (!Array.isArray(skills) || skills.length === 0) return false;\n\n  return skills.some((skill) => (\n    skill\n    && typeof skill === 'object'\n    && ('skill' in skill || 'lastUsed' in skill)\n  ));\n}\n\nfunction hasDiceSource(record) {\n  const sourceFields = [\n    record?.sourceType,\n    record?.profileSource,\n    record?.selectedSource,\n    record?.customFields?.sourceType,\n    record?.customFields?.profileSource,\n  ].flat();\n  \n  return sourceFields.some(\n    (value) => String(value ?? '').trim().toLowerCase() === 'dice',\n  ) || Boolean(record?.customFields?.diceProfileData);\n}\n\nexport async function getJobSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n\n  const query = params.toString();\n  return apiGetWithAuth(JOBS_URL, `/job-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getCandidateSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n\n  const query = params.toString();\n  return apiGetWithAuth(CANDIDATES_URL, `/profile-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getSubmissionSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n\n  const query = params.toString();\n  return apiGetWithAuth(SUBMISSIONS_URL, `/profile-summary${query ? `?${query}` : ''}`);\n}\n\n// Converts frontend filter rows to the BE FilterCondition[] format.\n// BE ops: eq | ne | in | nin | contains | gt | gte | lt | lte | isEmpty | notEmpty\nfunction toFilterConditions(filterRows) {\n  const conditions = [];\n  for (const row of filterRows) {\n    if (!row.field) continue;\n\n    // The row connector ('and'/'or') between this row and the previous one.\n    // 'isEmpty'/'notEmpty' rows use the operator slot for their op type, so they\n    // don't have an explicit AND/OR connector — default them to 'and'.\n    const rowConnector = row.operator === 'or' ? 'or' : 'and';\n\n    if (row.operator === 'isEmpty') {\n      conditions.push({ field: row.field, op: 'isEmpty', operator: 'and' });\n      continue;\n    }\n    if (row.operator === 'notEmpty') {\n      conditions.push({ field: row.field, op: 'notEmpty', operator: 'and' });\n      continue;\n    }\n\n    // Text keyword search → contains (case-insensitive regex on the backend)\n    if (row.filterInputType === 'text') {\n      const val = typeof row.value === 'string' ? row.value.trim() : '';\n      if (val) conditions.push({ field: row.field, op: 'contains', value: val, operator: rowConnector });\n      continue;\n    }\n\n    // Date range — from/to set by DatePicker.RangePicker.\n    // The row connector applies to the first (gte) condition; lte is always\n    // AND'd with it so the two bounds stay paired in the backend fold.\n    if (row.from || row.to) {\n      if (row.from) conditions.push({ field: row.field, op: 'gte', value: String(row.from), operator: rowConnector });\n      if (row.to)   conditions.push({ field: row.field, op: 'lte', value: String(row.to),   operator: 'and' });\n      continue;\n    }\n\n    // Multi-value (dropdown / checkbox / boolean) → in\n    if (Array.isArray(row.values) && row.values.length > 0) {\n      conditions.push({\n        field: row.field,\n        op: 'in',\n        values: row.values.map(String),\n        operator: rowConnector,\n        ...(Array.isArray(row.groupFields) && row.groupFields.length > 1 ? { groupFields: row.groupFields } : {}),\n      });\n    }\n  }\n  return conditions;\n}\n\n/**\n * Fetch distinct values for a specific field in a module.\n * Returns: [{ label, value }, ...]\n */\nexport async function getDropdownValues(module, field, search = '', meta = {}) {\n  const { limit = 50, offset = 0, dataSource, groupName, lookup, groupFields = [], groupSeparator = ' ' } = meta;\n  const params = new URLSearchParams({\n    module: getBaseModuleName(module),\n    field,\n    value: search,\n    limit: String(limit),\n    offset: String(offset),\n  });\n  if (dataSource) params.set('dataSource', dataSource);\n  if (Array.isArray(groupFields) && groupFields.length > 1) {\n    params.set('groupFields', groupFields.join(','));\n    params.set('groupSeparator', groupSeparator ?? ' ');\n  }\n  if (dataSource === 'group' && groupName) params.set('groupName', groupName);\n  if (dataSource === 'lookup' && lookup?.collection) {\n    params.set('lookupCollection', lookup.collection);\n    if (lookup.displayField) params.set('lookupField', lookup.displayField);\n  }\n  return apiGet(`/filter-dropdown-values?${params}`);\n}\n\nexport async function getDashboardOnboardingCount(\n  payload,\n  limit = 10,\n  offset = 0\n) {\n  const headers = await authHeaders();\n\n  const response = await fetch(\n    `${SUBMISSIONS_URL}/dashboard-onboarding-count?offset=${offset}&limit=${limit}`,\n    {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(payload),\n    }\n  );\n\n  const json = await response.json();\n  return json.data ?? json;\n}\n\nexport async function getJobs({\n  jobStatus = 'active',\n  jobRecruitmentStatus = 'unread',\n  limit = 50,\n  offset = 0,\n  userId = 1,\n  sortBy = 'id',\n} = {}) {\n  const headers = await authHeaders();\n\n  const params = new URLSearchParams({\n    jobStatus,\n    jobRecruitmentStatus,\n    limit: String(limit),\n    offset: String(offset),\n    userId: String(userId),\n    sortBy,\n  });\n\n  const response = await fetch(\n    `${JOBS_URL}/jobs?${params.toString()}`,\n    {\n      method: 'GET',\n      headers,\n    }\n  );\n\n  if (!response.ok) {\n    throw new Error(`API ${response.status}: ${response.statusText}`);\n  }\n\n  const json = await response.json();\n  return json.data ?? json;\n}\n\n\nfunction extractFormGroups(json) {\n  const payload = json?.data ?? json;\n  const groups = Array.isArray(payload) ? payload\n    : Array.isArray(payload?.groups) ? payload.groups\n      : Array.isArray(json?.groups) ? json.groups\n        : [];\n  // The backend attaches the loaded record's audit stamps (createdAt/updatedAt)\n  // as recordMeta when an id was supplied. Ride it along on the groups array so\n  // callers that only ever see the array (the detail header) can still show\n  // \"Created on …\" without audit fields having to exist as form fields.\n  const recordMeta = payload?.recordMeta ?? json?.recordMeta;\n  if (recordMeta && typeof recordMeta === 'object') groups.recordMeta = recordMeta;\n  return groups;\n}\n\nexport async function getFormGroups({\n  module,\n  id,\n  view,\n} = {}) {\n  if (!module) throw new Error('module is required to fetch form groups');\n\n  const headers = await authHeaders();\n\n  const params = new URLSearchParams({\n    module,\n  });\n\n  // When an id is supplied, the backend embeds each field's actual record value\n  // (field.value) in the response, so no separate detail-view call is needed.\n  if (id) params.set('id', String(id));\n\n  // `view=detail` opts into detail-view shaping: the backend resolves references\n  // to { id, value }, shapes documents into full objects, AND applies the admin\n  // Detail-Groups config (label/colour/prefix/hidden/lookups/merges). Without it\n  // the admin's customizations never reach the detail view. Forwarded only when\n  // provided, so add/edit-form callers keep the raw scalar values.\n  if (view) params.set('view', String(view));\n\n  // Shared with the form-side fetcher (services/formGroupsCache): the detail\n  // header, the detail body and the form on the same page routinely ask for the\n  // SAME payload, and these are 15-60 kB responses. Keyed by the finished URL,\n  // which both fetchers build in the same parameter order, so an identical\n  // question collapses to one request no matter which of them asked it — and a\n  // different `view`/scope stays a different entry.\n  const url = `${AUTH_URL}/admin/form-groups?${params.toString()}`;\n  const json = await fetchFormGroupsCached(url, async () => {\n    const response = await fetch(url, { method: 'GET', headers });\n    if (!response.ok) {\n      throw new Error(`API ${response.status}: ${response.statusText}`);\n    }\n    return response.json();\n  });\n  return extractFormGroups(json);\n}\n\nexport async function getCandidateFormGroups(options = {}) {\n  return getFormGroups({ module: 'candidates', ...options });\n}\n\nconst MODULE_EDIT_CONFIG = {\n    job: {\n        fetchUrl: (id) => `${JOBS_URL}/edit/detailed-view/${encodeURIComponent(id)}`,\n        updateUrl: (id) => `${JOBS_URL}/edit/${encodeURIComponent(id)}`,\n    },\n    candidates: {\n        fetchUrl: (id) => `${CANDIDATES_URL}/edit/detailed-view?_id=${encodeURIComponent(id)}`,\n        updateUrl: (id) => `${CANDIDATES_URL}/update?_id=${encodeURIComponent(id)}`,\n    },\n};\n\n\n\n\n\nexport async function getRecordForEdit(module, id) {\n  if (!module) throw new Error('module is required');\n  if (!id) throw new Error('id is required');\n\n  const config = MODULE_EDIT_CONFIG[module];\n  if (!config) throw new Error(`No edit config for module: ${module}`);\n\n  const token = await ensureToken();\n  const response = await fetch(config.fetchUrl(id), {\n    method: 'GET',\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: `Bearer ${token}`,\n    },\n  });\n\n  if (!response.ok) throw new Error(`API ${response.status}: ${response.statusText}`);\n\n  const json = await response.json();\n  return json.data ?? json;\n}\n\n\n\n\n\n\nexport async function updateRecord(module, id, payload) {\n  if (!module) throw new Error('module is required');\n  if (!id) throw new Error('id is required');\n\n  const config = MODULE_EDIT_CONFIG[module];\n  if (!config) throw new Error(`No edit config for module: ${module}`);\n\n  const token = await ensureToken();\n\n  const formData = new FormData();\n  formData.append('json', JSON.stringify(payload));\n\n  const response = await fetch(config.updateUrl(id), {\n    method: 'PUT',\n    headers: {\n      Authorization: `Bearer ${token}`,\n    },\n    body: formData,\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text();\n    console.error('[updateRecord] Error response:', errorText);\n    throw new Error(errorText || `API ${response.status}: ${response.statusText}`);\n  }\n\n  // A successful write makes every cached form-groups payload for this record\n  // stale, and the caller usually reads one straight back.\n  invalidateFormGroupsCache();\n\n  const json = await response.json();\n  return json.data ?? json;\n}\n\n\n\nexport async function uploadJobAttachment(recordId, file) {\n  const token = await ensureToken();\n\n  const formData = new FormData();\n  formData.append('jobId', recordId);\n  formData.append('file', file);\n\n  const response = await fetch(`${JOBS_URL}/jobs/${recordId}/attachment`, {\n    method: 'POST',\n    headers: {\n      Authorization: `Bearer ${token}`,\n      // DO NOT set Content-Type — browser sets it with boundary automatically\n    },\n    body: formData,\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text();\n    throw new Error(errorText || `API ${response.status}: ${response.statusText}`);\n  }\n\n  const json = await response.json();\n  return json.data ?? json;\n}\n\nexport async function addNotes({ notes, notesfor, receiver, notesRelatedId }) {\n  const tenantId = localStorage.getItem('tenantId') || '93c782a4aa626175e5d11afa';\n  const businessId = localStorage.getItem('businessId') || '83c782a4aa626175e5d11afa';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '63b57588fd768a839dbc0f63';\n\n  return fetchJsonWithAuth(JOBS_URL, '/notes', {\n    method: 'POST',\n    body: JSON.stringify({\n      schemaVersion: 1,\n      tenantId,\n      businessId,\n      businessUnitId,\n      notes,\n      notesfor,\n      receiver: receiver ?? [],\n      notesRelatedId,\n    }),\n  });\n}\n\nexport async function getCandidateGroups() {\n  return fetchJsonWithAuth(AUTH_URL, '/masters/dropdown?masterName=candidateGroups&offset=0&limit=50');\n}\n\nexport async function getSelfAssignData(jobId) {\n  return apiGetWithAuth(JOBS_URL, `/self-assign?jobId=${encodeURIComponent(jobId)}`);\n}\n\nexport async function getManagerUsers() {\n  const response = await apiGetWithAuth(JOBS_URL, '/users/manager');\n  if (Array.isArray(response)) return response;\n  return response ? [response] : [];\n}\n\nexport async function getRecruiterUsers(managerId = 0) {\n  return apiGetWithAuth(JOBS_URL, `/users/recruiter/${encodeURIComponent(managerId)}`);\n}\n\nexport async function selfAssignJob({ multiJobId, userId, schemaVersion, closureRating, jobPayDetails, priority, priorityFrom, recruitersData }) {\n  return fetchJsonWithAuth(JOBS_URL, '/assign?type=self', {\n    method: 'PUT',\n    body: JSON.stringify({\n      multiJobId,\n      userId: Number(userId),\n      schemaVersion,\n      closureRating,\n      jobPayDetails,\n      priority: String(priority ?? false),\n      priorityFrom: priorityFrom ?? '',\n      recruitersData: (recruitersData ?? []).map(Number).filter(Number.isInteger),\n    }),\n  });\n}\n\nexport async function assignJobToUser({ multiJobId, userId, schemaVersion, closureRating, jobPayDetails, priority, priorityFrom, recruitersData }) {\n  return fetchJsonWithAuth(JOBS_URL, '/assign?type=other', {\n    method: 'PUT',\n    body: JSON.stringify({\n      multiJobId,\n      userId: Number(userId),\n      schemaVersion,\n      closureRating,\n      jobPayDetails,\n      priority: String(priority ?? false),\n      priorityFrom: priorityFrom ?? '',\n      recruitersData: (recruitersData ?? []).map(Number).filter(Number.isInteger),\n    }),\n  });\n}\n\nexport async function addToGroup({ candidateIds, groupId, groupName }) {\n  return fetchJsonWithAuth(CANDIDATES_URL, '/actions/update-group', {\n    method: 'PUT',\n    body: JSON.stringify({ candidateIds, groupId, groupName }),\n  });\n}\n\n\nexport async function getJobList({ searchQuery, candidateId }) {\n  const tenantId = localStorage.getItem('tenantId') || '93c782a4aa626175e5d11afa';\n  const businessId = localStorage.getItem('businessId') || '83c782a4aa626175e5d11afa';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '63b57588fd768a839dbc0f63';\n  const userId = Number(localStorage.getItem('userId')) || 1;\n\n  return fetchJsonWithAuth(JOBS_URL, '/joblist', {\n    method: 'POST',\n    body: JSON.stringify({\n      tenantId,\n      businessId,\n      businessUnitId,\n      searchQuery,\n      userId,\n      candidateId: Array.isArray(candidateId) ? candidateId : [candidateId],\n    }),\n  });\n}\n\nexport async function tagToJob({ multiJobId, applicantId, updateStatus }) {\n  const tenantId = localStorage.getItem('tenantId') || '93c782a4aa626175e5d11afa';\n  const businessId = localStorage.getItem('businessId') || '83c782a4aa626175e5d11afa';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '63b57588fd768a839dbc0f63';\n  const userId = Number(localStorage.getItem('userId')) || 9;\n\n  return fetchJsonWithAuth(JOBS_URL, '/source/hiringStgUpdate', {\n    method: 'PUT',\n    body: JSON.stringify({\n      tenantId,\n      businessId,\n      businessUnitId,\n      multiJobId: Array.isArray(multiJobId) ? multiJobId : [multiJobId],\n      applicantId: Array.isArray(applicantId) ? applicantId : [applicantId],\n      updateStatus: String(updateStatus ?? '').toLowerCase(),\n      updateStatusType: 'call',\n      responseType: 'responded',\n      hiriringStatusChangeType: 'tagToJobs',\n      comments: '',\n      userId,\n    }),\n  });\n}\n\nexport async function deleteJobDetails(jobIds) {\n  const tenantId = localStorage.getItem('tenantId') || '93c782a4aa626175e5d11afa';\n  const businessId = localStorage.getItem('businessId') || '83c782a4aa626175e5d11afa';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '63b57588fd768a839dbc0f63';\n\n  return fetchJsonWithAuth(JOBS_URL, '/delete', {\n    method: 'POST',\n    body: JSON.stringify({\n      schemaVersion: 1,\n      tenantId,\n      businessId,\n      businessUnitId,\n      jobId: jobIds,\n    }),\n  });\n}\n\nexport async function deleteCandidateData(ids) {\n  const results = await Promise.all(\n    ids.map((id) => fetchJsonWithAuth(CANDIDATES_URL, `/delete?_id=${encodeURIComponent(id)}`, { method: 'PUT' }))\n  );\n  return results[results.length - 1] ?? {};\n}\n\nexport async function deleteModuleData(module, ids) {\n  return fetchJsonWithAuth(AUTH_URL, '/module-data-delete', {\n    method: 'POST',\n    body: JSON.stringify({ module, ids }),\n  });\n}\n\nexport async function getMentionUsers(search = '') {\n  const params = search ? `?search=${encodeURIComponent(search)}` : '';\n  return apiGetWithAuth(JOBS_URL, `/users/any${params}`);\n}\n\nexport async function searchCandidates(payload, offset = 0, limit = 10) {\n  console.log('[searchCandidates] Called with payload:', JSON.stringify(payload).substring(0, 200));\n  \n  const json = await fetchJsonWithAuth(\n    JOBS_URL,\n    `/source/hiring-candidate-list?offset=${offset}&limit=${limit}`,\n    { method: 'POST', body: JSON.stringify(payload) }\n  );\n  \n  console.log('[searchCandidates] Response received:', JSON.stringify(json).substring(0, 200));\n  \n  // Transform Dice responses to match Internal candidate format\n  const selectedSource = payload?.selectedSource ?? [];\n  const hasDiceSource = Array.isArray(selectedSource) && selectedSource.some(s => String(s).toLowerCase() === 'dice');\n  \n  console.log('[searchCandidates] selectedSource:', selectedSource);\n  console.log('[searchCandidates] hasDiceSource:', hasDiceSource);\n  \n  if (hasDiceSource) {\n    try {\n      console.log('[searchCandidates] Dice source detected, transforming response...');\n      console.log('[searchCandidates] Raw response structure:', json?.data?.data?.[0] ? Object.keys(json.data.data[0]) : 'No data');\n      console.log('[searchCandidates] Raw skills sample:', JSON.stringify(json?.data?.data?.[0]?.skills).substring(0, 150));\n      \n      const { transformDiceResponseToInternalFormat } = await import('./diceCandidateMapper');\n      const transformed = transformDiceResponseToInternalFormat(json, json);\n      \n      console.log('[searchCandidates] Transformed skills sample:', JSON.stringify(transformed?.data?.data?.[0]?.skills).substring(0, 150));\n      console.log('[searchCandidates] Transformation complete');\n      \n      return transformed;\n    } catch (error) {\n      console.error('[searchCandidates] Dice transformation failed, returning raw response:', error);\n      console.error('[searchCandidates] Error stack:', error.stack);\n      // Fall through to return raw response if transformation fails\n    }\n  } else {\n    console.log('[searchCandidates] No Dice source, returning raw response');\n  }\n  \n  return json;\n}\n\nexport async function getPipelineCount({ jobId, offset = 0, limit = 1, searchValue = '' }) {\n  const json = await fetchJsonWithAuth(\n    JOBS_URL,\n    `/source/hiring-candidate-list/pipeline?hiringType=pipeline&jobId=${jobId}&limit=${limit}&offset=${offset}&searchValue=${encodeURIComponent(searchValue)}`\n  );\n  return json?.data?.count ?? 0;\n}\n\nexport async function getShortlistedCount({ jobId, offset = 0, limit = 1, searchQuery = '' }) {\n  const json = await fetchJsonWithAuth(\n    JOBS_URL,\n    `/source/hiring-candidate-list/pipeline?hiringType=shortlisted&jobId=${jobId}&limit=${limit}&offset=${offset}&searchQuery=${encodeURIComponent(searchQuery)}`\n  );\n  return json?.data?.count ?? 0;\n}\n\nexport async function getSubmittedCandidates(jobId) {\n  const json = await fetchJsonWithAuth(SUBMISSIONS_URL, `/job-submissions?jobId=${jobId}`);\n  return json?.data ?? [];\n}\n\nexport async function getPipelineCandidates({ jobId, offset = 0, limit = 50, searchValue = '' }) {\n  const json = await fetchJsonWithAuth(\n    JOBS_URL,\n    `/source/hiring-candidate-list/pipeline?hiringType=pipeline&jobId=${jobId}&limit=${limit}&offset=${offset}&searchValue=${encodeURIComponent(searchValue)}`\n  );\n  return json;\n}\n\nexport async function getShortlistedCandidates({ jobId, offset = 0, limit = 50, searchQuery = '' }) {\n  const json = await fetchJsonWithAuth(\n    JOBS_URL,\n    `/source/hiring-candidate-list/pipeline?hiringType=shortlisted&jobId=${jobId}&limit=${limit}&offset=${offset}&searchQuery=${encodeURIComponent(searchQuery)}`\n  );\n  return json;\n}\n\nexport async function quickSubmitDetailedView({ _id, tenantId, businessId, businessUnitId }) {\n  const params = new URLSearchParams({ _id, tenantId, businessId, businessUnitId });\n  return apiGetWithAuth(CANDIDATES_URL, `/detailed-view?${params.toString()}`);\n}\n\n\n","function decodeJwtPayload(token) {\n  if (!token || typeof token !== 'string') return null;\n\n  try {\n    const encoded = token.split('.')[1];\n    if (!encoded) return null;\n    const normalized = encoded.replace(/-/g, '+').replace(/_/g, '/');\n    const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');\n    return JSON.parse(atob(padded));\n  } catch {\n    return null;\n  }\n}\n\nexport function getAccessTokenPayload() {\n  const token = localStorage.getItem('access_token') || localStorage.getItem('authToken');\n  return decodeJwtPayload(token) ?? {};\n}\n\nexport function getAccessTokenIdentity() {\n  const payload = getAccessTokenPayload();\n\n  return {\n    userId: payload.userId ?? payload.user_id ?? payload.USER_ID,\n    roleId: payload.roleId ?? payload.role_id ?? payload.ROLE_ID,\n  };\n}\n","import { useState, useEffect } from 'react';\nimport { getDropdownFields, getFieldConfig } from '../services/dropdownApi';\nimport { getAccessTokenIdentity } from '../utils/accessToken';\n\nfunction readRequestIdentity() {\n  const tokenIdentity = getAccessTokenIdentity();\n  return {\n    userId: tokenIdentity.userId ?? localStorage.getItem('userId') ?? undefined,\n    roleId: tokenIdentity.roleId ?? localStorage.getItem('roleId') ?? undefined,\n  };\n}\n\n/**\n * Fetches the list of filterable fields for a module.\n * Pass `module=null` to skip fetching (e.g. when drawer is closed).\n */\nexport function useDropdownFields(module) {\n  const [fields, setFields] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    if (!module) return;\n\n    let cancelled = false;\n    setLoading(true);\n    setError(null);\n\n    getDropdownFields(module)\n      .then((data) => {\n        if (!cancelled) setFields(Array.isArray(data) ? data : []);\n      })\n      .catch((err) => {\n        if (!cancelled) setError(err.message);\n      })\n      .finally(() => {\n        if (!cancelled) setLoading(false);\n      });\n\n    return () => { cancelled = true; };\n  }, [module]);\n\n  return { fields, loading, error };\n}\n\nexport function useFieldConfig(module) {\n  const [config, setConfig] = useState(null);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    if (!module) return;\n\n    let cancelled = false;\n    setLoading(true);\n    setError(null);\n\n    getFieldConfig(module)\n      .then((data) => {\n        if (!cancelled) setConfig(Array.isArray(data) ? data : null);\n      })\n      .catch((err) => {\n        if (!cancelled) setError(err.message);\n      })\n      .finally(() => {\n        if (!cancelled) setLoading(false);\n      });\n\n    return () => { cancelled = true; };\n  }, [module]);\n\n  return { config, loading, error };\n}\n\n/**\n * Fetches filter-specific field config from the auth API (configType=filter),\n * returning only fields where isVisible is true.\n * Falls back to the submissions filter-dropdown-fields endpoint when the auth\n * API returns nothing.\n */\nexport function useFilterFields(module) {\n  const [fields, setFields] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    if (!module) return;\n\n    let cancelled = false;\n    setLoading(true);\n    setError(null);\n\n    // roleId must represent the authenticated token, not a potentially stale\n    // or login-response-derived localStorage value.\n    const { userId, roleId } = readRequestIdentity();\n\n    const isFieldVisible = (f) => {\n      const vis = f?.isVisible ?? f?.is_visible ?? f?.visible;\n      if (vis === undefined || vis === null) return true;\n      if (typeof vis === 'boolean') return vis;\n      if (typeof vis === 'string') return !['false', '0', 'no', 'hide', 'hidden'].includes(vis.toLowerCase());\n      return Boolean(vis);\n    };\n\n    getFieldConfig(module, { configType: 'filter', userId, roleId })\n      .then(async (data) => {\n        const rows = Array.isArray(data) ? data : (data?.visibleFields ?? []);\n        const visible = rows.filter(isFieldVisible);\n        // If the filter config exists but has no visible fields (admin hasn't\n        // marked anything as visible yet), fall back to the module's base fields\n        // so the user can still filter without an empty drawer.\n        if (visible.length > 0) return visible;\n        const fallback = await getDropdownFields(module);\n        return Array.isArray(fallback) ? fallback.filter(isFieldVisible) : [];\n      })\n      .then((rows) => {\n        if (!cancelled) setFields(Array.isArray(rows) ? rows : []);\n      })\n      .catch((err) => {\n        if (!cancelled) setError(err.message);\n      })\n      .finally(() => {\n        if (!cancelled) setLoading(false);\n      });\n\n    return () => { cancelled = true; };\n  }, [module]);\n\n  return { fields, loading, error };\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// PermissionContext — resolves the logged-in user's CURRENT role permissions\n// from GET /me/permissions.\n//\n// `menuPermission` in localStorage is still maintained because several legacy\n// consumers (Sidebar and app-specific helpers) read that shape directly. The\n// live API response is authoritative and is mirrored back into localStorage so\n// a browser refresh/token refresh cannot fall back to an old login snapshot.\n//\n// Shape of `permissions`: moduleName -> actionKey -> boolean, or the wildcard\n// { \"*\": { \"*\": true } } for full-access roles (Admin/Manager).\n// ─────────────────────────────────────────────────────────────────────────\nimport { createContext, useCallback, useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { getMyPermissions } from '../services/adminApi';\nimport { getStoredToken } from '../services/authApi';\n\nexport const PermissionContext = createContext({ permissions: {}, loading: true });\n\nfunction isFullAccess(permissions) {\n  return Boolean(permissions?.['*']?.['*']);\n}\n\nfunction toLegacyMenuPermission(permissions) {\n  if (!permissions || typeof permissions !== 'object' || Array.isArray(permissions)) return {};\n\n  return Object.fromEntries(\n    Object.entries(permissions)\n      .filter(([moduleName]) => moduleName !== '*')\n      .map(([moduleName, actions]) => [\n        moduleName,\n        Object.fromEntries(\n          Object.entries(actions ?? {}).map(([action, allowed]) => [action, allowed ? 1 : 0]),\n        ),\n      ]),\n  );\n}\n\nfunction syncLegacyPermissionSnapshot(permissions) {\n  // Full-access roles intentionally use a wildcard in /me/permissions. Keep the\n  // richer login-time menuPermission map for legacy helpers; replacing it with\n  // only {\"*\":{\"*\":1}} would make helpers that do not understand wildcards\n  // (for example app-specific sendApprove checks) incorrectly return false.\n  if (isFullAccess(permissions)) return;\n\n  try {\n    localStorage.setItem('menuPermission', JSON.stringify(toLegacyMenuPermission(permissions)));\n    window.dispatchEvent(new Event('menu:updated'));\n  } catch {\n    // Storage can be unavailable in private/locked-down browser contexts. The\n    // live React permission state still remains usable, so do not fail access\n    // resolution merely because the compatibility snapshot could not be saved.\n  }\n}\n\nexport function PermissionProvider({ children }) {\n  const [permissions, setPermissions] = useState({});\n  const [loading, setLoading] = useState(true);\n\n  const refresh = useCallback(() => {\n    let hasToken = false;\n    try {\n      hasToken = Boolean(getStoredToken());\n    } catch {\n      hasToken = false;\n    }\n    if (!hasToken) {\n      setPermissions({});\n      setLoading(false);\n      return;\n    }\n\n    setLoading(true);\n    getMyPermissions()\n      .then((data) => {\n        const next = data ?? {};\n        setPermissions(next);\n        syncLegacyPermissionSnapshot(next);\n      })\n      // Keep the existing login snapshot as the compatibility fallback when the\n      // live permission endpoint is temporarily unavailable. Clearing it here\n      // would make a transient network error look like a permission change.\n      .catch(() => setPermissions({}))\n      .finally(() => setLoading(false));\n  }, []);\n\n  useEffect(() => {\n    refresh();\n    window.addEventListener('auth:login', refresh);\n    window.addEventListener('auth:logout', refresh);\n    window.addEventListener('auth:token-refreshed', refresh);\n    window.addEventListener('permissions:changed', refresh);\n    window.addEventListener('storage', refresh);\n    return () => {\n      window.removeEventListener('auth:login', refresh);\n      window.removeEventListener('auth:logout', refresh);\n      window.removeEventListener('auth:token-refreshed', refresh);\n      window.removeEventListener('permissions:changed', refresh);\n      window.removeEventListener('storage', refresh);\n    };\n  }, [refresh]);\n\n  return (\n    <PermissionContext.Provider value={{ permissions, loading, refresh }}>\n      {children}\n    </PermissionContext.Provider>\n  );\n}\n\nPermissionProvider.propTypes = {\n  children: PropTypes.node,\n};\n","import { useContext, useMemo } from 'react';\nimport { PermissionContext } from '../contexts/PermissionContext';\n\n// Overrides for menuPermission keys that don't derive from simple singular/plural\n// matching against the login menu (e.g. backend typos like \"campaingns\").\nconst MODULE_PERMISSION_MAP = {\n  campaign: 'campaingns',\n  campaigns: 'campaingns',\n};\n\nfunction normalizeKey(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\n// Treats \"job\"/\"jobs\", \"candidate\"/\"candidates\", etc. as the same key.\nfunction keysMatch(a, b) {\n  const left = normalizeKey(a);\n  const right = normalizeKey(b);\n  if (!left || !right) return false;\n  return left === right || `${left}s` === right || `${right}s` === left;\n}\n\nfunction resolveMenuKey(normalized) {\n  try {\n    const rawMenu = localStorage.getItem('menu');\n    if (!rawMenu) return null;\n    const menu = JSON.parse(rawMenu);\n    if (!Array.isArray(menu)) return null;\n\n    const match = menu.find((item) => {\n      const key = normalizeKey(item?.key);\n      return key && keysMatch(normalized, key);\n    });\n    return match ? normalizeKey(match.key) : null;\n  } catch {\n    return null;\n  }\n}\n\nfunction findModulePermission(all, moduleName) {\n  if (!all || typeof all !== 'object' || Array.isArray(all) || !moduleName) {\n    return { found: false, permissions: {} };\n  }\n\n  const normalized = normalizeKey(moduleName);\n  const mapped = MODULE_PERMISSION_MAP[normalized] ?? normalized;\n  const menuResolved = resolveMenuKey(normalized);\n  const candidates = [mapped, menuResolved, normalized].filter(Boolean);\n  const keys = Object.keys(all);\n\n  const matchedKey = keys.find((key) => candidates.some((candidate) => normalizeKey(key) === candidate))\n    ?? keys.find((key) => candidates.some((candidate) => keysMatch(candidate, key)));\n\n  return {\n    found: Boolean(matchedKey),\n    permissions: matchedKey ? (all[matchedKey] ?? {}) : {},\n  };\n}\n\nfunction readStoredPermissions(moduleName) {\n  try {\n    const raw = localStorage.getItem('menuPermission');\n    if (!raw) return {};\n    const all = JSON.parse(raw);\n    return findModulePermission(all, moduleName).permissions;\n  } catch {\n    return {};\n  }\n}\n\n// Permission values come as 1/0 integers from the login snapshot and booleans\n// from /me/permissions. Absent CRUD key keeps the historical default-allow\n// behaviour (unconfigured = unrestricted).\nfunction permissionScalar(value) {\n  if (value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, 'value')) {\n    return value.value;\n  }\n  return value;\n}\n\nfunction isAllowed(value) {\n  const scalar = permissionScalar(value);\n  if (scalar === undefined || scalar === null) return true;\n  return scalar === true || scalar === 1 || scalar === '1'\n    || String(scalar).trim().toLowerCase() === 'true';\n}\n\nfunction isExplicitlyAllowed(value) {\n  const scalar = permissionScalar(value);\n  if (scalar === undefined || scalar === null) return false;\n  return scalar === true || scalar === 1 || scalar === '1'\n    || String(scalar).trim().toLowerCase() === 'true';\n}\n\nfunction permissionValue(permissions, key) {\n  if (!permissions || typeof permissions !== 'object') return undefined;\n  if (Object.prototype.hasOwnProperty.call(permissions, key)) return permissions[key];\n  const wanted = normalizeKey(key);\n  const matchedKey = Object.keys(permissions).find(\n    (candidate) => normalizeKey(candidate) === wanted,\n  );\n  return matchedKey ? permissions[matchedKey] : undefined;\n}\n\nexport function useMenuPermission(moduleName) {\n  const { permissions: livePermissions, loading } = useContext(PermissionContext);\n\n  return useMemo(() => {\n    const fullAccess = Boolean(livePermissions?.['*']?.['*']);\n    const live = findModulePermission(livePermissions, moduleName);\n\n    // Once the live module is available it is authoritative. During initial\n    // load (or if an older deployment has no /me/permissions entry for this\n    // module), fall back to the login snapshot for compatibility.\n    const p = !loading && live.found ? live.permissions : readStoredPermissions(moduleName);\n\n    if (fullAccess) {\n      return {\n        canView: true,\n        canAdd: true,\n        canEdit: true,\n        canDelete: true,\n        canApprove: true,\n        canReject: true,\n        canReApprove: true,\n        canSendApprove: true,\n      };\n    }\n\n    return {\n      canView:        isAllowed(permissionValue(p, 'view')),\n      canAdd:         isAllowed(permissionValue(p, 'add')),\n      canEdit:        isAllowed(permissionValue(p, 'edit')),\n      canDelete:      isAllowed(permissionValue(p, 'delete')),\n      canApprove:     isAllowed(permissionValue(p, 'approve')),\n      canReject:      isAllowed(permissionValue(p, 'reject')),\n      canReApprove:   isExplicitlyAllowed(permissionValue(p, 'reApprove')),\n      canSendApprove: isExplicitlyAllowed(permissionValue(p, 'sendApprove')),\n    };\n  }, [moduleName, livePermissions, loading]);\n}\n","import { useCallback, useContext } from 'react';\nimport { PermissionContext } from '../contexts/PermissionContext';\n\nfunction normalize(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\nfunction moduleKeysMatch(a, b) {\n  const left = normalize(a);\n  const right = normalize(b);\n  if (!left || !right) return false;\n  return left === right || `${left}s` === right || `${right}s` === left;\n}\n\nfunction findModule(all, moduleName) {\n  if (!all || typeof all !== 'object' || Array.isArray(all)) return null;\n  const key = Object.keys(all).find((candidate) => moduleKeysMatch(candidate, moduleName));\n  return key ? all[key] : null;\n}\n\nfunction permissionScalar(value) {\n  if (value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, 'value')) {\n    return value.value;\n  }\n  return value;\n}\n\nfunction permissionAllowed(value, missingDefault = false) {\n  const scalar = permissionScalar(value);\n  if (scalar === undefined || scalar === null) return missingDefault;\n  return scalar === true || scalar === 1 || scalar === '1'\n    || String(scalar).trim().toLowerCase() === 'true';\n}\n\nfunction findAction(actions, action) {\n  if (!actions || typeof actions !== 'object') return undefined;\n  if (Object.prototype.hasOwnProperty.call(actions, action)) return actions[action];\n  const wanted = normalize(action);\n  const key = Object.keys(actions).find((candidate) => normalize(candidate) === wanted);\n  return key ? actions[key] : undefined;\n}\n\nfunction storedPermission(moduleName, action) {\n  try {\n    const all = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    const modulePermissions = findModule(all, moduleName);\n    // Preserve the old roleAllowsAction behaviour for deployments/screens that\n    // have not mounted PermissionProvider yet: an unconfigured explicit action\n    // was historically treated as allowed.\n    return permissionAllowed(findAction(modulePermissions, action), true);\n  } catch {\n    return true;\n  }\n}\n\n// can(module, action) — the single gate for role-based UI visibility.\n// Live /me/permissions data is authoritative. The localStorage fallback is only\n// for initial loading/legacy standalone consumers and prevents a stale login\n// snapshot from becoming the long-term source of truth.\nexport function usePermissions() {\n  const { permissions, loading } = useContext(PermissionContext);\n\n  const can = useCallback((moduleName, action) => {\n    if (permissions?.['*']?.['*']) return true;\n\n    const modulePermissions = findModule(permissions, moduleName);\n    if (modulePermissions) {\n      return permissionAllowed(findAction(modulePermissions, action), false);\n    }\n\n    if (loading || Object.keys(permissions ?? {}).length === 0) {\n      return storedPermission(moduleName, action);\n    }\n\n    // If the live role matrix loaded successfully but has no entry for this\n    // module, retain compatibility with the old login map rather than hiding a\n    // dynamically configured action solely because that module has not yet been\n    // migrated into role_menu_permissions.\n    return storedPermission(moduleName, action);\n  }, [permissions, loading]);\n\n  return { can, permissions, loading };\n}\n","function actionText(action) {\n  return [action?.key, action?.label, action?.name]\n    .filter(Boolean)\n    .join(' ')\n    .trim()\n    .toLowerCase();\n}\n\nexport function getCrudPermissionKey(action) {\n  const explicit = String(action?.permissionKey ?? '').trim().toLowerCase();\n  if (['add', 'edit', 'delete'].includes(explicit)) return explicit;\n  if (action?.danger) return 'delete';\n\n  const text = actionText(action);\n  if (/(^|[\\s_-])edit([\\s_-]|$)/.test(text)) return 'edit';\n  if (/(^|[\\s_-])(add|create)([\\s_-]|$)/.test(text)) return 'add';\n  return null;\n}\n","// Shared Module Action Rule evaluator — used by both ListView.jsx (List, one\n// evaluation per selected row) and DetailHeaderCard.jsx (Detail, one\n// evaluation for the single record on screen) so there is exactly one\n// implementation of the 7 operators configured in\n// pages/Modules/Admin/ModuleActionRulesSection.jsx, instead of two files that\n// can silently drift apart (which is how Detail's `scope` operator went dead\n// — it compared against a hardcoded literal instead of the real view scope).\n//\n// `scope` conditions compare against whatever \"view scope\" string the caller\n// passes in (e.g. the active List tab key like \"myJobs\"/\"allJobs\"). Callers\n// with no real scope concept (e.g. a Detail page) should pass `undefined` —\n// a rule can then only match `scope` conditions if the admin never configured\n// one for that context, same as any other field that isn't present.\n\n// Resolves a rule's field path against the record, tolerating BOTH record\n// shapes the two callers produce: List rows are the raw nested DB document\n// (rule path \"a.b\" → record.a.b), while the Detail header flattens form-group\n// fields under their configured field keys — which may be the dotted path\n// itself (\"a.b\" as a literal key) or just the leaf (\"b\", e.g. the submission\n// form's internalSubmissionStatusText vs the rule's nested\n// internalSubmissionStatus.internalSubmissionStatusText). Trying literal →\n// nested → leaf keeps one admin rule working against every caller with no\n// per-module code.\n// Walks a dotted path, and when it meets an ARRAY it maps the remaining path\n// over every element and flattens the result. That makes a path like\n// \"recruiters.recruiterId\" resolve to [1, 7, …] on a record whose `recruiters`\n// is an array of objects — which is what an array-membership condition (e.g.\n// \"is this job already assigned to me?\") needs. Scalar paths are unaffected.\nfunction resolvePath(value, keys) {\n  if (value === undefined || value === null) return undefined;\n  if (keys.length === 0) return value;\n  if (Array.isArray(value)) {\n    const mapped = value\n      .map((item) => resolvePath(item, keys))\n      .filter((item) => item !== undefined && item !== null);\n    return mapped.flat();\n  }\n  return resolvePath(value[keys[0]], keys.slice(1));\n}\n\nfunction getNestedValue(record, fieldKey) {\n  if (!fieldKey || typeof fieldKey !== 'string' || !record) return undefined;\n  if (fieldKey in record) return record[fieldKey];\n  const nested = resolvePath(record, fieldKey.split('.'));\n  if (nested !== undefined && !(Array.isArray(nested) && nested.length === 0)) return nested;\n  const leaf = fieldKey.split('.').pop();\n  return leaf !== fieldKey ? record[leaf] : undefined;\n}\n\n// Runtime tokens an admin can put in a condition's `value`, so a rule can be\n// written against \"the person looking at the screen\" instead of a hardcoded id.\n// Resolved at evaluation time from the signed-in user. Unknown tokens are left\n// alone, so an ordinary literal value is never altered.\nfunction currentUserId() {\n  try {\n    return typeof localStorage !== 'undefined' ? (localStorage.getItem('userId') ?? '') : '';\n  } catch {\n    return '';\n  }\n}\n\nconst RULE_VALUE_TOKENS = {\n  '{currentuserid}': currentUserId,\n  '{currentuser}': currentUserId,\n  '{me}': currentUserId,\n};\n\nfunction resolveRuleValue(value) {\n  const token = RULE_VALUE_TOKENS[String(value ?? '').trim().toLowerCase()];\n  return token ? token() : value;\n}\n\nfunction normalizeText(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\n// normalizeKey — the comparison used for EQUALITY, on top of normalizeText.\n//\n// Status values are typed by people and stored however the source system spells\n// them: \"In-Active\", \"In Active\", \"inactive\", \"In_Active\" are one status wearing\n// four coats. A rule written against any one of them silently stopped matching\n// the other three, and the symptom is the worst kind — actions quietly staying\n// visible on a job nobody should be able to act on.\n//\n// Only letters and digits survive, so every spelling above folds to \"inactive\".\n// Deliberately NOT applied to `contains`, whose whole job is substring matching:\n// stripping separators there would change what a substring means.\nfunction normalizeKey(value) {\n  return normalizeText(value).replace(/[^a-z0-9]/g, '');\n}\n\n// looseEquals — normalized equality, then the symbol-insensitive form as a\n// FALLBACK.\n//\n// Ordered that way on purpose: anything that matched before still matches, so\n// no existing rule can change meaning. The fallback only ever adds matches that\n// differ by punctuation, spacing or case — which is exactly the drift above and\n// never a distinction anybody configured deliberately.\nfunction looseEquals(a, b) {\n  if (a === b) return true;\n  return normalizeKey(a) === normalizeKey(b);\n}\n\nfunction isEmptyRuleValue(value) {\n  return value === undefined || value === null || value === ''\n    || (Array.isArray(value) && value.length === 0);\n}\n\nexport function conditionMatches(condition, record, scope) {\n  const operator = condition?.operator;\n  const actual = operator === 'scope' ? scope : getNestedValue(record, condition?.field);\n  const expected = resolveRuleValue(condition?.value);\n  const normalizedActual = normalizeText(actual);\n  const normalizedExpected = normalizeText(expected);\n\n  if (operator === 'eq' || operator === 'scope') return looseEquals(normalizedActual, normalizedExpected);\n  if (operator === 'ne') return !looseEquals(normalizedActual, normalizedExpected);\n  if (operator === 'isEmpty') return isEmptyRuleValue(actual);\n  if (operator === 'notEmpty') return !isEmptyRuleValue(actual);\n  if (operator === 'fieldEq') {\n    return looseEquals(normalizedActual, normalizeText(getNestedValue(record, condition?.compareField)));\n  }\n  // EXACT membership — the id-safe counterpart of `contains` (whose substring\n  // match would make user \"1\" match \"12\"). Use this for id lists, e.g.\n  // recruiters.recruiterId includes {currentUserId}.\n  if (operator === 'includes' || operator === 'notIncludes') {\n    const list = Array.isArray(actual) ? actual : [actual];\n    const hit = list.some((item) => looseEquals(normalizeText(item), normalizedExpected))\n      && normalizedExpected !== '';\n    return operator === 'includes' ? hit : !hit;\n  }\n  if (operator === 'contains') {\n    if (Array.isArray(actual)) return actual.some((item) => normalizeText(item).includes(normalizedExpected));\n    return normalizedActual.includes(normalizedExpected);\n  }\n  return false;\n}\n\n// ruleFires — the rule is on and every one of its conditions matches.\n// A rule with NO conditions never fires: an empty condition list would\n// otherwise be vacuously true and block the action on every record.\nfunction ruleFires(rule, record, scope) {\n  if (!rule || rule.isActive === false) return false;\n  const conditions = rule.conditions ?? [];\n  if (!conditions.length) return false;\n  return conditions.every((condition) => conditionMatches(condition, record, scope));\n}\n\n// allowedActionsOf — a rule's ALLOW-LIST, or null when it has none.\n//\n// The inverse of blockedActions, and the honest way to express \"when this\n// fires, only these actions remain\". Listing every other action instead is a\n// rule that silently rots: add a ninth action next month and it appears on the\n// very records the rule exists to lock down, because nobody remembered to\n// extend the list. An allow-list cannot go stale that way.\nfunction allowedActionsOf(rule) {\n  const raw = rule?.allowedActions;\n  if (!Array.isArray(raw) || raw.length === 0) return null;\n  return raw.map(String);\n}\n\nexport function isRuleActionBlocked(actionKey, record, rules, scope) {\n  const list = Array.isArray(rules) ? rules : [];\n  if (!list.length) return false;\n  const key = String(actionKey);\n  return list.some((rule) => {\n    if (!ruleFires(rule, record, scope)) return false;\n    // An allow-list blocks everything it does not name. Compared loosely so a\n    // key configured as \"Quick-Submit\" still matches the action \"quickSubmit\"\n    // — the same folding every other comparison here uses.\n    const allowed = allowedActionsOf(rule);\n    if (allowed && !allowed.some((entry) => looseEquals(entry, key))) return true;\n    return (rule?.blockedActions ?? []).map(String).includes(key);\n  });\n}\n\n// isRuleActionDisabled — the same admin-configured rule shape as blockedActions,\n// but the action stays VISIBLE and just goes unclickable instead of vanishing\n// (e.g. Approve/Reject during a \"Resubmission\" review cycle: the user should\n// still see the buttons and understand why they can't act, not wonder where\n// the actions went). Returns the matched rule (so the caller can surface its\n// `description` as the disabled reason) or null.\nexport function ruleActionDisabledReason(actionKey, record, rules, scope) {\n  const list = Array.isArray(rules) ? rules : [];\n  const rule = list.find((r) => (\n    (r?.disabledActions ?? []).map(String).includes(String(actionKey))\n    && ruleFires(r, record, scope)\n  ));\n  return rule ? (rule.description || `${actionKey} is temporarily unavailable`) : null;\n}\n\n// actionDoneState — config-driven \"done\" terminus. When the action's\n// admin-configured `doneWhen` condition matches the record, the action stops\n// being clickable and renders `doneLabel` (in `doneTone`) instead of its normal\n// label — e.g. \"Move to Onboarding\" becomes a disabled \"Moved to Onboarded\"\n// once the submission has been onboarded. Reuses the same condition evaluator\n// as the visibility rules. Returns { label, tone } or null. Shared so the List,\n// the row-action dropdown and the Detail header all render it identically.\nexport function actionDoneState(action, record, scope) {\n  const condition = action?.doneWhen;\n  if (!condition || !condition.field) return null;\n  if (!conditionMatches(condition, record, scope)) return null;\n  return {\n    label: action.doneLabel || action.label,\n    tone: action.doneTone || 'success',\n  };\n}\n\n// isActionBlocked — List view's original signature: blocked if ANY of the\n// given records would have this action blocked (used for the bulk multi-select\n// toolbar, where one action covers every selected row at once).\nexport function isActionBlocked(actionKey, records, rules, scope) {\n  const list = Array.isArray(records) ? records : [];\n  if (!list.length) return false;\n  return list.some((record) => isRuleActionBlocked(actionKey, record, rules, scope));\n}\n","{\n  \"rows\": { \"sources\": [\"payload\"], \"paths\": [\"rows\", \"records\", \"items\", \"list\", \"data\"] },\n  \"total\": { \"sources\": [\"response\", \"payload\"], \"paths\": [\"total\", \"count\", \"totalCount\"] },\n  \"tabs\": { \"sources\": [\"response\", \"payload\"], \"paths\": [\"tabs\", \"tabList\"] },\n  \"fields\": { \"sources\": [\"response\", \"payload\"], \"paths\": [\"fields\", \"fieldConfig\"] },\n  \"tabField\": { \"sources\": [\"payload\"], \"paths\": [\"tabField\"] },\n  \"actionRules\": { \"sources\": [\"payload\"], \"paths\": [\"actionRules\"] },\n  \"actions\": { \"sources\": [\"payload\"], \"paths\": [\"actions\"] },\n  \"columnActions\": { \"sources\": [\"payload\"], \"paths\": [\"columnActions\"] },\n  \"synthesizeFieldsFromRows\": true,\n  \"visibilityFlag\": null\n}\n","import defaultConfig from '../../config/responseMappings/default.json';\nimport { parseModulePath } from '../../utils/modulePath';\n\n// Any src/config/responseMappings/<moduleName>.json is auto-registered as a\n// per-module override, shallow-merged over defaultConfig — no code change needed.\nconst overrideConfigs = import.meta.glob('../../config/responseMappings/*.json', { eager: true });\n\nfunction getModuleOverride(moduleName) {\n  if (!moduleName) return null;\n\n  for (const path of Object.keys(overrideConfigs)) {\n    const fileName = path.split('/').pop().replace(/\\.json$/, '');\n    if (fileName === moduleName) {\n      const mod = overrideConfigs[path];\n      return mod.default ?? mod;\n    }\n  }\n\n  return null;\n}\n\nfunction loadMappingConfig(moduleName) {\n  const override = getModuleOverride(moduleName);\n  return override ? { ...defaultConfig, ...override } : defaultConfig;\n}\n\nfunction getPath(source, path) {\n  return String(path).split('.').reduce((value, key) => (value == null ? undefined : value[key]), source);\n}\n\nfunction resolveFirst(response, payload, spec) {\n  if (!spec) return undefined;\n  const sourceMap = { response, payload };\n\n  for (const sourceName of spec.sources) {\n    for (const path of spec.paths) {\n      const value = getPath(sourceMap[sourceName], path);\n      if (value !== undefined) return value;\n    }\n  }\n\n  return undefined;\n}\n\nfunction firstFiniteNumber(...values) {\n  for (const value of values) {\n    const number = Number(value);\n    if (Number.isFinite(number)) return number;\n  }\n\n  return undefined;\n}\n\nfunction humanizeKey(key) {\n  return key.replace(/([A-Z])/g, ' $1').replace(/^./, (char) => char.toUpperCase());\n}\n\n// Substrings that flag a key as sensitive; synthesis must never surface these\n// automatically even though they are primitive values. See\n// docs/JSON-Driven-Response-Mapping-Security-Assessment.html — \"Accidental\n// sensitive-data exposure\".\nconst SENSITIVE_KEY_PATTERN = /token|password|passwd|secret|apikey|api_key|auth|credential|salary|ssn|ein\\b/i;\n\nfunction isSensitiveKey(key) {\n  return SENSITIVE_KEY_PATTERN.test(key);\n}\n\nexport function synthesizeFieldsFromRows(rows) {\n  const firstRow = rows[0];\n  if (!firstRow) return [];\n\n  return Object.keys(firstRow)\n    .filter((key) => !key.startsWith('_') && !isSensitiveKey(key) && typeof firstRow[key] !== 'object')\n    .map((key) => ({\n      value: key,\n      field: key,\n      label: humanizeKey(key),\n      isVisible: true,\n    }));\n}\n\nexport function applyVisibilityFlag(fields, flagKey) {\n  if (!flagKey) return fields;\n\n  return fields\n    .filter((field) => field[flagKey] === 1 || field[flagKey] === true || field[flagKey] === undefined)\n    .map((field) => ({ ...field, isVisible: true }));\n}\n\n// Collection caps: an untrusted response with huge arrays can freeze the\n// browser (see \"Unbounded response size\" in the security assessment).\nconst MAX_ROWS = 5000;\nconst MAX_FIELDS = 300;\nconst MAX_TABS = 100;\nconst MAX_ACTIONS = 100;\nconst MAX_ACTION_RULES = 300;\nconst MAX_COLUMN_ACTIONS = 100;\n\nfunction isPlainObject(value) {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction clampArray(value, max) {\n  return Array.isArray(value) ? value.slice(0, max) : [];\n}\n\n// Backend metadata is trusted with minimal validation (\"Backend metadata is\n// trusted\" finding). A field/tab/action array must at least be an array of\n// plain objects before it reaches ListView.\nfunction sanitizeObjectList(value, max) {\n  return clampArray(value, max).filter(isPlainObject);\n}\n\nfunction sanitizeFieldList(value, max) {\n  return sanitizeObjectList(value, max).filter(\n    (field) => typeof field.value === 'string' || typeof field.field === 'string'\n  );\n}\n\n// javascript:/data:/vbscript:/file: URLs in action metadata can reach a\n// rendered <a href> (ListView's renderActionButton) and execute in the\n// user's session. Only allow relative routes and standard web protocols.\nconst UNSAFE_URL_PROTOCOL = /^\\s*(javascript|data|vbscript|file):/i;\nconst ACTION_URL_KEYS = ['url', 'href', 'routeUrl', 'routeURL'];\n\nfunction sanitizeAction(action) {\n  const safe = { ...action };\n  for (const key of ACTION_URL_KEYS) {\n    if (typeof safe[key] === 'string' && UNSAFE_URL_PROTOCOL.test(safe[key])) {\n      delete safe[key];\n    }\n  }\n  return safe;\n}\n\nfunction sanitizeActionList(value, max) {\n  return sanitizeObjectList(value, max).map(sanitizeAction);\n}\n\n// Dot-notation module names (\"job.client\", \"job.client.company\") display the\n// data nested at that path inside each fetched record instead of the record\n// itself. Objects become one row each, arrays are flattened into one row per\n// entry, and primitives are wrapped as { value } so they still render.\nfunction extractNestedRows(rows, nestedPath) {\n  return rows.flatMap((row) => {\n    const value = getPath(row, nestedPath);\n    if (value === undefined || value === null) return [];\n\n    const entries = Array.isArray(value) ? value : [value];\n    return entries\n      .filter((entry) => entry !== undefined && entry !== null)\n      .map((entry) => (isPlainObject(entry) ? entry : { value: entry }));\n  });\n}\n\n// The failure this catches is invisible: a producer that pre-unwraps the\n// envelope hands us an object whose own `data` key holds its ROWS, so `payload`\n// resolves to that array and every key a mapping looks up only in `payload` —\n// actions, actionRules, columnActions, tabField — is read off an array and comes\n// back undefined. Rows, total, fields and tabs still resolve, so the list looks\n// almost right and only the Actions menu is quietly empty. Nothing throws.\n//\n// One warning beats an afternoon of bisecting. Emit rows under `items`.\nfunction warnOnShadowedPayload(response, payload) {\n  if (!Array.isArray(payload) || Array.isArray(response) || !isPlainObject(response)) return;\n  const shadowed = ['actions', 'actionRules', 'columnActions', 'tabField']\n    .filter((key) => response[key] !== undefined);\n  if (shadowed.length === 0) return;\n\n  console.warn(\n    `[mapListResponse] response.data is an array, so ${shadowed.join(', ')} cannot be `\n    + 'resolved from it. Send rows under \"items\" instead of \"data\", or pass the full '\n    + 'envelope rather than the unwrapped payload.',\n  );\n}\n\nexport function mapListResponse(response, moduleName) {\n  const { baseModule, nestedPath } = parseModulePath(moduleName);\n  const config = loadMappingConfig(baseModule);\n  // Two lookup roots; a mapping names which of them to try for each key. The\n  // convention every producer follows is to hand this the WHOLE envelope\n  // ({status, message, data: {...}}), so `payload` lands on the config object.\n  const payload = response?.data ?? response;\n  warnOnShadowedPayload(response, payload);\n\n  const rowsRaw = Array.isArray(payload) ? payload : resolveFirst(response, payload, config.rows);\n  let rows = clampArray(rowsRaw, MAX_ROWS);\n  if (nestedPath) {\n    rows = clampArray(extractNestedRows(rows, nestedPath), MAX_ROWS);\n    console.log(`[mapListResponse] module \"${baseModule}\" → nested path \"${nestedPath}\": ${rows.length} row(s)`);\n  }\n\n  const totalRaw = resolveFirst(response, payload, config.total);\n  // Some backends nest the total under an object (e.g. { total, searchCount,\n  // count }) instead of a flat number; Number(object) is NaN, so unwrap it\n  // first or the count silently collapses to 0.\n  const unwrappedTotal = isPlainObject(totalRaw)\n    ? firstFiniteNumber(totalRaw.total, totalRaw.searchCount, totalRaw.count)\n    : totalRaw;\n  const total = Number(unwrappedTotal ?? rows.length) || 0;\n\n  const tabs = sanitizeObjectList(resolveFirst(response, payload, config.tabs), MAX_TABS);\n\n  // In nested mode the response's field config describes the parent module's\n  // records, not the nested objects being displayed — always synthesize the\n  // columns from the nested rows themselves.\n  const fieldsRaw = nestedPath ? [] : resolveFirst(response, payload, config.fields);\n  let fields = Array.isArray(fieldsRaw) ? fieldsRaw : [];\n  if (fields.length === 0 && (nestedPath || config.synthesizeFieldsFromRows)) {\n    fields = synthesizeFieldsFromRows(rows);\n  }\n  fields = sanitizeFieldList(fields, MAX_FIELDS);\n  if (config.visibilityFlag) {\n    fields = applyVisibilityFlag(fields, config.visibilityFlag);\n  }\n\n  const tabFieldRaw = resolveFirst(response, payload, config.tabField);\n  const tabField = typeof tabFieldRaw === 'string' ? tabFieldRaw : '';\n\n  return {\n    rows,\n    total,\n    tabs,\n    fields,\n    tabField,\n    actionRules: sanitizeActionList(resolveFirst(response, payload, config.actionRules), MAX_ACTION_RULES),\n    actions: sanitizeActionList(resolveFirst(response, payload, config.actions), MAX_ACTIONS),\n    columnActions: sanitizeActionList(resolveFirst(response, payload, config.columnActions), MAX_COLUMN_ACTIONS),\n  };\n}\n","const SUMMARY_REQUESTS = {\n  jobs: {\n    module: 'jobs',\n    keys: ['jobRecruitmentStatus', 'jobStatus'],\n    dateField: 'createdAt',\n  },\n  candidates: {\n    module: 'candidates',\n    keys: ['candidateSummary'],\n    items: [\n      {\n        key: 'created',\n        label: 'Created',\n        collection: 'candidates',\n        countType: 'documents',\n        dateField: 'createdAt',\n      },\n      {\n        key: 'submitted',\n        label: 'Submitted',\n        collection: 'submissions',\n        countType: 'distinct',\n        distinctField: 'applicantId',\n        dateField: 'submittedAt',\n      },\n      {\n        key: 'onboarded',\n        label: 'Onboarded',\n        collection: 'onboarding',\n        countType: 'distinct',\n        distinctField: 'candidateId',\n        dateField: 'onboardingActivity.activityTime',\n        filters: {\n          onboardingObStage: ['Completed'],\n        },\n      },\n    ],\n  },\n  submissions: {\n    module: 'submission',\n    keys: [\n      'internalSubmissionStatus.internalSubmissionStatusText',\n      'clientSubmissionStatus.clientSubmissionStatusText',\n    ],\n    dateField: 'createdAt',\n  },\n};\n\nexport const SUMMARY_VISIBLE_COUNTS = {\n  jobSummary: [\n    {\n      label: 'Open',\n      field: 'jobStatus',\n      keys: ['open', 'active'],\n    },\n    {\n      label: 'Partially Fulfilled',\n      field: 'jobRecruitmentStatus',\n      keys: ['partially fulfilled', 'partiallyFulfilled'],\n    },\n    {\n      label: 'Fulfilled',\n      field: 'jobRecruitmentStatus',\n      keys: ['fulfilled'],\n    },\n    {\n      label: 'In-active / Closed',\n      field: 'jobStatus',\n      keys: ['closed', 'inactive', 'in-active'],\n    },\n  ],\n};\n\nfunction normalizeComparableText(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\nfunction makeSummaryItem(label, count) {\n  return {\n    label,\n    count: Number.isFinite(Number(count)) ? Number(count) : 0,\n  };\n}\n\nfunction getCountsFromField(field) {\n  return Array.isArray(field?.counts) ? field.counts : [];\n}\n\nfunction getFieldFromSummary(data, key) {\n  if (data?.key === key) return data;\n\n  const fields = Array.isArray(data?.fields) ? data.fields : [];\n  return fields.find((field) => field?.key === key) ?? {};\n}\n\nfunction getCountByAliases(data, aliases) {\n  const aliasList = Array.isArray(aliases) ? aliases : [aliases];\n  const items = Array.isArray(data?.counts) ? data.counts : [];\n  const normalizedAliases = aliasList.filter(Boolean).map(normalizeComparableText);\n\n  const countItem = items.find((item) => {\n    const candidates = [item?.key, item?.label].map(normalizeComparableText);\n    return candidates.some((candidate) => normalizedAliases.includes(candidate));\n  });\n\n  if (countItem) return Number(countItem.count) || 0;\n\n  for (const alias of aliasList) {\n    const directValue = data?.[alias];\n    if (Number.isFinite(Number(directValue))) return Number(directValue);\n  }\n\n  return 0;\n}\n\nfunction getCountByLabels(field, labels) {\n  const labelList = Array.isArray(labels) ? labels : [labels].filter(Boolean);\n  const normalizedLabels = labelList.map(normalizeComparableText);\n\n  return getCountsFromField(field).reduce((total, item) => {\n    const itemLabel = normalizeComparableText(item?.key ?? item?.label);\n    if (!normalizedLabels.includes(itemLabel)) return total;\n\n    return total + (Number(item?.count) || 0);\n  }, 0);\n}\n\nexport function getSummaryRequest(moduleName) {\n  const normalized = normalizeComparableText(moduleName);\n\n  if (normalized.includes('candidate')) return SUMMARY_REQUESTS.candidates;\n  if (normalized.includes('submission')) return SUMMARY_REQUESTS.submissions;\n  if (normalized.includes('job')) return SUMMARY_REQUESTS.jobs;\n\n  return null;\n}\n\nexport function visibleSummaryCountsFor(moduleName) {\n  return SUMMARY_VISIBLE_COUNTS[moduleName] ?? null;\n}\n\nexport function getJobSummaryItemsFromApi(data) {\n  if (Array.isArray(data?.counts) || data?.openCount !== undefined || data?.myAssignedCount !== undefined) {\n    return [\n      makeSummaryItem('Open', getCountByAliases(data, ['openCount', 'open'])),\n      makeSummaryItem(\n        'Partially Fulfilled',\n        getCountByAliases(data, ['partiallyFulfilledCount', 'partially fulfilled']),\n      ),\n      makeSummaryItem('Fulfilled', getCountByAliases(data, ['fulfilledCount', 'fulfilled'])),\n      makeSummaryItem(\n        'In-active / Closed',\n        getCountByAliases(data, ['closedCount', 'closed', 'inactive', 'in active']),\n      ),\n    ];\n  }\n\n  return (visibleSummaryCountsFor('jobSummary') ?? []).map((item) => {\n    const field = getFieldFromSummary(data, item.field);\n    return makeSummaryItem(item.label, getCountByLabels(field, item.keys ?? []));\n  });\n}\n\nexport function getCandidateSummaryItems(data) {\n  return getCountsFromField(data).map(({ label, key, count }) =>\n    makeSummaryItem(label || key, count),\n  );\n}\n\nexport function getSubmissionSummaryFromApi(data) {\n  const fields = Array.isArray(data?.fields) ? data.fields : [];\n  const clientGroup = fields.find(g => g.key === 'clientSubmissionStatus.clientSubmissionStatusText') ?? {};\n  const internalGroup = fields.find(g => g.key === 'internalSubmissionStatus.internalSubmissionStatusText') ?? {};\n\n  const toBreakdown = (g) =>\n    Array.isArray(g.counts) ? g.counts.map(({ label, count }) => makeSummaryItem(label, count)) : [];\n\n  const clientCount = Number(clientGroup.total) || 0;\n  const internalCount = Number(internalGroup.total) || 0;\n\n  return {\n    total: clientCount + internalCount,\n    clientCount,\n    internalCount,\n    clientBreakdown: toBreakdown(clientGroup),\n    internalBreakdown: toBreakdown(internalGroup),\n  };\n}\n\n\n\n\n","import { useEffect, useState } from 'react';\nimport { Button, Card, DatePicker, Select } from 'antd';\nimport { CloseOutlined } from '@ant-design/icons';\nimport AppTypography from './typography/Typography';\nimport { getDynamicCommonCount } from '../services/dashboardApi';\nimport {\n  getCandidateSummaryItems,\n  getJobSummaryItemsFromApi,\n  getSubmissionSummaryFromApi,\n  getSummaryRequest,\n} from './viewSummaryConfig';\n\nconst { RangePicker } = DatePicker;\n\nconst DATE_RANGE_OPTIONS = [\n  { value: 'today', label: 'Today' },\n  { value: 'yesterday', label: 'Yesterday' },\n  { value: 'last-7-days', label: 'Last 7 Days' },\n  { value: 'last-30-days', label: 'Last 30 Days' },\n  { value: 'this-month', label: 'This Month' },\n  { value: 'last-month', label: 'Last Month' },\n  { value: 'custom-range', label: 'Custom Range' },\n];\n\nfunction getSummaryPopupContainer(triggerNode) {\n  return triggerNode.closest('.view-summary-card') ?? document.body;\n}\n\nfunction formatDateParam(date) {\n  const year = date.getFullYear();\n  const month = String(date.getMonth() + 1).padStart(2, '0');\n  const day = String(date.getDate()).padStart(2, '0');\n\n  return `${year}-${month}-${day}`;\n}\n\nfunction addDays(date, days) {\n  const nextDate = new Date(date);\n  nextDate.setDate(nextDate.getDate() + days);\n\n  return nextDate;\n}\n\nfunction getDateRangeForPreset(rangeKey) {\n  const today = new Date();\n  const startOfThisMonth = new Date(today.getFullYear(), today.getMonth(), 1);\n  const startOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);\n  const endOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);\n\n  if (rangeKey === 'today') return { startDate: today, endDate: today };\n  if (rangeKey === 'yesterday') {\n    const yesterday = addDays(today, -1);\n    return { startDate: yesterday, endDate: yesterday };\n  }\n  if (rangeKey === 'last-30-days') return { startDate: addDays(today, -29), endDate: today };\n  if (rangeKey === 'this-month') return { startDate: startOfThisMonth, endDate: today };\n  if (rangeKey === 'last-month') return { startDate: startOfLastMonth, endDate: endOfLastMonth };\n\n  return { startDate: addDays(today, -6), endDate: today };\n}\n\nfunction getRangeParams(rangeKey, customRange) {\n  if (rangeKey === 'custom-range') {\n    const [startDate, endDate] = customRange ?? [];\n\n    if (!startDate || !endDate) return null;\n\n    return {\n      startDate: startDate.format('YYYY-MM-DD'),\n      endDate: endDate.format('YYYY-MM-DD'),\n    };\n  }\n\n  const range = getDateRangeForPreset(rangeKey);\n\n  return {\n    startDate: formatDateParam(range.startDate),\n    endDate: formatDateParam(range.endDate),\n  };\n}\n\nfunction normalizeComparableText(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\nfunction toTitleCase(value) {\n  return String(value ?? '')\n    .replace(/[-_]+/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim()\n    .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction getModuleSummaryName(moduleName) {\n  const normalized = normalizeComparableText(moduleName);\n\n  if (normalized.includes('candidate')) return 'Candidate';\n  if (normalized.includes('submission')) return 'Submission';\n  if (normalized.includes('job')) return 'Job';\n\n  return toTitleCase(moduleName || 'List');\n}\n\nfunction getPayloadData(response) {\n  return response?.data ?? response;\n}\n\nfunction buildSummaryPayload(summaryRequest, params) {\n  const payload = {\n    module: summaryRequest.module,\n    dateRange: {\n      startDate: params.startDate,\n      endDate: params.endDate,\n    },\n  };\n\n  if (summaryRequest.summary) {\n    payload.summary = summaryRequest.summary;\n  }\n  if (Array.isArray(summaryRequest.items) && summaryRequest.items.length > 0) {\n    payload.items = summaryRequest.items;\n  }\n  if (Array.isArray(summaryRequest.keys) && summaryRequest.keys.length > 0) {\n    payload.keys = summaryRequest.keys;\n  }\n  if (summaryRequest.dateField) {\n    payload.dateRange.key = summaryRequest.dateField;\n  }\n\n  return payload;\n}\n\nexport default function ViewSummaryWidget({\n  moduleName,\n  open,\n  onClose,\n}) {\n  const moduleSummaryName = getModuleSummaryName(moduleName);\n  const normalizedModule = normalizeComparableText(moduleName);\n  const isSubmission = normalizedModule.includes('submission');\n  const isJob = normalizedModule.includes('job');\n  const isCandidate = normalizedModule.includes('candidate');\n  const summaryRequest = getSummaryRequest(moduleName);\n  const defaultRange = isSubmission ? 'last-30-days' : 'last-7-days';\n  const [selectedRange, setSelectedRange] = useState(defaultRange);\n  const [customRange, setCustomRange] = useState(null);\n  const [jobSummary, setJobSummary] = useState(null);\n  const [candidateSummary, setCandidateSummary] = useState(null);\n  const [submissionSummaryData, setSubmissionSummaryData] = useState(null);\n  const [summaryError, setSummaryError] = useState('');\n  const jobItems = getJobSummaryItemsFromApi(jobSummary);\n  const candidateSummaryItems = getCandidateSummaryItems(candidateSummary);\n  const submissionSummary = getSubmissionSummaryFromApi(submissionSummaryData);\n  const totalSubmissions = Math.max(submissionSummary.total, 1);\n  const internalPercent = Math.round((submissionSummary.internalCount / totalSubmissions) * 100);\n  const clientPercent = Math.max(0, 100 - internalPercent);\n  const showCustomRange = selectedRange === 'custom-range';\n\n  useEffect(() => {\n    if (!open) return;\n\n    setSelectedRange(defaultRange);\n    setCustomRange(null);\n  }, [defaultRange, open]);\n\n  useEffect(() => {\n    if (!open || !summaryRequest) return undefined;\n\n    const params = getRangeParams(selectedRange, customRange);\n\n    if (!params) return undefined;\n\n    let cancelled = false;\n    setSummaryError('');\n\n    const summaryRequestPromise = getDynamicCommonCount(\n      buildSummaryPayload(summaryRequest, params),\n    );\n\n    summaryRequestPromise\n      .then((response) => {\n        if (cancelled) return;\n        const data = getPayloadData(response);\n\n        if (isJob) {\n          setJobSummary(data);\n          setCandidateSummary(null);\n          setSubmissionSummaryData(null);\n          return;\n        }\n\n        if (isCandidate) {\n          setCandidateSummary(data);\n          setJobSummary(null);\n          setSubmissionSummaryData(null);\n          return;\n        }\n\n        setSubmissionSummaryData(data);\n        setJobSummary(null);\n        setCandidateSummary(null);\n      })\n      .catch((error) => {\n        if (cancelled) return;\n        setJobSummary(null);\n        setCandidateSummary(null);\n        setSubmissionSummaryData(null);\n        setSummaryError(error.message || 'Could not load summary');\n      });\n\n    return () => {\n      cancelled = true;\n    };\n  }, [customRange, isCandidate, isJob, isSubmission, open, selectedRange, summaryRequest]);\n\n  if (!open) return null;\n\n  return (\n    <div className=\"view-summary-layer\" role=\"presentation\">\n      <div className=\"view-summary-scrim\" />\n      <Card\n        aria-label={`${moduleSummaryName} summary`}\n        bordered={false}\n        className={`view-summary-card view-summary-card--${isSubmission ? 'submission' : 'simple'}`}\n      >\n        <Button\n          aria-label=\"Close summary\"\n          className=\"view-summary-close\"\n          icon={<CloseOutlined />}\n          type=\"text\"\n          onClick={onClose}\n        />\n        <header className=\"view-summary-header\">\n          <AppTypography\n            className=\"view-summary-title\"\n            color=\"primary\"\n            size=\"md\"\n            tag=\"h2\"\n            variant=\"h2\"\n            weight=\"medium\"\n          >\n            {moduleSummaryName} Summary\n          </AppTypography>\n          <Select\n            aria-label=\"Summary date range\"\n            className=\"view-summary-range\"\n            popupClassName=\"view-summary-range-dropdown\"\n            getPopupContainer={getSummaryPopupContainer}\n            popupMatchSelectWidth={false}\n            value={selectedRange}\n            options={DATE_RANGE_OPTIONS}\n            onChange={(value) => {\n              setSelectedRange(value);\n              if (value !== 'custom-range') setCustomRange(null);\n            }}\n          />\n        </header>\n\n        {isSubmission ? (\n          <>\n            {showCustomRange && (\n              <RangePicker\n                allowClear\n                className=\"view-summary-custom-range view-summary-custom-range--full\"\n                format=\"MMM DD, YYYY\"\n                getPopupContainer={getSummaryPopupContainer}\n                placeholder={['Start date', 'End date']}\n                value={customRange}\n                onChange={setCustomRange}\n              />\n            )}\n            <section className=\"view-summary-submission-top\" aria-label=\"Submission totals\">\n              <div\n                className=\"view-summary-donut\"\n                style={{\n                  '--summary-internal': `${internalPercent}%`,\n                  '--summary-client': `${clientPercent}%`,\n                }}\n              >\n                <AppTypography\n                  color=\"success\"\n                  size=\"2xl\"\n                  tag=\"span\"\n                  variant=\"metric\"\n                  weight=\"semibold\"\n                >\n                  {submissionSummary.total}\n                </AppTypography>\n                <AppTypography\n                  color=\"success\"\n                  size=\"xs\"\n                  tag=\"span\"\n                  variant=\"caption\"\n                  weight=\"semibold\"\n                >\n                  Total\n                </AppTypography>\n              </div>\n              <div className=\"view-summary-legend\">\n                <AppTypography color=\"muted\" size=\"sm\" tag=\"span\" variant=\"body\" weight=\"regular\">\n                  <i className=\"view-summary-dot view-summary-dot--internal\" />\n                  Internal\n                  <AppTypography color=\"primary\" size=\"sm\" tag=\"b\" variant=\"body\" weight=\"regular\">\n                    {submissionSummary.internalCount}\n                  </AppTypography>\n                </AppTypography>\n                <AppTypography color=\"muted\" size=\"sm\" tag=\"span\" variant=\"body\" weight=\"regular\">\n                  <i className=\"view-summary-dot view-summary-dot--client\" />\n                  Client\n                  <AppTypography color=\"primary\" size=\"sm\" tag=\"b\" variant=\"body\" weight=\"regular\">\n                    {submissionSummary.clientCount}\n                  </AppTypography>\n                </AppTypography>\n              </div>\n            </section>\n            <div className=\"view-summary-divider\" />\n            <section className=\"view-summary-breakdown\">\n              <AppTypography className=\"view-summary-subtitle\" color=\"primary\" size=\"md\" tag=\"h3\" variant=\"h4\" weight=\"medium\">\n                Internal Breakdown\n              </AppTypography>\n              {submissionSummary.internalBreakdown.length > 0 ? (\n                submissionSummary.internalBreakdown.map((item) => (\n                  <div className=\"view-summary-row view-summary-row--bullet\" key={`internal-${item.label}`}>\n                    <AppTypography color=\"muted\" size=\"sm\" tag=\"span\" variant=\"body\" weight=\"regular\">\n                      <i className=\"view-summary-dot view-summary-dot--internal\" />\n                      {item.label}\n                    </AppTypography>\n                    <AppTypography color=\"primary\" size=\"sm\" tag=\"b\" variant=\"body\" weight=\"regular\">\n                      {item.count}\n                    </AppTypography>\n                  </div>\n                ))\n              ) : (\n                <AppTypography color=\"muted\" size=\"sm\" tag=\"p\" variant=\"body\" weight=\"regular\">\n                  No internal data found\n                </AppTypography>\n              )}\n              <AppTypography className=\"view-summary-subtitle\" color=\"primary\" size=\"md\" tag=\"h3\" variant=\"h4\" weight=\"medium\">\n                Client Breakdown\n              </AppTypography>\n              {submissionSummary.clientBreakdown.length > 0 ? (\n                submissionSummary.clientBreakdown.map((item) => (\n                  <div className=\"view-summary-row view-summary-row--bullet\" key={`client-${item.label}`}>\n                    <AppTypography color=\"muted\" size=\"sm\" tag=\"span\" variant=\"body\" weight=\"regular\">\n                      <i className=\"view-summary-dot view-summary-dot--client\" />\n                      {item.label}\n                    </AppTypography>\n                    <AppTypography color=\"primary\" size=\"sm\" tag=\"b\" variant=\"body\" weight=\"regular\">\n                      {item.count}\n                    </AppTypography>\n                  </div>\n                ))\n              ) : (\n                <AppTypography color=\"muted\" size=\"sm\" tag=\"p\" variant=\"body\" weight=\"regular\">\n                  No client data found\n                </AppTypography>\n              )}\n              {summaryError && (\n                <AppTypography color=\"danger\" size=\"xs\" tag=\"p\" variant=\"caption\">\n                  {summaryError}\n                </AppTypography>\n              )}\n            </section>\n          </>\n        ) : (\n          <section className=\"view-summary-breakdown\">\n            <div className=\"view-summary-section-head\">\n              <AppTypography\n                className=\"view-summary-section-title\"\n                color=\"primary\"\n                size=\"md\"\n                tag=\"h3\"\n                variant=\"h3\"\n                weight=\"medium\"\n              >\n                All {moduleSummaryName}\n              </AppTypography>\n              {showCustomRange && (\n                <RangePicker\n                  allowClear\n                  className=\"view-summary-custom-range\"\n                  format=\"MMM DD, YYYY\"\n                  getPopupContainer={getSummaryPopupContainer}\n                  placeholder={['Start date', 'End date']}\n                  value={customRange}\n                  onChange={setCustomRange}\n                />\n              )}\n            </div>\n            <div className=\"view-summary-divider\" />\n            {normalizedModule.includes('job') && (\n              <AppTypography\n                className=\"view-summary-breakdown-title\"\n                color=\"primary\"\n                size=\"sm\"\n                tag=\"h4\"\n                variant=\"h4\"\n                weight=\"regular\"\n              >\n                Breakdown\n              </AppTypography>\n            )}\n            {(isCandidate ? candidateSummaryItems : jobItems).map((item) => (\n              <div className=\"view-summary-row\" key={item.label}>\n                <AppTypography color=\"muted\" size=\"sm\" tag=\"span\" variant=\"body\">\n                  {item.label}\n                </AppTypography>\n                <AppTypography color=\"primary\" size=\"sm\" tag=\"b\" variant=\"body\">\n                  {item.count}\n                </AppTypography>\n              </div>\n            ))}\n            {summaryError && (\n              <AppTypography color=\"danger\" size=\"xs\" tag=\"p\" variant=\"caption\">\n                {summaryError}\n              </AppTypography>\n            )}\n          </section>\n        )}\n      </Card>\n    </div>\n  );\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { getDropdownValues } from '../services/dropdownApi';\n\n/**\n * Manages per-field value lists fetched from the API.\n * Debounces search calls by 300 ms to avoid hammering the server while typing.\n */\nexport function useDropdownValues(module) {\n  const [valuesByField, setValuesByField] = useState({});\n  const [loadingFields, setLoadingFields] = useState(new Set());\n  const timers = useRef({});\n\n  const setFieldLoading = (field, isLoading) => {\n    setLoadingFields((prev) => {\n      const next = new Set(prev);\n      isLoading ? next.add(field) : next.delete(field);\n      return next;\n    });\n  };\n\n  const fetchValues = useCallback((field, search = '', meta = {}) => {\n    if (!field || !module) return;\n\n    // Clear any pending debounce for this field\n    if (timers.current[field]) clearTimeout(timers.current[field]);\n\n    const delay = search ? 300 : 0;\n\n    timers.current[field] = setTimeout(async () => {\n      setFieldLoading(field, true);\n      try {\n        const data = await getDropdownValues(module, field, search, meta);\n        const options = Array.isArray(data)\n          ? data.map((item) => ({ label: String(item.label), value: item.value }))\n          : [];\n        setValuesByField((prev) => ({ ...prev, [field]: options }));\n      } catch {\n        // Keep previous options on error — don't blank out the dropdown\n      } finally {\n        setFieldLoading(field, false);\n      }\n    }, delay);\n  }, [module]);\n\n  return { valuesByField, loadingFields, fetchValues };\n}\nexport default useDropdownValues;","import { useEffect, useMemo, useRef } from 'react';\nimport {\n  Checkbox,\n  DatePicker,\n  Drawer,\n  Flex,\n  Form,\n  Input,\n  InputNumber,\n  Radio,\n  Select,\n  Space,\n  Spin,\n  Alert,\n  Tag,\n} from 'antd';\nimport { DeleteOutlined, PlusOutlined } from '@ant-design/icons';\nimport dayjs from 'dayjs';\nimport AppButton from '../AppButton';\nimport AppTypography from '../typography/Typography';\nimport { useFilterFields } from '../../hooks/useDropdownFields';\nimport { useDropdownValues } from '../../hooks/useDropdownValues';\nimport '../../styles/DynamicFieldFilter.css';\n\nconst DATE_SHORTCUTS = [\n  { label: 'Last 7 days', getDates: () => [dayjs().subtract(6, 'day'), dayjs()] },\n  { label: 'This month',  getDates: () => [dayjs().startOf('month'), dayjs()] },\n  { label: 'Overdue',     getDates: () => [null, dayjs().subtract(1, 'day')] },\n];\n\nfunction DateRangeWithShortcuts({ value, onChange, disabled }) {\n  return (\n    <Flex vertical gap={4}>\n      <DatePicker.RangePicker\n        value={value}\n        onChange={onChange}\n        disabled={disabled}\n        style={{ width: '100%' }}\n        allowEmpty={[true, true]}\n        disabledDate={(current) => current && current.isAfter(dayjs(), 'day')}\n      />\n      {!disabled && (\n        <Space size={4} wrap>\n          {DATE_SHORTCUTS.map(({ label, getDates }) => (\n            <Tag\n              key={label}\n              className=\"filter-date-shortcut\"\n              onClick={() => onChange?.(getDates())}\n            >\n              {label}\n            </Tag>\n          ))}\n        </Space>\n      )}\n    </Flex>\n  );\n}\n\nconst operatorOptions = [\n  { label: 'AND', value: 'and' },\n  { label: 'OR', value: 'or' },\n  { label: 'Is Empty', value: 'isEmpty' },\n  { label: 'Not Empty', value: 'notEmpty' },\n];\n\nconst BOOLEAN_OPTIONS = [\n  { label: 'Yes', value: 'true' },\n  { label: 'No', value: 'false' },\n];\n\nfunction NumberRangeInput({ value, onChange, disabled }) {\n  const [min, max] = Array.isArray(value) ? value : [undefined, undefined];\n  return (\n    <Flex gap={8}>\n      <InputNumber\n        disabled={disabled}\n        placeholder=\"Min\"\n        value={min}\n        onChange={(v) => onChange?.([v, max])}\n        style={{ flex: 1 }}\n      />\n      <InputNumber\n        disabled={disabled}\n        placeholder=\"Max\"\n        value={max}\n        onChange={(v) => onChange?.([min, v])}\n        style={{ flex: 1 }}\n      />\n    </Flex>\n  );\n}\n\nconst defaultFilterRow = { operator: 'and', field: undefined, values: [] };\n\nfunction renderValuesInput({ filterInputType, fieldType, disabled, loading, valueOptions, onSearch, onOpen }) {\n  // filterInputType from admin config takes precedence over fieldType-based defaults\n  const effective = filterInputType\n    || (fieldType === 'boolean' ? 'boolean' : null)\n    || (fieldType === 'date' ? 'datepicker' : null)\n    || (fieldType === 'number' ? 'number-range' : null)\n    || 'dropdown';\n\n  if (effective === 'boolean') {\n    return (\n      <Select\n        allowClear\n        disabled={disabled}\n        mode=\"multiple\"\n        options={BOOLEAN_OPTIONS}\n        placeholder=\"Select value\"\n      />\n    );\n  }\n\n  if (effective === 'text') {\n    return (\n      <Input\n        disabled={disabled}\n        placeholder=\"Type keyword...\"\n        allowClear\n      />\n    );\n  }\n\n  if (effective === 'datepicker') {\n    return <DateRangeWithShortcuts disabled={disabled} />;\n  }\n\n  if (effective === 'number-range') {\n    return <NumberRangeInput disabled={disabled} />;\n  }\n\n  if (effective === 'checkbox') {\n    return (\n      <Spin spinning={loading}>\n        <Checkbox.Group\n          disabled={disabled}\n          options={valueOptions}\n          style={{ display: 'flex', flexWrap: 'wrap', gap: '4px 16px' }}\n        />\n      </Spin>\n    );\n  }\n\n  if (effective === 'radio') {\n    return (\n      <Spin spinning={loading}>\n        <Radio.Group\n          disabled={disabled}\n          options={valueOptions}\n          style={{ display: 'flex', flexWrap: 'wrap', gap: '4px 16px' }}\n        />\n      </Spin>\n    );\n  }\n\n  // dropdown (default)\n  return (\n    <Select\n      allowClear\n      disabled={disabled}\n      loading={loading}\n      mode=\"multiple\"\n      options={valueOptions}\n      placeholder={disabled ? 'Select field first' : 'Select values'}\n      showSearch\n      filterOption={false}\n      onSearch={onSearch}\n      onDropdownVisibleChange={onOpen}\n    />\n  );\n}\n\nfunction getFieldLabel(field) {\n  return field.label ?? field.fieldLabel ?? field.name ?? field.fieldName ?? field.value;\n}\n\nfunction getFieldValue(field) {\n  return field.value ?? field.field ?? field.fieldName ?? field.name ?? field.label;\n}\n\n// Convert an applied filter row back to a form row value.\n// Applied rows carry string dates and scalar values; the form needs dayjs objects\n// for the date picker and raw values for all other inputs.\nfunction appliedRowToFormRow(row, apiFields) {\n  const meta = apiFields.find((f) => f.value === row.field);\n  const filterInputType = row.filterInputType ?? meta?.filterInputType;\n  const isDateInput = filterInputType === 'datepicker' || (!filterInputType && meta?.type === 'date');\n  const isTextInput = filterInputType === 'text';\n\n  let values = row.values ?? [];\n  if (isTextInput) {\n    values = row.value ?? '';\n  } else if (isDateInput) {\n    const from = row.from ? dayjs(row.from) : null;\n    const to   = row.to   ? dayjs(row.to)   : null;\n    values = [from, to];\n  }\n\n  return {\n    field: row.field,\n    operator: row.operator ?? 'and',\n    values,\n    locked: meta?.isDefaultFilter ?? false,\n  };\n}\n\nexport default function DynamicFieldFilter({\n  moduleName,\n  open = false,\n  filters = [],\n  onClose,\n  onApply,\n  onReset,\n}) {\n  const [form] = Form.useForm();\n  const filterRows = Form.useWatch('filters', form) ?? [];\n\n  // Fetch filter-visible fields from auth API (respects Configure → Filter tab)\n  const { fields, loading: fieldsLoading, error: fieldsError } = useFilterFields(\n    open ? moduleName : null,\n  );\n\n  const apiFields = useMemo(() => (\n    (fields ?? [])\n      .map((field) => ({\n        label: getFieldLabel(field),\n        value: getFieldValue(field),\n        type: field.type,\n        filterInputType: field.filterInputType,\n        dataSource: field.dataSource,\n        groupName: field.groupName,\n        filterGroupFields: Array.isArray(field.filterGroupFields) ? field.filterGroupFields : [],\n        filterGroupSeparator: field.filterGroupSeparator ?? ' ',\n        lookup: field.lookup ?? null,\n        isDefaultFilter:\n          field.isDefaultFilter === 1 ||\n          field.isDefaultFilter === \"1\" ||\n          field.isDefaultFilter === true,\n      }))\n      .filter((field) => field.label && field.value)\n  ), [fields]);\n\n  const defaultFields = useMemo(\n    () => apiFields.filter((field) => field.isDefaultFilter),\n    [apiFields],\n  );\n  const defaultFieldsSignature = useMemo(\n    () => defaultFields.map((field) => String(field.value)).sort().join('|'),\n    [defaultFields],\n  );\n\n  // Fields selectable via \"Add Row\" — default fields are still selectable here\n  // (e.g. to combine the same field with a different operator); duplicate\n  // selection is prevented separately via the usedFields check below.\n  const addableFields = apiFields;\n\n  const { valuesByField, loadingFields, fetchValues } = useDropdownValues(moduleName);\n\n  function fetchInitialValuesIfNeeded(field) {\n    const meta = apiFields.find((f) => f.value === field);\n    const inputType = meta?.filterInputType;\n    const noApiFetch = !field\n      || inputType === 'datepicker'\n      || inputType === 'number-range'\n      || inputType === 'text'\n      || (!inputType && ['boolean', 'date', 'number'].includes(meta?.type));\n    if (!noApiFetch) {\n      const isLookup = Boolean(meta?.lookup?.collection);\n      fetchValues(field, '', {\n        dataSource: isLookup ? 'lookup' : meta?.dataSource,\n        groupName: meta?.groupName,\n        lookup: meta?.lookup,\n        groupFields: meta?.filterGroupFields,\n        groupSeparator: meta?.filterGroupSeparator,\n      });\n    }\n  }\n\n  function buildDefaultRows() {\n    return defaultFields.length > 0\n      ? defaultFields.map((field) => ({\n        operator: 'and',\n        field: field.value,\n        values: [],\n        locked: field.isDefaultFilter,\n      }))\n      : [defaultFilterRow];\n  }\n\n  function mergeDefaultRows(rows = []) {\n    const validRows = rows.filter((row) => row?.field);\n    const existingFields = new Set(validRows.map((row) => String(row.field)));\n    const missingDefaults = defaultFields\n      .filter((field) => !existingFields.has(String(field.value)))\n      .map((field) => ({\n        operator: 'and',\n        field: field.value,\n        values: [],\n        locked: true,\n      }));\n\n    const mergedRows = [...missingDefaults, ...validRows].map((row) => ({\n      ...row,\n      locked: defaultFields.some((field) => String(field.value) === String(row.field)),\n    }));\n    return mergedRows.length > 0 ? mergedRows : [defaultFilterRow];\n  }\n\n  // Tracks whether the last `filters` prop change originated from inside this\n  // drawer (Apply / Reset). When true the external-sync effect below skips the\n  // form update — the form is already correct and re-converting applied rows\n  // back would produce stale dayjs objects for date fields.\n  const isInternalChangeRef = useRef(false);\n\n  // Sync the internal form when filters are changed from *outside* the drawer\n  // (e.g. a chip is removed from the filter chips bar in ListView).\n  const externalFiltersRef = useRef(filters);\n  useEffect(() => {\n    if (filters === externalFiltersRef.current) return;\n    externalFiltersRef.current = filters;\n\n    if (isInternalChangeRef.current) {\n      isInternalChangeRef.current = false;\n      return;\n    }\n\n    // Convert applied rows back to form rows and update the form.\n    const formRows = (filters ?? [])\n      .filter((row) => row.field)\n      .map((row) => appliedRowToFormRow(row, apiFields));\n\n    // External ListView updates (tab changes, chip removal, or an initial\n    // empty filters array) must not wipe the admin-configured default rows.\n    // This used to replace the form with a blank row after defaults had been\n    // initialized, which is why the drawer could open without its defaults.\n    const rows = mergeDefaultRows(formRows);\n    form.setFieldsValue({ filters: rows });\n    rows.forEach((row) => fetchInitialValuesIfNeeded(row.field));\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [filters, apiFields]);\n\n  const initializedRef = useRef(false);\n  const initializedDefaultsRef = useRef('');\n  const prevModuleRef = useRef(moduleName);\n  const prevLoadingRef = useRef(false);\n  useEffect(() => {\n    if (moduleName !== prevModuleRef.current) {\n      prevModuleRef.current = moduleName;\n      initializedRef.current = false;\n      initializedDefaultsRef.current = '';\n      prevLoadingRef.current = false;\n    }\n  }, [moduleName]);\n  useEffect(() => {\n    // Initialize default rows only once per mount — not on every reopen.\n    // The drawer stays mounted while closed (Drawer doesn't unmount its\n    // content), so re-running this on each open would stomp on whatever\n    // values the user had applied last time, resetting them back to blank.\n    if (!open) return;\n    const defaultsChanged = initializedDefaultsRef.current !== defaultFieldsSignature;\n    if (initializedRef.current && !defaultsChanged) return;\n\n    // Guard against the race on the very first open: this effect can run\n    // before useFilterFields' own effect has flipped fieldsLoading to true,\n    // so a stale \"loading=false, fields=[]\" snapshot would lock in the empty\n    // fallback row forever. Only initialize once a load has actually\n    // completed (loading transitioned true → false) or fields were already\n    // available (e.g. a cached result from a prior open).\n    const justFinishedLoading = prevLoadingRef.current && !fieldsLoading;\n    const alreadyHasFields = !fieldsLoading && apiFields.length > 0;\n    prevLoadingRef.current = fieldsLoading;\n    if (!justFinishedLoading && !alreadyHasFields) return;\n\n    const wasInitialized = initializedRef.current;\n    initializedRef.current = true;\n    initializedDefaultsRef.current = defaultFieldsSignature;\n    const currentRows = form.getFieldValue('filters') ?? [];\n    const rows = wasInitialized\n      ? mergeDefaultRows(currentRows)\n      : mergeDefaultRows(currentRows.length > 0 ? currentRows : buildDefaultRows());\n    form.setFieldsValue({ filters: rows });\n    rows.forEach((row) => fetchInitialValuesIfNeeded(row.field));\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, fieldsLoading, apiFields, defaultFieldsSignature]);\n\n  function handleReset() {\n    isInternalChangeRef.current = true;\n    const rows = buildDefaultRows();\n    form.setFieldsValue({ filters: rows });\n    rows.forEach((row) => fetchInitialValuesIfNeeded(row.field));\n    onApply?.({ moduleName, filters: [] });\n    onReset?.();\n    onClose?.();\n  }\n\n  function handleApply() {\n    isInternalChangeRef.current = true;\n    const raw = form.getFieldsValue();\n    const appliedFilters = (raw.filters ?? [])\n      .filter((row) => !isRowIncomplete(row))\n      .map((formRow) => {\n        const row = { ...formRow };\n        delete row.locked;\n        const meta = apiFields.find((f) => f.value === row.field);\n        const fieldLabel = meta?.label ?? row.field;\n        const filterInputType = meta?.filterInputType;\n        const isDateInput = filterInputType === 'datepicker' || meta?.type === 'date';\n        const isNumberRange = filterInputType === 'number-range'\n          || (!filterInputType && meta?.type === 'number');\n        const isTextInput = filterInputType === 'text';\n\n        if (isDateInput) {\n          const dateArr = Array.isArray(row.values) ? row.values : [];\n          const [rawFrom, rawTo] = dateArr;\n          const formatDate = (d) => {\n            if (!d) return null;\n            if (typeof d.format === 'function') return d.format('YYYY-MM-DD');\n            if (typeof d.toISOString === 'function') return d.toISOString().substring(0, 10);\n            if (d instanceof Date) return d.toISOString().substring(0, 10);\n            return null;\n          };\n          const from = formatDate(rawFrom);\n          const to = formatDate(rawTo);\n          return {\n            ...row,\n            values: [from, to].filter(Boolean),\n            from: from ?? undefined,\n            to: to ?? undefined,\n            fieldLabel,\n            filterInputType,\n          };\n        }\n\n        if (isNumberRange) {\n          const [min, max] = Array.isArray(row.values) ? row.values : [];\n          return {\n            ...row,\n            values: [min, max].filter((v) => v != null),\n            from: min != null ? String(min) : undefined,\n            to: max != null ? String(max) : undefined,\n            fieldLabel,\n            filterInputType,\n          };\n        }\n\n        if (isTextInput) {\n          const textVal = typeof row.values === 'string' ? row.values.trim() : '';\n          return {\n            ...row,\n            value: textVal,\n            values: [],\n            fieldLabel,\n            filterInputType,\n          };\n        }\n\n        return {\n          ...row,\n          values: row.values ?? [],\n          fieldLabel,\n          filterInputType,\n          groupFields: meta?.filterGroupFields ?? [],\n        };\n      });\n    onApply?.({ moduleName, filters: appliedFilters });\n    onClose?.();\n  }\n\n  function isRowIncomplete(row) {\n    if (!row?.field) return true;\n    if (row.operator === 'isEmpty' || row.operator === 'notEmpty') return false;\n    const { values } = row;\n    if (typeof values === 'string') return values.trim() === '';\n    if (Array.isArray(values)) {\n      return values.length === 0 || values.every((v) => v === null || v === undefined || v === '');\n    }\n    return true;\n  }\n\n  const hasNoCompleteRow = filterRows.length === 0 || filterRows.every(isRowIncomplete);\n\n  function handleFieldChange(rowName, newField) {\n    const currentFilters = form.getFieldValue('filters') ?? [];\n    form.setFieldValue(\n      'filters',\n      currentFilters.map((row, index) => (index === rowName ? { ...row, values: [] } : row)),\n    );\n    const meta = apiFields.find((f) => f.value === newField);\n    const inputType = meta?.filterInputType;\n    // Skip API fetch for types that use hardcoded or range inputs\n    const noApiFetch = !newField\n      || inputType === 'datepicker'\n      || inputType === 'number-range'\n      || inputType === 'text'\n      || (!inputType && ['boolean', 'date', 'number'].includes(meta?.type));\n    if (!noApiFetch) {\n      const isLookup = Boolean(meta?.lookup?.collection);\n      fetchValues(newField, '', {\n        dataSource: isLookup ? 'lookup' : meta?.dataSource,\n        groupName: meta?.groupName,\n        lookup: meta?.lookup,\n        groupFields: meta?.filterGroupFields,\n        groupSeparator: meta?.filterGroupSeparator,\n      });\n    }\n  }\n\n  return (\n    <Drawer\n      title={(\n        <AppTypography variant=\"card-title\" color=\"primary\">\n          Filters\n        </AppTypography>\n      )}\n      placement=\"right\"\n      width={720}\n      open={open}\n      onClose={onClose}\n      rootClassName=\"dynamic-field-filter\"\n      maskClosable={false}\n      footer={(\n        <Space className=\"dynamic-field-filter__footer\">\n          <AppButton onClick={handleReset}>Reset</AppButton>\n          <AppButton variant=\"primary\" onClick={handleApply} disabled={hasNoCompleteRow}>Apply</AppButton>\n        </Space>\n      )}\n    >\n\n      {fieldsError && (\n        <Alert\n          type=\"error\"\n          message=\"Could not load filter fields\"\n          description={fieldsError}\n          style={{ marginBottom: 16 }}\n          showIcon\n        />\n      )}\n\n      <Spin spinning={fieldsLoading} tip=\"Loading fields…\">\n        <Form\n          form={form}\n          layout=\"vertical\"\n          className=\"dynamic-field-filter__form\"\n          initialValues={{ filters: [defaultFilterRow] }}\n        >\n          <Form.List name=\"filters\">\n            {(formFields, { add, remove }) => (\n              <Space direction=\"vertical\" className=\"dynamic-field-filter__rows\">\n                {formFields.map((formField, index) => {\n                  const selectedField = filterRows[index]?.field;\n                  const selectedOperator = filterRows[index]?.operator;\n\n                  const selectedFieldMeta = apiFields.find(\n                    (f) => f.value === selectedField\n                  );\n\n                  const isLocked = selectedFieldMeta?.isDefaultFilter === true;\n                  const disableValues = !selectedField\n                    || selectedOperator === 'isEmpty'\n                    || selectedOperator === 'notEmpty';\n                  const selectedFieldType = selectedFieldMeta?.type ?? 'text';\n                  const selectedFilterInputType = selectedFieldMeta?.filterInputType;\n                  const valueOptions = valuesByField[selectedField] ?? [];\n                  const valuesLoading = loadingFields.has(selectedField);\n\n                  // Default (admin-configured) fields are pinned rows; only the\n                  // remaining fields can be picked when adding a new row, and a\n                  // field already used in another row can't be picked again.\n                  // Values are coerced to strings since the API can return the\n                  // field key as either a string or a number.\n                  const usedFields = new Set(\n                    filterRows\n                      .filter((_, i) => i !== index)\n                      .map((row) => row?.field)\n                      .filter(Boolean)\n                      .map(String),\n                  );\n                  const fieldOptions = isLocked\n                    ? apiFields.filter((f) => f.value === selectedField)\n                    : addableFields.filter((f) => !usedFields.has(String(f.value)));\n\n                  return (\n                    <Space\n                      key={formField.key}\n                      direction=\"vertical\"\n                      className=\"dynamic-field-filter__row\"\n                    >\n                      {formFields.length > 1 && !isLocked && (\n                        <AppButton\n                          variant=\"danger\"\n                          htmlType=\"button\"\n                          icon={<DeleteOutlined />}\n                          aria-label=\"Remove filter row\"\n                          className=\"dynamic-field-filter__remove\"\n                          onClick={() => remove(formField.name)}\n                        />\n                      )}\n\n                      {index > 0 && (\n                        <Flex justify=\"center\">\n                          <Form.Item\n                            name={[formField.name, 'operator']}\n                            rules={[{ required: true, message: 'Select condition' }]}\n                            className=\"dynamic-field-filter__operator\"\n                          >\n                            <Select options={operatorOptions} placeholder=\"Condition\" />\n                          </Form.Item>\n                        </Flex>\n                      )}\n\n                      <Flex align=\"end\" gap=\"middle\" wrap>\n                        <Form.Item\n                          label={<AppTypography variant=\"label\" color=\"secondary\">Field</AppTypography>}\n                          style={{ flex: 1, minWidth: 220 }}\n                        >\n                          {isLocked ? (\n                            <>\n                              <AppTypography variant=\"body\" className=\"dynamic-field-filter__locked-field\">\n                                {selectedFieldMeta?.label ?? selectedField}\n                              </AppTypography>\n                              <Form.Item name={[formField.name, 'field']} noStyle>\n                                <Input type=\"hidden\" />\n                              </Form.Item>\n                            </>\n                          ) : (\n                            <Form.Item\n                              name={[formField.name, 'field']}\n                              rules={[{ required: true, message: 'Select field' }]}\n                              noStyle\n                            >\n                              <Select\n                                allowClear\n                                showSearch\n                                placeholder=\"Select field\"\n                                options={fieldOptions}\n                                optionFilterProp=\"label\"\n                                loading={fieldsLoading}\n                                onChange={(val) => handleFieldChange(formField.name, val)}\n                              />\n                            </Form.Item>\n                          )}\n                        </Form.Item>\n\n                        <Form.Item\n                          label={<AppTypography variant=\"label\" color=\"secondary\">Values</AppTypography>}\n                          name={[formField.name, 'values']}\n                          style={{ flex: 1, minWidth: 220 }}\n                        >\n                          {renderValuesInput({\n                            filterInputType: selectedFilterInputType,\n                            fieldType: selectedFieldType,\n                            disabled: disableValues,\n                            loading: valuesLoading,\n                            valueOptions,\n                            onSearch: (search) => {\n                              if (selectedField) {\n                                const isLookup = Boolean(selectedFieldMeta?.lookup?.collection);\n                                fetchValues(selectedField, search, {\n                                  dataSource: isLookup ? 'lookup' : selectedFieldMeta?.dataSource,\n                                  groupName: selectedFieldMeta?.groupName,\n                                  lookup: selectedFieldMeta?.lookup,\n                                  groupFields: selectedFieldMeta?.filterGroupFields,\n                                  groupSeparator: selectedFieldMeta?.filterGroupSeparator,\n                                });\n                              }\n                            },\n                            onOpen: (visible) => {\n                              if (visible && selectedField) {\n                                const isLookup = Boolean(selectedFieldMeta?.lookup?.collection);\n                                fetchValues(selectedField, '', {\n                                  dataSource: isLookup ? 'lookup' : selectedFieldMeta?.dataSource,\n                                  groupName: selectedFieldMeta?.groupName,\n                                  lookup: selectedFieldMeta?.lookup,\n                                  groupFields: selectedFieldMeta?.filterGroupFields,\n                                  groupSeparator: selectedFieldMeta?.filterGroupSeparator,\n                                });\n                              }\n                            },\n                          })}\n                        </Form.Item>\n                      </Flex>\n                    </Space>\n                  );\n                })}\n\n                <AppButton\n                  htmlType=\"button\"\n                  variant=\"soft\"\n                  icon={<PlusOutlined />}\n                  disabled={addableFields.length > 0 && filterRows.filter((r) => r?.field).length >= addableFields.length}\n                  onClick={() => add(defaultFilterRow)}\n                >\n                  Add Row\n                </AppButton>\n              </Space>\n            )}\n          </Form.List>\n        </Form>\n      </Spin>\n\n    </Drawer>\n  );\n}\n","export default \"data:image/svg+xml,%3csvg%20width='12'%20height='12'%20viewBox='0%200%2012%2012'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M6.00035%204.69941C4.74567%204.69941%203.72701%205.71807%203.72701%206.97275C3.72701%208.22745%204.74567%209.24609%206.00035%209.24609C7.25503%209.24609%208.2737%208.22745%208.2737%206.97275C8.2737%205.71807%207.25503%204.69941%206.00035%204.69941ZM6.00035%205.87128C6.60827%205.87128%207.10182%206.36485%207.10182%206.97275C7.10182%207.58067%206.60827%208.07422%206.00035%208.07422C5.39243%208.07422%204.89888%207.58067%204.89888%206.97275C4.89888%206.36485%205.39243%205.87128%206.00035%205.87128ZM2.06843%206.41445C2.85434%204.9331%204.16742%203.92578%206.00035%203.92578C7.83328%203.92578%209.14637%204.9331%209.93227%206.41445C10.0838%206.70013%2010.4388%206.80902%2010.7245%206.65745C11.0102%206.50587%2011.1191%206.15091%2010.9675%205.86523C9.97758%203.9994%208.30902%202.75391%206.00035%202.75391C3.69169%202.75391%202.02312%203.9994%201.03322%205.86523C0.881648%206.15091%200.990538%206.50587%201.27619%206.65745C1.56187%206.80902%201.91686%206.70013%202.06843%206.41445Z'%20fill='%23586888'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='14'%20height='14'%20viewBox='0%200%2014%2014'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.6279%206.78121C12.6857%206.88148%2012.7014%207.00057%2012.6715%207.11239C12.6417%207.22422%2012.5688%207.31967%2012.4688%207.37785L7.21875%2010.4403C7.15185%2010.4794%207.0758%2010.4999%206.99836%2010.4999C6.92092%2010.4999%206.84487%2010.4794%206.77797%2010.4403L1.52797%207.37785C1.42936%207.31859%201.35806%207.22289%201.32951%207.11145C1.30095%207.00001%201.31744%206.88181%201.37539%206.78244C1.43335%206.68306%201.52811%206.61052%201.63916%206.5805C1.75022%206.55048%201.86863%206.56542%201.96875%206.62207L7%209.55605L12.0312%206.62207C12.1315%206.56428%2012.2506%206.54858%2012.3624%206.57841C12.4743%206.60824%2012.5697%206.68116%2012.6279%206.78121ZM1.3125%204.37496C1.31267%204.29833%201.33297%204.22309%201.37136%204.15677C1.40975%204.09045%201.46489%204.03538%201.53125%203.99707L6.78125%200.934566C6.84815%200.895555%206.9242%200.875%207.00164%200.875C7.07908%200.875%207.15513%200.895555%207.22203%200.934566L12.472%203.99707C12.5381%204.0356%2012.5929%204.09076%2012.6309%204.15707C12.669%204.22337%2012.6891%204.2985%2012.6891%204.37496C12.6891%204.45142%2012.669%204.52654%2012.6309%204.59285C12.5929%204.65915%2012.5381%204.71432%2012.472%204.75285L7.22203%207.81535C7.15513%207.85436%207.07908%207.87491%207.00164%207.87491C6.9242%207.87491%206.84815%207.85436%206.78125%207.81535L1.53125%204.75285C1.46489%204.71453%201.40975%204.65946%201.37136%204.59314C1.33297%204.52682%201.31267%204.45159%201.3125%204.37496ZM2.61844%204.37496L7%206.93105L11.3816%204.37496L7%201.81886L2.61844%204.37496ZM7.65625%2011.7993L7%2012.1821L1.96875%209.24707C1.86913%209.19747%201.75436%209.18769%201.64779%209.21973C1.54122%209.25177%201.45087%209.32322%201.39512%209.41953C1.33937%209.51583%201.32241%209.62977%201.3477%209.73814C1.37299%209.84651%201.43863%209.94117%201.53125%2010.0028L6.78125%2013.0653C6.84815%2013.1044%206.9242%2013.1249%207.00164%2013.1249C7.07908%2013.1249%207.15513%2013.1044%207.22203%2013.0653L8.09703%2012.5551C8.14746%2012.5266%208.19171%2012.4883%208.22723%2012.4426C8.26275%2012.3968%208.28882%2012.3444%208.30394%2012.2885C8.31906%2012.2326%208.32291%2012.1742%208.31529%2012.1167C8.30766%2012.0593%208.28871%2012.004%208.25952%2011.9539C8.23033%2011.9039%208.19149%2011.8601%208.14526%2011.8252C8.09903%2011.7903%208.04632%2011.7649%207.9902%2011.7505C7.93408%2011.7361%207.87566%2011.7331%207.81833%2011.7414C7.761%2011.7498%207.70591%2011.7695%207.65625%2011.7993Z'%20fill='%236B7280'/%3e%3cpath%20d='M10.6036%2011.3825L13.4607%209.4477C13.5813%209.36599%2013.614%209.20256%2013.5341%209.08069L13.0105%208.282C12.9303%208.15966%2012.7665%208.12478%2012.6434%208.20383L9.54053%2010.1964L8.94939%2011.4054C8.84904%2011.6106%209.03632%2011.8387%209.25715%2011.7803L10.4338%2011.469C10.4561%2011.4631%2010.4776%2011.4543%2010.4977%2011.4429L10.6036%2011.3825ZM9.54053%2010.1964L10.6036%2011.3825'%20stroke='%236B7280'%20stroke-width='0.6'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='14'%20height='14'%20viewBox='0%200%2014%2014'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cmask%20id='path-1-inside-1_8856_23533'%20fill='white'%3e%3crect%20x='1.40039'%20y='1.40039'%20width='5.09086'%20height='5.09086'%20rx='0.727266'/%3e%3c/mask%3e%3crect%20x='1.40039'%20y='1.40039'%20width='5.09086'%20height='5.09086'%20rx='0.727266'%20stroke='%23586888'%20stroke-width='1.5'%20mask='url(%23path-1-inside-1_8856_23533)'/%3e%3cmask%20id='path-2-inside-2_8856_23533'%20fill='white'%3e%3crect%20x='1.40039'%20y='7.50781'%20width='5.09086'%20height='5.09086'%20rx='0.727266'/%3e%3c/mask%3e%3crect%20x='1.40039'%20y='7.50781'%20width='5.09086'%20height='5.09086'%20rx='0.727266'%20stroke='%23586888'%20stroke-width='1.5'%20mask='url(%23path-2-inside-2_8856_23533)'/%3e%3cline%20x1='7.375'%20y1='2.93555'%20x2='12.225'%20y2='2.93555'%20stroke='%23586888'%20stroke-width='0.75'%20stroke-linecap='round'/%3e%3cline%20x1='7.375'%20y1='5.83398'%20x2='12.225'%20y2='5.83398'%20stroke='%23586888'%20stroke-width='0.75'%20stroke-linecap='round'/%3e%3cline%20x1='7.375'%20y1='8.87305'%20x2='12.225'%20y2='8.87305'%20stroke='%23586888'%20stroke-width='0.75'%20stroke-linecap='round'/%3e%3cline%20x1='7.375'%20y1='11.7227'%20x2='12.225'%20y2='11.7227'%20stroke='%23586888'%20stroke-width='0.75'%20stroke-linecap='round'/%3e%3c/svg%3e\"","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Avatar,\n  Badge,\n  Button,\n  Card,\n  Checkbox,\n  Dropdown,\n  Empty,\n  Flex,\n  Input,\n  message,\n  Popover,\n  Space,\n  Spin,\n  Table,\n  Tag,\n  Tooltip,\n  Typography,\n} from 'antd';\nimport {\n  CaretDownOutlined,\n  CaretUpOutlined,\n  DeleteOutlined,\n  DownOutlined,\n  EditOutlined,\n  FilterOutlined,\n  LinkedinFilled,\n  MailOutlined,\n  PlusOutlined,\n  SearchOutlined,\n  ShareAltOutlined,\n  RightOutlined,\n  ThunderboltOutlined,\n  UnorderedListOutlined,\n  AppstoreOutlined,\n  UserAddOutlined,\n  UserSwitchOutlined,\n} from '@ant-design/icons';\nimport { Link as RouterLink, useLocation, useNavigate, useSearchParams } from 'react-router-dom';\nimport { useFieldConfig } from '../hooks/useDropdownFields';\nimport { useMenuPermission } from '../hooks/useMenuPermission';\nimport { usePermissions } from '../hooks/usePermissions';\nimport { getCrudPermissionKey } from '../utils/actionPermission';\nimport { checkPermission, isActionValueAllowed } from '../utils/roleAllowsAction';\nimport { isActionBlocked, isRuleActionBlocked, ruleActionDisabledReason, actionDoneState, conditionMatches } from '../utils/actionRuleEngine';\nimport { getModuleDataList } from '../services/dropdownApi';\nimport { getBaseModuleName } from '../utils/modulePath';\nimport { mapListResponse } from '../services/responseMapping/mapListResponse';\nimport { clearAuthTokenOverride, fetchJsonWithAuth, setAuthTokenOverride } from '../services/authApi';\nimport { APP_ID, AUTH_URL } from '../services/apiConfig';\nimport AppBreadcrumb from './Breadcrumb';\nimport CustomPagination from './CustomPagination';\nimport DynamicTabs from './DynamicTabs';\nimport ViewSummaryWidget from './ViewSummaryWidget';\nimport DynamicFieldFilter from './filters/DynamicFieldFilter';\nimport eyeOutlinedIcon from './images/common/eyeoutlined.svg';\nimport frameIcon from './images/common/frame.svg';\nimport unorderedListOutlinedIcon from './images/common/unorderedlistoutlined.svg';\n\nconst { Text } = Typography;\n\nfunction getFieldLabel(field) {\n  return firstPresentValue(field?.label, field?.fieldLabel, field?.name, field?.fieldName, field?.value, field?.field);\n}\n\nfunction getFieldValue(field) {\n  return firstPresentValue(field?.value, field?.field, field?.fieldName, field?.name, field?.label);\n}\n\nfunction firstPresentValue(...values) {\n  return values.find((value) => value !== undefined && value !== null && String(value).trim() !== '');\n}\n\nfunction normalizePathSegments(fieldKey) {\n  return String(fieldKey ?? '')\n    .replace(/\\[(\\-?\\d+)\\]/g, '.$1')\n    .split('.')\n    .filter(Boolean);\n}\n\nfunction getNestedRecordValue(record, fieldKey) {\n  if (!fieldKey || typeof fieldKey !== 'string') return undefined;\n\n  return normalizePathSegments(fieldKey).reduce((value, segment) => {\n    if (value === null || value === undefined) return undefined;\n\n    if (/^-?\\d+$/.test(segment)) {\n      if (!Array.isArray(value)) return undefined;\n      const index = Number(segment);\n      const resolvedIndex = index < 0 ? value.length + index : index;\n      return value[resolvedIndex];\n    }\n\n    return value?.[segment];\n  }, record);\n}\n\nfunction getRecordRawValue(record, fieldKey) {\n  if (fieldKey === 'id') return record?.id ?? record?._id;\n\n  const directValue = record?.[fieldKey];\n\n  return directValue ?? getNestedRecordValue(record, fieldKey);\n}\n\nfunction getLastArrayItemValue(value, childField) {\n  if (!Array.isArray(value) || value.length === 0 || !childField) return undefined;\n\n  const lastItem = value[value.length - 1];\n  if (lastItem === null || lastItem === undefined) return undefined;\n  if (typeof lastItem !== 'object') return lastItem;\n\n  return getNestedRecordValue(lastItem, childField);\n}\n\nfunction isExternalSourceValue(value) {\n  if (Array.isArray(value)) return value.some(isExternalSourceValue);\n  if (value === null || value === undefined) return false;\n\n  const normalized = String(value).trim().toLowerCase();\n  if (!normalized) return false;\n\n  return !['all', 'internal'].includes(normalized);\n}\n\nfunction getExternalProfileSource(record) {\n  const flatProfileKey = Object.keys(record ?? {}).find((key) => (\n    /^customFields\\.[^.]*profiledata\\./i.test(key)\n    && !/^customFields\\.internalprofiledata\\./i.test(key)\n  ));\n\n  if (flatProfileKey) {\n    return flatProfileKey\n      .replace(/^customFields\\./i, '')\n      .replace(/profiledata\\..*$/i, '');\n  }\n\n  const customFields = record?.customFields;\n  if (!customFields || typeof customFields !== 'object') return '';\n\n  const profileKey = Object.keys(customFields).find((key) => (\n    /profiledata$/i.test(key)\n    && !/^internalprofiledata$/i.test(key)\n    && customFields[key]\n    && typeof customFields[key] === 'object'\n  ));\n\n  return profileKey ? profileKey.replace(/profiledata$/i, '') : '';\n}\n\nfunction isExternalSourceField(field) {\n  if (typeof field?.isVisible === 'boolean' && !field.isVisible) return false;\n  if (typeof field?.isVisible === 'string' && field.isVisible.toLowerCase() === 'false') return false;\n\n  const fieldKey = getFieldValue(field);\n  if (!fieldKey || typeof fieldKey !== 'string') return false;\n\n  return (\n    /^customFields\\.[^.]*profiledata\\./i.test(fieldKey)\n    && !/^customFields\\.internalprofiledata\\./i.test(fieldKey)\n  );\n}\n\nfunction isExternalSourceRecord(record) {\n  const explicitSources = [\n    record?.sourceType,\n    record?.profileSource,\n    record?.selectedSource,\n    record?.customFields?.sourceType,\n    record?.customFields?.profileSource,\n  ];\n\n  return explicitSources.some(isExternalSourceValue) || Boolean(getExternalProfileSource(record));\n}\n\nfunction getRecordValue(record, fieldKey) {\n  const value = getRecordRawValue(record, fieldKey);\n\n  if (value === null || value === undefined || value === '') return '-';\n  if (Array.isArray(value)) return value.join(', ');\n  if (typeof value === 'object') return Object.values(value).join(' ');\n\n  return value;\n}\n\nfunction getConfiguredDefaultValue(field) {\n  const value = field?.defaultValue;\n  if (value === null || value === undefined) return '';\n  return String(value).trim();\n}\n\nfunction shouldTreatZeroAsEmpty(field) {\n  return Boolean(field?.renderConfig?.treatZeroAsEmpty);\n}\n\nfunction isEmptyListValue(value, field = null) {\n  if (value === null || value === undefined || value === '' || value === '-') return true;\n  if (shouldTreatZeroAsEmpty(field) && (value === 0 || value === '0')) return true;\n  if (Array.isArray(value)) return value.length === 0;\n  if (typeof value === 'object') return Object.keys(value).length === 0;\n  return false;\n}\n\nfunction applyConfiguredDefaultValue(field, value) {\n  const defaultValue = getConfiguredDefaultValue(field);\n  return defaultValue && isEmptyListValue(value, field) ? defaultValue : value;\n}\n\nfunction formatAvatarDateTime(value) {\n  if (!value) return '';\n\n  const date = value instanceof Date ? value : new Date(value);\n  if (Number.isNaN(date.getTime())) return String(value);\n\n  const parts = new Intl.DateTimeFormat('en-US', {\n    month: 'short',\n    day: '2-digit',\n    year: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit',\n    hour12: true,\n  }).formatToParts(date);\n  const getPart = (type) => parts.find((part) => part.type === type)?.value ?? '';\n  const dateText = `${getPart('month')} ${getPart('day')},${getPart('year')}`;\n  const timeText = `${getPart('hour')}:${getPart('minute')} ${getPart('dayPeriod')}`;\n\n  return `${dateText} | ${timeText}`;\n}\n\nfunction getAvatarInitial(value) {\n  return String(value || 'U').trim().charAt(0).toUpperCase() || 'U';\n}\n\nfunction getAvatarFieldValue(item, keys) {\n  const key = keys.find((candidateKey) => {\n    const value = getRecordRawValue(item, candidateKey);\n    return value !== null && value !== undefined && value !== '';\n  });\n\n  return key ? getRecordValue(item, key) : '';\n}\n\nfunction normalizeAvatarItems(field, record) {\n  const rawValue = getRecordRawValue(record, field.key);\n  const items = Array.isArray(rawValue) ? rawValue : (rawValue ? [rawValue] : []);\n  const config = field.renderConfig ?? {};\n  const nameKeys = [\n    config.nameField,\n    config.labelField,\n    'recruiterName',\n    'name',\n    'fullName',\n    'displayName',\n    'userName',\n    'email',\n    'recruiterEmail',\n  ].filter(Boolean);\n  const metaKeys = [\n    config.metaField,\n    config.dateField,\n    config.assignedDateField,\n    'assignedDateTime',\n    'assignedDate',\n    'createdAt',\n  ].filter(Boolean);\n\n  return items.map((item, index) => {\n    const recordItem = typeof item === 'object' && item !== null ? item : { value: item };\n    const name = getAvatarFieldValue(recordItem, nameKeys) || String(item || 'User');\n    const metaValue = getAvatarFieldValue(recordItem, metaKeys);\n\n    return {\n      key: getAvatarFieldValue(recordItem, ['recruiterId', 'id', '_id', 'email', 'recruiterEmail']) || `${name}-${index}`,\n      name,\n      initial: getAvatarInitial(name),\n      meta: formatAvatarDateTime(metaValue),\n    };\n  });\n}\n\nfunction AvatarTooltipContent({ item }) {\n  return (\n    <div className=\"job-avatar-tooltip\">\n      <div className=\"job-avatar-tooltip-name\">{item.name}</div>\n      {item.meta && <div className=\"job-avatar-tooltip-meta\">{item.meta}</div>}\n    </div>\n  );\n}\n\nfunction AvatarMoreTooltipContent({ items }) {\n  return (\n    <div className=\"job-avatar-more-tooltip\">\n      {items.map((item) => (\n        <AvatarTooltipContent item={item} key={item.key} />\n      ))}\n    </div>\n  );\n}\n\nfunction isTrueValue(value) {\n  if (typeof value === 'boolean') return value;\n  if (typeof value === 'string') return value.toLowerCase() === 'true';\n\n  return Boolean(value);\n}\n\nfunction stringifyLinkPart(value) {\n  if (value === null || value === undefined) return '';\n  if (Array.isArray(value)) return value.join(',');\n  if (typeof value === 'object') return Object.values(value).join(' ');\n\n  return String(value);\n}\n\nfunction fillLinkTemplate(template, record) {\n  if (!template) return '';\n\n  return String(template)\n    .replace(/\\{([^}]+)\\}/g, (_, key) => encodeURIComponent(stringifyLinkPart(getRecordRawValue(record, key))))\n    .replace(/:([A-Za-z_][\\w.]*)/g, (_, key) => encodeURIComponent(stringifyLinkPart(getRecordRawValue(record, key))));\n}\n\nfunction isUrlLike(value) {\n  return /^(https?:\\/\\/|\\/)/i.test(String(value));\n}\n\nfunction getLinkTarget(target, href) {\n  const normalizedTarget = String(target ?? '').trim().toLowerCase();\n\n  if (normalizedTarget === 'blank' || normalizedTarget === '_blank') return '_blank';\n  if (normalizedTarget === 'self' || normalizedTarget === '_self') return '_self';\n  if (normalizedTarget) return target;\n  if (/^https?:\\/\\//i.test(String(href))) return '_blank';\n\n  return undefined;\n}\n\nfunction isExternalUrl(value) {\n  return /^https?:\\/\\//i.test(String(value));\n}\n\nfunction getFieldHref(field, record, value) {\n  const template = field.routeUrl\n    ?? field.routeURL\n    ?? field.linkTemplate\n    ?? field.linkUrl\n    ?? field.href\n    ?? field.url\n    ?? field.action;\n\n  if (template) return fillLinkTemplate(template, record);\n  if (isUrlLike(value)) return String(value);\n\n  return '';\n}\n\nfunction highlightText(text, query) {\n  if (!query || query.length < 3 || !text || typeof text !== 'string' || text === '-') return text;\n  const lowerText = text.toLowerCase();\n  const lowerQuery = query.toLowerCase();\n  const parts = [];\n  let lastIndex = 0;\n\n  while (lastIndex <= text.length) {\n    const matchIndex = lowerText.indexOf(lowerQuery, lastIndex);\n    if (matchIndex === -1) {\n      parts.push(text.slice(lastIndex));\n      break;\n    }\n    if (matchIndex > lastIndex) parts.push(text.slice(lastIndex, matchIndex));\n    parts.push(\n      <mark\n        key={matchIndex}\n        className=\"search-highlight\"\n        style={{ backgroundColor: '#ffff00', color: 'inherit', padding: 0, borderRadius: 2 }}\n      >\n        {text.slice(matchIndex, matchIndex + query.length)}\n      </mark>\n    );\n    lastIndex = matchIndex + query.length;\n  }\n\n  return parts;\n}\n\nfunction renderLinkedValue(field, record, value, searchQuery = '') {\n  const href = getFieldHref(field, record, value);\n  const target = getLinkTarget(field.linkTarget, href);\n  const highlightedValue = highlightText(value, searchQuery);\n\n  if (isExternalUrl(href)) {\n    return (\n      <Tooltip title={value !== '-' ? value : undefined}>\n        <a\n          className=\"job-cell-link job-cell-value\"\n          href={href}\n          rel={target === '_blank' ? 'noreferrer' : undefined}\n          target={target}\n        >\n          {highlightedValue}\n        </a>\n      </Tooltip>\n    );\n  }\n\n  return (\n    <Tooltip title={value !== '-' ? value : undefined}>\n      <RouterLink\n        className=\"job-cell-link job-cell-value\"\n        target={target}\n        to={href || '#'}\n      >\n        {highlightedValue}\n      </RouterLink>\n    </Tooltip>\n  );\n}\n\nfunction getDateDisplayMode(field) {\n  const candidates = [\n    field?.props,\n    field?.props?.format,\n    field?.props?.display,\n    field?.props?.dateDisplay,\n    field?.renderConfig?.format,\n    field?.renderConfig?.display,\n    field?.renderConfig?.dateDisplay,\n    field?.dateDisplay,\n  ];\n\n  const normalized = candidates\n    .map((value) => (typeof value === 'string' ? value.trim().toLowerCase() : ''))\n    .find(Boolean);\n\n  if (normalized === 'datetime' || normalized === 'time') return normalized;\n  return 'date';\n}\n\nfunction formatDateValue(value, field) {\n  if (value === null || value === undefined || value === '') return '-';\n\n  const date = value instanceof Date ? value : new Date(value);\n\n  if (Number.isNaN(date.getTime())) return getRecordValue({ value }, 'value');\n\n  const parts = new Intl.DateTimeFormat('en-US', {\n    month: 'short',\n    day: '2-digit',\n    year: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit',\n    hour12: true,\n    timeZone: 'UTC',\n  }).formatToParts(date);\n\n  const getPart = (type) => parts.find((part) => part.type === type)?.value ?? '';\n  const dateText = `${getPart('month')}, ${getPart('day')}, ${getPart('year')}`;\n  const timeText = `${getPart('hour')}:${getPart('minute')} ${getPart('dayPeriod')}`;\n  const mode = getDateDisplayMode(field);\n\n  if (mode === 'time') return timeText;\n  if (mode === 'datetime') return `${dateText} | ${timeText}`;\n  return dateText;\n}\nfunction isDateField(field) {\n  return /date/i.test(`${field.key ?? ''} ${field.label ?? ''} ${field.type ?? ''}`);\n}\n\nfunction normalizeTemplateValue(value) {\n  if (value === null || value === undefined || value === '') return '-';\n  if (Array.isArray(value)) return value.join(', ');\n  if (typeof value === 'object') return Object.values(value).join(' ');\n  return value;\n}\n\nfunction getDisplayTemplateValue(record, placeholderKey, field) {\n  const key = String(placeholderKey ?? '').trim();\n  if (!key) return '-';\n\n  const normalizedKey = key.replace(/^record\\./, '');\n  const arrayChildField = field?.renderConfig?.lastItemField ?? field?.renderConfig?.arrayDisplayField;\n\n  if (arrayChildField) {\n    // The configured ListView field may be a computed/virtual key such as\n    // `_fmt_client_rate`. In that case the actual array path is available only\n    // in the display template, for example `jobPayDetails.clientBudgetStart`.\n    // Resolve the placeholder's array root directly from the record and use\n    // the same final array object for every placeholder in this field.\n    const pathSegments = normalizePathSegments(normalizedKey);\n\n    for (let splitIndex = pathSegments.length - 1; splitIndex >= 1; splitIndex -= 1) {\n      const parentPath = pathSegments.slice(0, splitIndex).join('.');\n      const parentValue = getRecordRawValue(record, parentPath);\n\n      if (!Array.isArray(parentValue)) continue;\n\n      const lastItem = parentValue[parentValue.length - 1];\n      if (lastItem === null || lastItem === undefined) return '-';\n\n      const childPath = pathSegments.slice(splitIndex).join('.');\n      return normalizeTemplateValue(getNestedRecordValue(lastItem, childPath));\n    }\n\n    // Preserve support for configurations where the field itself points to\n    // the array instead of using a virtual/computed field key.\n    const fieldKey = field?.key;\n    const rawFieldValue = fieldKey ? getRecordRawValue(record, fieldKey) : undefined;\n\n    if (fieldKey && Array.isArray(rawFieldValue)) {\n      const lastItem = rawFieldValue[rawFieldValue.length - 1];\n      if (normalizedKey === fieldKey) return normalizeTemplateValue(lastItem);\n\n      const fieldPrefix = `${fieldKey}.`;\n      if (normalizedKey.startsWith(fieldPrefix)) {\n        return normalizeTemplateValue(\n          getNestedRecordValue(lastItem, normalizedKey.slice(fieldPrefix.length)),\n        );\n      }\n    }\n  }\n\n  return getRecordValue(record, normalizedKey);\n}\n\nfunction cleanGroupedTemplateSeparators(value) {\n  return String(value ?? '')\n    .replace(/\\s+/g, ' ')\n    // Drop separators left at the beginning/end when one grouped value is empty.\n    .replace(/^\\s*[-–—/:|·,]+\\s*/, '')\n    .replace(/\\s*[-–—/:|·,]+\\s*$/, '')\n    // Remove duplicated/orphan separators created by adjacent empty placeholders.\n    .replace(/\\s*([-–—/:|·,])\\s*([-–—/:|·,])\\s*/g, ' $2 ')\n    // \"3 - Yrs\" / \"$ - Hourly\" -> \"3 Yrs\" / \"$ Hourly\" when the right token vanished.\n    .replace(/\\s+[-–—]\\s+(?=[A-Za-z$€£₹])/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim();\n}\n\nfunction formatDisplayTemplate(template, record, field) {\n  if (typeof template !== 'string' || template.trim() === '') return '';\n\n  let hasResolvedValue = false;\n  const rendered = template.replace(/\\{\\{\\s*([^}]+?)\\s*\\}\\}/g, (_, key) => {\n    const value = getDisplayTemplateValue(record, key, field);\n    if (isEmptyListValue(value, field)) return '';\n    hasResolvedValue = true;\n    return String(value);\n  });\n\n  // If every placeholder is empty, static template text (e.g. \"Yrs\" or \"/ Hourly\")\n  // must not prevent the configured Default Value from being used.\n  if (!hasResolvedValue) return '';\n\n  const normalized = rendered.replace(/\\s+/g, ' ').trim();\n  return field?.renderConfig?.cleanEmptyTemplateSeparators\n    ? cleanGroupedTemplateSeparators(normalized)\n    : normalized;\n}\n\nfunction formatFieldValue(field, record) {\n  const rawValue = getRecordRawValue(record, field.key);\n  const templatedValue = formatDisplayTemplate(field.displayTemplate, record, field);\n  const arrayChildField = field.renderConfig?.lastItemField ?? field.renderConfig?.arrayDisplayField;\n\n  if (templatedValue) return templatedValue;\n\n  if (arrayChildField) {\n    const lastArrayValue = getLastArrayItemValue(rawValue, arrayChildField);\n    if (!isEmptyListValue(lastArrayValue, field)) {\n      if (Array.isArray(lastArrayValue)) return applyConfiguredDefaultValue(field, lastArrayValue.join(', '));\n      if (typeof lastArrayValue === 'object') return applyConfiguredDefaultValue(field, Object.values(lastArrayValue).join(' '));\n      return lastArrayValue;\n    }\n    return applyConfiguredDefaultValue(field, '-');\n  }\n\n  if (isDateField(field)) return applyConfiguredDefaultValue(field, formatDateValue(rawValue, field));\n\n  return applyConfiguredDefaultValue(field, getRecordValue(record, field.key));\n}\n\nfunction isConfiguredDefaultValueActive(field, record) {\n  if (!getConfiguredDefaultValue(field)) return false;\n\n  const templatedValue = formatDisplayTemplate(field.displayTemplate, record, field);\n  if (templatedValue) return false;\n\n  const rawValue = getRecordRawValue(record, field.key);\n  const arrayChildField = field.renderConfig?.lastItemField ?? field.renderConfig?.arrayDisplayField;\n\n  if (arrayChildField) {\n    return isEmptyListValue(getLastArrayItemValue(rawValue, arrayChildField), field);\n  }\n\n  if (isDateField(field)) return isEmptyListValue(formatDateValue(rawValue, field), field);\n\n  return isEmptyListValue(getRecordValue(record, field.key), field);\n}\n\nfunction capitalizeWords(value) {\n  if (value === '-' || typeof value !== 'string' || !value.trim()) return value;\n\n  return value.replace(/\\b([A-Za-z])([A-Za-z]*)\\b/g, (word, first, rest) => {\n    if (word.length > 1 && word === word.toUpperCase()) return word;\n    return `${first.toUpperCase()}${rest.toLowerCase()}`;\n  });\n}\n\nfunction formatExperienceRange(value) {\n  if (typeof value !== 'string' || !value.includes('-')) return value;\n\n  return value\n    .replace(/(^|\\s)-\\s*(\\d+)(?=\\s*[A-Za-z])/, '$10-$2')\n    .replace(/(\\d+)\\s*-\\s*(?=[A-Za-z])/, '$1-0 ');\n}\n\nfunction getOrderedFields(fields) {\n  const indexedFields = fields.map((field, index) => ({ field, index }));\n  const hasOrder = indexedFields.some(({ field }) => field.order !== undefined && field.order !== null && field.order !== '');\n\n  if (!hasOrder) return fields;\n\n  return [...indexedFields]\n    .sort((a, b) => {\n      const firstOrder = Number(a.field.order);\n      const secondOrder = Number(b.field.order);\n      const firstHasOrder = Number.isFinite(firstOrder);\n      const secondHasOrder = Number.isFinite(secondOrder);\n\n      if (firstHasOrder && secondHasOrder && firstOrder !== secondOrder) return firstOrder - secondOrder;\n      if (firstHasOrder !== secondHasOrder) return firstHasOrder ? -1 : 1;\n\n      return a.index - b.index;\n    })\n    .map(({ field }) => field);\n}\n\nfunction getActionIconUrl(action) {\n  return action.iconUrl ?? action.iconURL ?? action.icon ?? action.iconPath;\n}\n\nfunction normalizeActionButtons(actionButtons) {\n  if (!Array.isArray(actionButtons)) return [];\n\n  return actionButtons\n    .map((action, index) => ({\n      ...action,\n      key: action.key ?? action.name ?? action.label ?? action.routeUrl ?? action.type ?? String(index),\n      label: action.label ?? action.name ?? action.title ?? action.type ?? 'Action',\n      iconUrl: getActionIconUrl(action),\n    }))\n    .filter((action) => action.iconUrl);\n}\n\n// isActionButtonVisible — a column (in-cell) action button now shares the SAME\n// rule system as the row-dropdown and toolbar actions, so an action configured\n// once is gated identically wherever it renders:\n//   1. Module Action Rules (Admin → Action Rules) keyed by the action's `key` —\n//      isRuleActionBlocked hides it (e.g. \"Not my submission — hide Resubmit\",\n//      createdBy ne {currentUserId}); the same {currentUserId} token and\n//      includes/notIncludes/ne operators the other surfaces use.\n//   2. An inline `conditions` array on the button itself (same {field, operator,\n//      value} shape) — \"show only if EVERY condition matches\", so an admin can\n//      gate a single button without authoring a module rule.\n//   3. The legacy showIfField/showIfValue single-field equality (kept for\n//      backward compatibility; expressed through the same evaluator).\nfunction isActionButtonVisible(action, record, actionRules = [], scope) {\n  if (isRuleActionBlocked(action.key, record, actionRules, scope)) return false;\n\n  if (Array.isArray(action.conditions) && action.conditions.length > 0) {\n    if (!action.conditions.every((condition) => conditionMatches(condition, record, scope))) return false;\n  }\n\n  const fieldKey = action?.showIfField ?? action?.visibleWhenField;\n  if (!fieldKey) return true;\n  const operator = action?.showIfOperator || 'eq';\n  const expected = action?.showIfValue ?? action?.visibleWhenValue ?? '';\n  return conditionMatches({ field: fieldKey, operator, value: expected }, record, scope);\n}\n\n// Gates admin-configured column action buttons (e.g. the inline \"Edit\" pencil\n// icon on a list field) by the same add/edit/delete menuPermission flags used\n// for the dropdown row actions (see getCrudPermissionKey usage above), so an\n// icon configured in Admin can't bypass a role's edit/add/delete restriction.\nfunction isActionButtonAllowed(action, permissions = {}) {\n  const pk = getCrudPermissionKey(action);\n  if (pk === 'add') return permissions.canAdd !== false;\n  if (pk === 'edit') return permissions.canEdit !== false;\n  if (pk === 'delete') return permissions.canDelete !== false;\n  return true;\n}\n\nfunction renderActionButton(action, record, onPopupAction) {\n  const routeUrl = fillLinkTemplate(\n    action.routeUrl ?? action.routeURL ?? action.route ?? action.url ?? action.href,\n    record,\n  );\n  const normalizedType = normalizeComparableText(action.type ?? action.actionType);\n  const label = typeof action.label === 'function' ? action.label(record) : action.label;\n  const content = (\n    <img\n      src={action.iconUrl}\n      alt={label}\n      className=\"job-field-action-icon\"\n    />\n  );\n  const className = \"job-field-action-button\";\n\n  const done = action.__done;\n  const disabledReason = action.__disabledReason;\n  if (done || disabledReason) {\n    return (\n      <Tooltip key={action.key} title={done ? done.label : disabledReason}>\n        <button\n          aria-label={done ? done.label : `${label} (unavailable)`}\n          className={`${className} job-field-action-button--done`}\n          type=\"button\"\n          disabled\n        >\n          {content}\n        </button>\n      </Tooltip>\n    );\n  }\n\n  if (typeof action.onClick === 'function') {\n    return (\n      <Tooltip key={action.key} title={label}>\n        <button\n          aria-label={label}\n          className={className}\n          type=\"button\"\n          onClick={(event) => {\n            event.stopPropagation();\n            action.onClick(record);\n          }}\n        >\n          {content}\n        </button>\n      </Tooltip>\n    );\n  }\n\n  if ((normalizedType === 'popup' || normalizedType === 'modal' || action.popupKey) && routeUrl) {\n    return (\n      <Tooltip key={action.key} title={label}>\n        <button\n          aria-label={label}\n          className={className}\n          type=\"button\"\n          onClick={(event) => {\n            event.stopPropagation();\n            onPopupAction?.(routeUrl, record, action);\n          }}\n        >\n          {content}\n        </button>\n      </Tooltip>\n    );\n  }\n\n  if (routeUrl && (normalizedType === 'page' || routeUrl.startsWith('/'))) {\n    return (\n      <Tooltip key={action.key} title={label}>\n        <RouterLink\n          aria-label={label}\n          className={className}\n          to={routeUrl}\n        >\n          {content}\n        </RouterLink>\n      </Tooltip>\n    );\n  }\n\n  if (routeUrl) {\n    return (\n      <Tooltip key={action.key} title={label}>\n      <a\n        aria-label={label}\n        className={className}\n        href={routeUrl}\n        rel=\"noreferrer\"\n        target=\"_blank\"\n        >\n        {content}\n      </a>\n      </Tooltip >\n    );\n  }\n\n  return (\n    <Tooltip key={action.key} title={label}>\n      <button\n        aria-label={label}\n        className={className}\n        type=\"button\"\n      >\n        {content}\n      </button>\n    </Tooltip>\n  );\n}\n\n\n\nfunction getSecondaryFieldKeys(field) {\n  const secondaryFields = Array.isArray(field.secondaryFields)\n    ? field.secondaryFields\n    : [];\n  const secondaryField = field.secondaryField ? [field.secondaryField] : [];\n\n  return [...secondaryFields, ...secondaryField]\n    .filter((key, index, keys) => key && keys.indexOf(key) === index);\n}\n\nfunction getSecondaryFieldValue(field, record) {\n  const separator = field.secondarySeparator ?? ' ';\n  const values = getSecondaryFieldKeys(field)\n    .map((key) => getRecordValue(record, key))\n    .filter((value) => value !== '-');\n\n  return values.length ? values.join(` ${separator} `) : '';\n}\n\nfunction formatListText(value) {\n  return capitalizeWords(formatExperienceRange(value));\n}\n\nfunction getBadgeValueStyle(field, value) {\n  if (!Array.isArray(field.valueStyles)) return null;\n\n  const normalizedValue = normalizeComparableText(value);\n\n  return field.valueStyles.find((style) => (\n    normalizeComparableText(style?.value) === normalizedValue\n    || normalizeComparableText(style?.label) === normalizedValue\n  )) ?? null;\n}\n\nfunction getBadgeStyle(styleConfig) {\n  const color = styleConfig?.color;\n  const bg = styleConfig?.bg ?? styleConfig?.background ?? styleConfig?.backgroundColor;\n\n  return {\n    ...(color ? { '--job-cell-badge-color': color } : {}),\n    ...(bg ? { '--job-cell-badge-bg': bg } : {}),\n  };\n}\n\nfunction getBadgeVariant(styleConfig) {\n  return normalizeComparableText(styleConfig?.varient ?? styleConfig?.variant)\n    .replace(/[^a-z0-9-]/g, '-');\n}\n\nfunction renderBadgeField(field, value) {\n  const valueStyle = getBadgeValueStyle(field, value);\n  const styleConfig = valueStyle ?? field.commonStyle ?? {};\n  const rawLabel = valueStyle?.label ?? value;\n  const fullLabel = (typeof rawLabel === 'string' ? rawLabel.trim() : rawLabel) || '-';\n  const variant = getBadgeVariant(styleConfig);\n  const className = [\n    'job-cell-badge',\n    'job-cell-value',\n    variant ? `job-cell-badge--${variant}` : '',\n  ].filter(Boolean).join(' ');\n\n  const MAX_VISIBLE_ITEMS = 1;\n  const items = !valueStyle && typeof fullLabel === 'string' && fullLabel.includes(',')\n    ? fullLabel.split(',').map((item) => item.trim()).filter(Boolean)\n    : null;\n  const displayLabel = items && items.length > MAX_VISIBLE_ITEMS\n    ? `${items.slice(0, MAX_VISIBLE_ITEMS).join(', ')} +${items.length - MAX_VISIBLE_ITEMS}`\n    : fullLabel;\n\n  const badgeStyle = getBadgeStyle(styleConfig);\n\n  return (\n    <Tooltip title={fullLabel !== '-' ? fullLabel : undefined}>\n      <Tag className={className} style={badgeStyle}>\n        {displayLabel}\n      </Tag>\n    </Tooltip>\n  );\n}\n\nfunction renderAvatarField(field, record) {\n  const avatars = normalizeAvatarItems(field, record);\n  const visibleAvatars = avatars.slice(0, 2);\n  const overflowAvatars = avatars.slice(2);\n\n  if (!avatars.length) {\n    const fallback = getConfiguredDefaultValue(field) || '-';\n    return <Text className=\"job-cell-primary job-cell-value\">{fallback}</Text>;\n  }\n\n  return (\n    <span className=\"job-avatar-group\">\n      {visibleAvatars.map((item, index) => (\n        <Tooltip\n          key={item.key}\n          overlayClassName=\"job-avatar-tooltip-overlay\"\n          title={<AvatarTooltipContent item={item} />}\n        >\n          <Avatar className={`job-avatar job-avatar--${index + 1}`}>\n            {item.initial}\n          </Avatar>\n        </Tooltip>\n      ))}\n      {overflowAvatars.length > 0 && (\n        <Tooltip\n          overlayClassName=\"job-avatar-tooltip-overlay job-avatar-more-tooltip-overlay\"\n          title={<AvatarMoreTooltipContent items={overflowAvatars} />}\n        >\n          <Avatar className=\"job-avatar job-avatar--more\">\n            +{overflowAvatars.length}\n          </Avatar>\n        </Tooltip>\n      )}\n    </span>\n  );\n}\n\nfunction renderFieldValue(field, record, searchQuery = '', onPopupAction, permissions = {}, actionRules = [], scope) {\n  if (normalizeComparableText(field.renderType) === 'avatar') return renderAvatarField(field, record);\n\n  const usingDefaultValue = isConfiguredDefaultValueActive(field, record);\n  const value = formatListText(formatFieldValue(field, record));\n  const actionButtons = normalizeActionButtons(field.actionButtons)\n    .filter((action) => isActionButtonVisible(action, record, actionRules, scope))\n    .filter((action) => isActionButtonAllowed(action, permissions))\n    // Attach the same done-state / rule-disabled state the row + toolbar\n    // actions get, so a column button also greys out (with its doneLabel or the\n    // rule's reason) instead of staying clickable.\n    .map((action) => ({\n      ...action,\n      __done: actionDoneState(action, record, scope),\n      __disabledReason: ruleActionDisabledReason(action.key, record, actionRules, scope),\n    }));\n  const secondaryValue = formatListText(getSecondaryFieldValue(field, record));\n  const isBadge = normalizeComparableText(field.renderType) === 'badge';\n  const renderedValue = isBadge && value !== '-'\n    ? renderBadgeField(field, value)\n    : (!isTrueValue(field.isLink) || value === '-' || usingDefaultValue\n      ? <Tooltip title={value !== '-' ? value : undefined}><Text className=\"job-cell-primary job-cell-value\">{highlightText(value, searchQuery)}</Text></Tooltip>\n      : renderLinkedValue(field, record, value, searchQuery));\n\n  return (\n    <span className=\"job-cell-content\">\n      <span className=\"job-cell-main-line\">\n        {renderedValue}\n        {actionButtons.length > 0 && (\n          <span className=\"job-field-actions\">\n            {actionButtons\n              .filter((action) => typeof action.hiddenIf !== 'function' || !action.hiddenIf(record))\n              .map((action) => renderActionButton(action, record, onPopupAction))}\n          </span>\n        )}\n      </span>\n      {secondaryValue && (\n        <Tooltip title={secondaryValue}>\n          <span className=\"job-cell-secondary\">\n            {highlightText(secondaryValue, searchQuery)}\n          </span>\n        </Tooltip>\n      )}\n    </span>\n  );\n}\n\n// Content-based column sizing — mirrors how the cell actually renders\n// (primary value via formatFieldValue + secondary line + header label with its\n// sort trigger) and estimates a pixel width from the longest of those, so each\n// column hugs its values like the reference design instead of splitting the\n// table width evenly. Values longer than MAX_COLUMN_WIDTH still ellipsize with\n// a tooltip (handled by the .job-cell-* CSS).\nconst MIN_COLUMN_WIDTH = 130;\nconst MAX_COLUMN_WIDTH = 230;\nconst CELL_CHAR_PX = 7.2;\nconst CELL_PADDING_PX = 26;\nconst HEADER_CHAR_PX = 8;\nconst HEADER_SORTER_PX = 44;\nconst VERTICAL_SCROLLBAR_GUTTER_PX = 20;\n\nfunction estimateColumnWidth(field, records) {\n  const headerWidth = String(field.label ?? '').length * HEADER_CHAR_PX + HEADER_SORTER_PX;\n\n  if (normalizeComparableText(field.renderType) === 'avatar') {\n    return Math.max(Math.round(headerWidth), 120);\n  }\n\n  let maxChars = 0;\n  for (const record of records) {\n    const primary = String(formatListText(formatFieldValue(field, record)) ?? '');\n    const secondary = String(formatListText(getSecondaryFieldValue(field, record)) ?? '');\n    maxChars = Math.max(maxChars, primary.length, secondary.length);\n  }\n\n  // Badges add horizontal padding around the value.\n  const extra = normalizeComparableText(field.renderType) === 'badge' ? 24 : 0;\n  const contentWidth = maxChars * CELL_CHAR_PX + CELL_PADDING_PX + extra;\n\n  return Math.round(Math.min(Math.max(headerWidth, contentWidth, MIN_COLUMN_WIDTH), MAX_COLUMN_WIDTH));\n}\n\nfunction getComparableValue(record, fieldKey) {\n  const value = getRecordValue(record, fieldKey);\n  return value === '-' ? '' : String(value);\n}\n\n\nfunction normalizeComparableText(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\nfunction getTabKey(tab, index) {\n  return tab?.key ?? tab?.value ?? tab?.id ?? (index !== undefined ? String(index) : undefined);\n}\n\nfunction normalizeTabKey(tabKey) {\n  return normalizeComparableText(tabKey);\n}\n\nfunction isAllTabKey(tabKey) {\n  return ['all', ''].includes(normalizeTabKey(tabKey));\n}\n\nfunction recordMatchesTab(record, activeTab, activeTabConfig, fields, tabField) {\n  if (isAllTabKey(activeTab)) return true;\n\n  const tabValue = activeTabConfig?.filterValue\n    ?? activeTabConfig?.status\n    ?? activeTabConfig?.title\n    ?? activeTabConfig?.tabTitle\n    ?? activeTabConfig?.name\n    ?? (typeof activeTabConfig?.label === 'string' ? activeTabConfig.label : undefined)\n    ?? activeTabConfig?.value\n    ?? activeTabConfig?.key\n    ?? activeTab;\n  const normalizedTabValue = normalizeComparableText(tabValue);\n  const explicitField = activeTabConfig?.field\n    ?? activeTabConfig?.fieldName\n    ?? activeTabConfig?.filterField\n    ?? activeTabConfig?.dataIndex\n    ?? tabField;\n\n  if (explicitField) {\n    return normalizeComparableText(getRecordValue(record, explicitField)) === normalizedTabValue;\n  }\n\n  const statusFields = fields.filter((field) => {\n    const key = normalizeComparableText(field.key);\n    const label = normalizeComparableText(field.label);\n    return key.includes('status') || label.includes('status');\n  });\n  const candidateFields = statusFields.length ? statusFields : fields;\n\n  return candidateFields.some((field) => (\n    normalizeComparableText(getRecordValue(record, field.key)) === normalizedTabValue\n  ));\n}\n\nfunction getRowKey(record, index, rowKey) {\n  if (typeof rowKey === 'function') return rowKey(record, index);\n  if (typeof rowKey === 'string') return record?.[rowKey];\n\n  return record.id ?? record._id ?? record.key ?? index;\n}\n\nfunction isInteractiveClickTarget(target) {\n  return Boolean(target?.closest?.(\n    'a,button,input,textarea,select,label,[role=\"button\"],[role=\"menuitem\"],.ant-checkbox,.ant-radio,.ant-dropdown,.ant-dropdown-trigger,.ant-table-selection-column,.job-field-actions,.job-row-eye-button'\n  ));\n}\n\nfunction getActionLabel(action) {\n  return action.label ?? action.name ?? action.title ?? action.value;\n}\n\nfunction getActionKey(action, index) {\n  return action.key ?? action.value ?? action.route ?? action.name ?? String(index);\n}\n\nconst ACTION_ICON_MAP = {\n  delete: <DeleteOutlined />,\n  edit: <EditOutlined />,\n  mail: <MailOutlined />,\n  shareAlt: <ShareAltOutlined />,\n  swap: <RightOutlined />,\n  thunderbolt: <ThunderboltOutlined />,\n  userAdd: <UserAddOutlined />,\n  userSwitch: <UserSwitchOutlined />,\n};\n\n// antd's Dropdown `menu.items` only understands {key, label, icon, danger, ...}.\n// Admin-configured actions carry extra config fields (actionType, routeTemplate,\n// popupKey, popupState, ...) that must NOT be spread onto the menu item, or antd\n// forwards them straight onto the underlying DOM node. An action with\n// admin-configured children (actionType \"group\", e.g. \"Shortlist\") renders as\n// a submenu — antd's Menu natively supports this via item.children.\nfunction toMenuItem(action, done) {\n  const item = {\n    key: action.key,\n    // Config-driven \"done\" terminus (doneWhen matched, e.g. onboardingStatus\n    // set): the item shows its doneLabel (\"Moved to Onboarded\") and is disabled.\n    label: done ? done.label : action.label,\n    icon: ACTION_ICON_MAP[action.icon] ?? undefined,\n    danger: done ? undefined : (action.danger || undefined),\n    disabled: !!done || undefined,\n    title: done ? done.label : undefined,\n  };\n  if (action.children?.length) {\n    item.children = action.children.map((child) => toMenuItem(child));\n  }\n  return item;\n}\n\n// bulkDoneState — done-state for a toolbar action across the CURRENT selection:\n// the action is \"done\" only when EVERY selected record already satisfies its\n// doneWhen (you can't Move-to-Onboarding a set that's already all onboarded).\n// The common case is a single selected row. Returns { label, tone } or null.\nfunction bulkDoneState(action, records, scope) {\n  if (!action?.doneWhen?.field || !records?.length) return null;\n  return records.every((record) => actionDoneState(action, record, scope))\n    ? actionDoneState(action, records[0], scope)\n    : null;\n}\n\n// Applies predicate to every action AND recursively to its children, keeping\n// a parent (e.g. a \"group\" action) whenever the parent itself passes,\n// independent of how many children pass — so admin-configured visibility,\n// permission, and blocking rules apply the same way at every nesting level.\nfunction filterActionTree(actions, predicate) {\n  return actions\n    .filter(predicate)\n    .map((action) => (\n      action.children?.length\n        ? { ...action, children: filterActionTree(action.children, predicate) }\n        : action\n    ));\n}\n\n// Flattens a (possibly nested) action tree depth-first, so lookups by key\n// (e.g. dispatching a click on a nested \"Tag To Job\" action) work regardless\n// of nesting.\nfunction flattenActions(actions) {\n  const flat = [];\n  for (const action of actions) {\n    flat.push(action);\n    if (action.children?.length) flat.push(...flattenActions(action.children));\n  }\n  return flat;\n}\n\nfunction normalizeActions(actions) {\n  if (!Array.isArray(actions)) return [];\n\n  return actions\n    .map((action, index) => {\n      const label = getActionLabel(action);\n      const key = getActionKey(action, index);\n\n      if (!label || !key) return null;\n\n      return {\n        ...action,\n        key: String(key),\n        label,\n        route: action.route || action.routeTemplate || (\n          action.actionType === 'modal' && (action.popupKey || key)\n            ? `/popup/${action.popupKey || key}`\n            : ''\n        ),\n        children: action.children?.length ? normalizeActions(action.children) : undefined,\n      };\n    })\n    .filter(Boolean);\n}\n\nfunction isChangeStatusAction(action) {\n  const key = String(action?.key ?? '').trim().toLowerCase();\n  const label = String(action?.label ?? '').trim().toLowerCase();\n  const popupKey = String(action?.popupKey ?? '').trim().toLowerCase();\n  const route = String(action?.route ?? action?.routeTemplate ?? '').trim().toLowerCase();\n\n  return key === 'change-status'\n    || key === 'changestatus'\n    || label === 'change status'\n    || popupKey === 'change-status'\n    || route.includes('/popup/change-status');\n}\n\nfunction getClientSubmissionStatusIdentity(record) {\n  const nested = record?.clientSubmissionStatus;\n  const nestedObject = nested && typeof nested === 'object' ? nested : null;\n\n  const id = Number(\n    nestedObject?.clientSubmissionStatusId\n      ?? nestedObject?.id\n      ?? nestedObject?.uniqueId\n      ?? record?.clientSubmissionStatusId\n      ?? record?.clientStatusId\n      ?? record?.['clientSubmissionStatus.clientSubmissionStatusId']\n      ?? 0,\n  ) || 0;\n\n  const text = String(\n    nestedObject?.clientSubmissionStatusText\n      ?? nestedObject?.name\n      ?? (typeof nested === 'string' ? nested : undefined)\n      ?? record?.clientSubmissionStatusText\n      ?? record?.clientStatusText\n      ?? record?.clientStatus\n      ?? record?.['clientSubmissionStatus.clientSubmissionStatusText']\n      ?? '',\n  ).trim();\n\n  return { id, text: normalizeComparableText(text) };\n}\n\nfunction recordHasTerminalClientStatus(record, terminalStatusIds, terminalStatusNames) {\n  const current = getClientSubmissionStatusIdentity(record);\n  if (current.id > 0 && terminalStatusIds.has(current.id)) return true;\n  return Boolean(current.text && terminalStatusNames.has(current.text));\n}\n\nfunction selectedRecordsHaveTerminalClientStatus(records, terminalStatusIds, terminalStatusNames) {\n  if (!records?.length) return false;\n  return records.some((record) => recordHasTerminalClientStatus(\n    record,\n    terminalStatusIds,\n    terminalStatusNames,\n  ));\n}\n\nfunction selectedRecordsAllowAction(action, records) {\n  if (!action.permissionKey || !records.length) return true;\n  return records.every((record) => isActionValueAllowed(\n    getNestedRecordValue(record, `actionPermission.${action.permissionKey}`),\n  ));\n}\n\n// isActionBlocked / isRuleActionBlocked (per-row) now live in\n// ../utils/actionRuleEngine, shared with DetailHeaderCard.jsx so the two\n// views can no longer drift apart on operator behavior.\n\n// getRowActions — the per-row counterpart of `selectedActionItems` (which only\n// ever fed the bulk multi-select toolbar). Applied to a SINGLE record, so a\n// configured Module Action Rule can actually hide a row's own action button,\n// not just an entry in the bulk dropdown that only appears after selecting rows.\nfunction getRowActions(record, visibleActionItems, actionRules, scope) {\n  return filterActionTree(visibleActionItems, (action) => (\n    selectedRecordsAllowAction(action, [record])\n    && !isRuleActionBlocked(action.key, record, actionRules, scope)\n  ));\n}\n\nfunction getNextSortDirection(currentSortDir, sameField) {\n  if (!sameField) return 'asc';\n  if (currentSortDir === 'asc') return 'desc';\n  if (currentSortDir === 'desc') return '';\n\n  return 'asc';\n}\n\nfunction getSortTooltipText(sortDir) {\n  if (sortDir === 'asc') return 'Ascending';\n  if (sortDir === 'desc') return 'Descending';\n\n  return 'Neutral';\n}\n\nfunction renderSortHeader({ label, sortDir, sortable, onSort }) {\n  if (!sortable) {\n    return <span className=\"job-table-header-label\">{label}</span>;\n  }\n\n  const tooltipText = getSortTooltipText(sortDir);\n\n  return (\n    <div className=\"job-table-header-content\">\n      <span className=\"job-table-header-label\" title={typeof label === 'string' ? label : undefined}>\n        {label}\n      </span>\n      <Tooltip title={tooltipText} mouseEnterDelay={0.08} overlayClassName=\"job-sort-tooltip\">\n        <button\n          type=\"button\"\n          className={`job-table-sort-trigger${sortDir ? ' job-table-sort-trigger--active' : ''}`}\n          aria-label={`Sort ${typeof label === 'string' ? label : 'column'}, ${tooltipText}`}\n          onClick={(event) => {\n            event.preventDefault();\n            event.stopPropagation();\n            onSort?.();\n          }}\n        >\n          <span className=\"job-table-sort-icon-stack\">\n            <CaretUpOutlined\n              className={`job-table-sort-icon job-table-sort-icon--up${sortDir === 'asc' ? ' job-table-sort-icon--active' : ''}`}\n            />\n            <CaretDownOutlined\n              className={`job-table-sort-icon job-table-sort-icon--down${sortDir === 'desc' ? ' job-table-sort-icon--active' : ''}`}\n            />\n          </span>\n        </button>\n      </Tooltip>\n    </div>\n  );\n}\n\nfunction getDefaultListSnapshotKey({ moduleName, activeTabScope, pageSize, sort, sortDir, queryParams }) {\n  return [\n    moduleName ?? '',\n    activeTabScope ?? '',\n    pageSize,\n    sort ?? '',\n    sortDir ?? '',\n    queryParams ? JSON.stringify(queryParams) : '',\n  ].join('|');\n}\n\nfunction getPositivePage(value) {\n  const page = Number(value);\n\n  return Number.isInteger(page) && page > 0 ? page : 1;\n}\n\nfunction getPageFromSearchParams(searchParams) {\n  for (const key of searchParams.keys()) {\n    const match = /^p(\\d+)$/.exec(key);\n\n    if (match) return getPositivePage(match[1]);\n  }\n\n  return 1;\n}\n\nfunction removePageSearchParams(searchParams) {\n  [...searchParams.keys()].forEach((key) => {\n    if (/^p\\d+$/.test(key) || key === 'page') searchParams.delete(key);\n  });\n}\n\nconst EMPTY_FIELDS = [];\nconst EMPTY_QUERY_PARAMS = {};\n\n// RecordCard renders using the exact same field.render / renderFieldValue functions\n// that the list view table uses — no hardcoded field slots except name (header) and\n// action (footer). Every other visible field is a dynamic label + value row.\nfunction RecordCard({\n  record,\n  fields,\n  selected,\n  onSelect,\n  onPreview,\n  onRecordClick,\n  isControlled,\n  selectionMode = 'checkbox',\n  onPopupAction,\n  permissions,\n}) {\n  const nameField = fields.find((f) => f.cardRole === 'name');\n  const actionField = fields.find((f) => f.cardRole === 'action');\n  const headerActionField = fields.find((f) => f.cardRole === 'headerAction');\n  const bodyFields = fields.filter((f) => f !== nameField && f !== actionField && f !== headerActionField);\n\n  const nameValue = nameField ? getRecordValue(record, getFieldValue(nameField)) : '';\n\n  const actionNode = actionField?.render\n    ? actionField.render(getRecordRawValue(record, getFieldValue(actionField)), record)\n    : null;\n\n  const headerActionNode = headerActionField?.render\n    ? headerActionField.render(getRecordRawValue(record, getFieldValue(headerActionField)), record)\n    : null;\n\n  return (\n    <div\n      className={`param-card${selected ? ' param-card--selected' : ''}`}\n      aria-selected={selected}\n      onClick={(event) => {\n        if (isInteractiveClickTarget(event.target)) return;\n        onRecordClick?.();\n      }}\n      role={onRecordClick ? 'button' : undefined}\n      tabIndex={onRecordClick ? 0 : undefined}\n      onKeyDown={(event) => {\n        if (!onRecordClick || (event.key !== 'Enter' && event.key !== ' ')) return;\n        event.preventDefault();\n        onRecordClick();\n      }}\n    >\n\n      {/* Header — name always shown prominently; skips field.render (table-specific) */}\n      <div className=\"param-card__header\">\n        <div className=\"param-card__name-row\">\n          {selectionMode === 'checkbox' && (\n            <Checkbox\n              checked={selected}\n              onChange={onSelect}\n              onClick={(e) => e.stopPropagation()}\n              className=\"param-card__checkbox\"\n            />\n          )}\n          {onPreview && (\n            <button\n              type=\"button\"\n              className=\"job-row-eye-button\"\n              aria-label=\"Preview\"\n              onClick={(event) => {\n                event.stopPropagation();\n                onPreview();\n              }}\n            >\n              <img src={eyeOutlinedIcon} alt=\"\" className=\"job-row-eye-icon\" />\n            </button>\n          )}\n\n          <Text className=\"param-card__name\">{nameValue}</Text>\n          {headerActionNode && (\n            <div className=\"param-card__header-actions\">{headerActionNode}</div>\n          )}\n        </div>\n      </div>\n\n      {/* Body — every other visible field rendered dynamically, same as list columns */}\n      {bodyFields.length > 0 && (\n        <div className=\"param-card__body-fields\">\n          {bodyFields.map((field) => {\n            const fieldKey = getFieldValue(field);\n            const rawValue = getRecordRawValue(record, fieldKey);\n            const displayNode = isControlled && typeof field.render === 'function'\n              ? field.render(rawValue, record)\n              : renderFieldValue(field, record, '', onPopupAction, permissions);\n            return (\n              <div key={fieldKey} className=\"param-card__field-row\">\n                <Text className=\"param-card__field-label\">{getFieldLabel(field)}</Text>\n                <div className=\"param-card__field-value\">{displayNode}</div>\n              </div>\n            );\n          })}\n        </div>\n      )}\n\n      {/* Divider */}\n      <div className=\"param-card__divider\" />\n\n      {/* Footer — action field only */}\n      <div className=\"param-card__footer\">\n        <div className=\"param-card__footer-left\" />\n        <div className=\"param-card__footer-right\">{actionNode}</div>\n      </div>\n    </div>\n  );\n}\n\nfunction hasFilterValue(row) {\n  if (row.operator === 'isEmpty' || row.operator === 'notEmpty') return true;\n  if (row.value) return true;\n  if (row.from || row.to) return true;\n  if (Array.isArray(row.values) && row.values.length > 0) return true;\n  return false;\n}\n\nfunction formatChipFieldLabel(row) {\n  if (row.fieldLabel) return row.fieldLabel;\n  return (row.field ?? '')\n    .replace(/([A-Z])/g, ' $1')\n    .replace(/^(.)/, (s) => s.toUpperCase())\n    .trim();\n}\n\nfunction formatChipValue(row) {\n  if (row.operator === 'isEmpty') return 'Is Empty';\n  if (row.operator === 'notEmpty') return 'Not Empty';\n  if (row.value) return `\"${row.value}\"`;\n  if (row.from && row.to) return `${row.from} to ${row.to}`;\n  if (row.from) return `from ${row.from}`;\n  if (row.to) return `to ${row.to}`;\n  if (Array.isArray(row.values) && row.values.length > 0) {\n    const shown = row.values.slice(0, 2).join(', ');\n    return row.values.length > 2 ? `${shown} +${row.values.length - 2}` : shown;\n  }\n  return '';\n}\n\nfunction FilterChipsBar({ filters, onRemove, onClearAll }) {\n  const chips = (filters ?? [])\n    .map((row, originalIdx) => ({ row, originalIdx }))\n    .filter(({ row }) => row.field && hasFilterValue(row));\n\n  if (chips.length === 0) return null;\n\n  return (\n    <Flex gap={6} wrap=\"wrap\" align=\"center\" className=\"filter-chips-bar\">\n      <Text className=\"filter-chips-bar__label\">Filters:</Text>\n      {chips.map(({ row, originalIdx }) => (\n        <Tag\n          key={`${row.field}-${originalIdx}`}\n          closable\n          onClose={() => onRemove(originalIdx)}\n          className=\"filter-chip\"\n        >\n          <span className=\"filter-chip__field\">{formatChipFieldLabel(row)}</span>\n          <span className=\"filter-chip__sep\">: </span>\n          <span className=\"filter-chip__value\">{formatChipValue(row)}</span>\n        </Tag>\n      ))}\n      {chips.length > 1 && (\n        <Button type=\"link\" size=\"small\" onClick={onClearAll} className=\"filter-chips-clear\">\n          Clear all\n        </Button>\n      )}\n    </Flex>\n  );\n}\n\nexport default function ListView({\n  moduleName,\n  authToken,\n  actions = [],\n  actionRules = [],\n  breadcrumbItems = [],\n  dataSource = [],\n  className = '',\n  initialPageSize = 10,\n  onAction,\n  onSummaryClick,\n  rowKey,\n  showSummaryButton = false,\n  summaryButtonLabel = 'View Summary',\n  summaryRoute,\n  showFieldButton = true,\n  showFilterButton = true,\n  fieldButtonLabel = 'View Field',\n  fieldButtonRoute,\n  tabs,\n  tabTitleOverrides = null,\n  tableClassName = 'job-list-table',\n  // new controlled-mode props\n  fields: externalFields = EMPTY_FIELDS,\n  fieldOverrides = null,\n  extraFields = EMPTY_FIELDS,\n  listName = '',\n  loading: propLoading = false,\n  total: externalTotal,\n  current: externalCurrent,\n  pageSize: externalPageSize,\n  onPageChange,\n  onPageSizeChange,\n  onSearch,\n  toolbarExtra = null,\n  showSearch = true,\n  searchPlaceholder = 'Min 3 Chars, press Enter to search',\n  // Restrict the text search to these field keys (e.g. ['jobTitle',\n  // 'clientName']). Empty means search across all fields (default).\n  searchFields = EMPTY_FIELDS,\n  showViewToggle = false,\n  activeView = 'list',\n  onViewChange,\n  autoCardForExternalRows = true,\n  createAction,\n  onRecordClick,\n  selectedRecordId,\n  selectionMode = 'checkbox',\n  compact = false,\n  onSelectionChange,\n  // Source tab props\n  selectedSource,\n  onTabChange,\n  fetchData = getModuleDataList,\n  responseMapper = mapListResponse,\n  // Extra static params forwarded to fetchData/the module-data-list API\n  // (e.g. { assessmentId: recordId }) — merged into the request alongside\n  // scope/sort/search/filters, for nested lists scoped to a parent record.\n  queryParams = EMPTY_QUERY_PARAMS,\n  // Number of columns shown by default (before the user opts more in via the\n  // column-visibility menu). Defaults to 6; pass a different value per module\n  // when needed.\n  defaultVisibleColumnCount = 6,\n  // Set to false to hide the Add icon/button for pages that shouldn't allow\n  // creating new records from this list (e.g. read-only or nested views).\n  showAdd = true,\n  lockOuterPageScroll = false,\n}) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  // Dot-notation module names (\"job.client\") drill into nested data of the\n  // base module — permissions, create routes and role checks belong to the\n  // base module, not the nested path.\n  const baseModuleName = getBaseModuleName(moduleName);\n  const [terminalClientStatusIds, setTerminalClientStatusIds] = useState(() => new Set());\n  const [terminalClientStatusNames, setTerminalClientStatusNames] = useState(() => new Set());\n\n  useEffect(() => {\n    if (normalizeComparableText(baseModuleName) !== 'submissions') {\n      setTerminalClientStatusIds(new Set());\n      setTerminalClientStatusNames(new Set());\n      return undefined;\n    }\n\n    let cancelled = false;\n    const params = new URLSearchParams({\n      masterName: 'clientSubmissions',\n      offset: '0',\n      limit: '100',\n    });\n    if (APP_ID) params.set('app_id', APP_ID);\n\n    fetchJsonWithAuth(AUTH_URL, `/masters/dropdown?${params.toString()}`)\n      .then((response) => {\n        if (cancelled) return;\n        const rows = Array.isArray(response?.data) ? response.data : [];\n        const terminalRows = rows.filter((row) => row?.isTerminalStatus === true);\n        setTerminalClientStatusIds(new Set(\n          terminalRows\n            .map((row) => Number(row?.id ?? row?.uniqueId ?? 0))\n            .filter((id) => id > 0),\n        ));\n        setTerminalClientStatusNames(new Set(\n          terminalRows\n            .map((row) => normalizeComparableText(row?.name))\n            .filter(Boolean),\n        ));\n      })\n      .catch(() => {\n        if (cancelled) return;\n        setTerminalClientStatusIds(new Set());\n        setTerminalClientStatusNames(new Set());\n      });\n\n    return () => {\n      cancelled = true;\n    };\n  }, [baseModuleName]);\n  const shouldLockOuterPageScroll = Boolean(lockOuterPageScroll);\n  const { canView, canAdd, canEdit, canDelete } = useMenuPermission(baseModuleName);\n  const { can } = usePermissions();\n  // Callers often pass queryParams as a fresh inline object each render\n  // (e.g. queryParams={{ assessmentId: recordId }}) — memoize by value so the\n  // fetch effect below only re-runs when the actual params change.\n  const queryParamsKey = JSON.stringify(queryParams ?? EMPTY_QUERY_PARAMS);\n  const stableQueryParams = useMemo(() => queryParams ?? EMPTY_QUERY_PARAMS, [queryParamsKey]);\n  const [searchParams] = useSearchParams();\n  const routePage = getPageFromSearchParams(searchParams);\n  // Seed the active tab from `selectedSource` instead of always starting on\n  // 'all'.\n  //\n  // The tab drives `activeTabScope`, which is a dependency of the list fetch.\n  // Starting on 'all' meant the FIRST fetch went out with an empty scope, and\n  // the sync effect below then corrected the tab once the response's `tabs`\n  // arrived — firing a SECOND, identical-but-correctly-scoped fetch. Every list\n  // page therefore issued two /module-data-list calls on open, and the first of\n  // them asked the wrong question: measured on Jobs, an unscoped 648ms query\n  // whose result was thrown away, followed by the real scope=myJobs one.\n  //\n  // Every consumer passes a route TAB KEY here (jobs `/jobs/:tab`, submissions\n  // `/submissions/:tab`, campaign contacts), and internally `selectedSource` is\n  // only ever compared against tab keys — so trusting it for the first render is\n  // exactly as correct as the value the sync effect was going to arrive at.\n  // The sync still runs and still reconciles against the real tabs, so a value\n  // that turns out not to match any tab is corrected exactly as before.\n  const [activeTab, setActiveTab] = useState(() => {\n    const seed = String(selectedSource ?? '').trim();\n    return seed || 'all';\n  });\n  const [search, setSearch] = useState('');\n  const [committedSearch, setCommittedSearch] = useState('');\n  const [filtersOpen, setFiltersOpen] = useState(false);\n  const [appliedFilterRows, setAppliedFilterRows] = useState([]);\n  const [selectedRowKeys, setSelectedRowKeys] = useState([]);\n  const [selectedRows, setSelectedRows] = useState([]);\n  const [refreshKey, setRefreshKey] = useState(0);\n  const [pagination, setPagination] = useState({ current: routePage, pageSize: initialPageSize });\n  const [sortConfig, setSortConfig] = useState({ sort: '', sortDir: '' });\n  const [visibleColumnKeys, setVisibleColumnKeys] = useState([]);\n  const [columnMenuOpen, setColumnMenuOpen] = useState(false);\n  const [selectedCardIds, setSelectedCardIds] = useState([]);\n  useEffect(() => {\n    if (authToken) setAuthTokenOverride(authToken);\n    return () => {\n      if (authToken) clearAuthTokenOverride();\n    };\n  }, [authToken]);\n\n  useEffect(() => {\n    if (!shouldLockOuterPageScroll) return undefined;\n\n    document.documentElement.classList.add('listview-page-scroll-lock');\n    document.body.classList.add('listview-page-scroll-lock');\n\n    return () => {\n      document.documentElement.classList.remove('listview-page-scroll-lock');\n      document.body.classList.remove('listview-page-scroll-lock');\n    };\n  }, [shouldLockOuterPageScroll]);\n\n  // Tracks the live width of the table's wrapping element so column widths\n  // can be recalculated as the viewport / sidebar / container resizes,\n  // instead of being frozen at whatever they measured on first render.\n  const tableContainerRef = useRef(null);\n  const [tableContainerWidth, setTableContainerWidth] = useState(0);\n  const syncedSourceRef = useRef();\n  const skipNextImplicitScopeFetchRef = useRef('');\n\n  useEffect(() => {\n    const el = tableContainerRef.current;\n    if (!el || typeof ResizeObserver === 'undefined') return undefined;\n\n    const observer = new ResizeObserver((entries) => {\n      const width = entries[0]?.contentRect?.width;\n      if (typeof width === 'number') setTableContainerWidth(width);\n    });\n    observer.observe(el);\n    return () => observer.disconnect();\n  }, []);\n\n  const resolveRecordId = (record, index) => String(getRowKey(record, index, rowKey));\n  const isRecordSelected = (record, index) => (\n    String(resolveRecordId(record, index)) === String(selectedRecordId ?? '')\n  );\n\n  const handleRecordClick = (record, index) => {\n    const id = resolveRecordId(record, index);\n    if (!id) return;\n    onRecordClick?.(record, id);\n  };\n\n  const updateSelection = (keys, rows) => {\n    setSelectedRowKeys(keys);\n    setSelectedRows(rows);\n    onSelectionChange?.(keys, rows);\n  };\n  const [moduleRows, setModuleRows] = useState(dataSource);\n  const [moduleTotal, setModuleTotal] = useState(dataSource.length);\n  const [moduleTabs, setModuleTabs] = useState([]);\n  const [moduleFields, setModuleFields] = useState([]);\n  const [moduleTabField, setModuleTabField] = useState('');\n  const [moduleActions, setModuleActions] = useState([]);\n  const [moduleActionRules, setModuleActionRules] = useState([]);\n  const [moduleLoading, setModuleLoading] = useState(false);\n  const [moduleError, setModuleError] = useState(null);\n  const [defaultListSnapshot, setDefaultListSnapshot] = useState(null);\n  const [summaryOpen, setSummaryOpen] = useState(false);\n\n  const isControlled = Boolean(onPageChange || onPageSizeChange || onSearch);\n\n  // Controlled mode overrides - must be declared before useFieldConfig hook\n  const effectiveRows = isControlled ? dataSource : moduleRows;\n  const effectiveTotal = isControlled ? (externalTotal ?? 0) : moduleTotal;\n  const effectiveFields = isControlled ? externalFields : moduleFields;\n  const effectiveTabs = isControlled ? tabs : moduleTabs;\n  const effectiveTabField = isControlled ? '' : moduleTabField;\n  const effectiveError = isControlled ? null : moduleError;\n  const hasExternalSourceRows = useMemo(\n    () => effectiveRows.some((record) => isExternalSourceRecord(record)),\n    [effectiveRows],\n  );\n  const hasExternalSourceFields = useMemo(\n    () => effectiveFields.some((field) => isExternalSourceField(field)),\n    [effectiveFields],\n  );\n  // External-source rows (Dice and friends) carry a wide, sparse field set that\n  // reads badly in a table, so this OVERRIDES the caller's activeView and shows\n  // cards. It is a hard override, not a default: a caller that asks for a list\n  // does not get one, and the view toggle renders but does nothing.\n  //\n  // Kept ON by default so every existing caller behaves exactly as before. A\n  // caller that owns its own view — the candidate sourcing screen, whose Dice\n  // tab must open as a list and whose toggle must work — turns it off.\n  const resolvedActiveView =\n    (autoCardForExternalRows && (hasExternalSourceRows || hasExternalSourceFields))\n      ? 'card'\n      : activeView;\n  const configuredActions = actions.length > 0 ? actions : moduleActions;\n  const configuredActionRules = actionRules.length > 0 ? actionRules : moduleActionRules;\n  const actionItems = useMemo(() => normalizeActions(configuredActions), [configuredActions]);\n\n  const actionByKey = useMemo(() => (\n    new Map(flattenActions(actionItems).map((action) => [action.key, action]))\n  ), [actionItems]);\n  const visibleActionItems = useMemo(() => (\n    filterActionTree(actionItems, (action) => {\n      // Infer permission key: explicit > danger convention > key name\n      const pk = getCrudPermissionKey(action);\n      if (pk === 'add' && !canAdd) return false;\n      if (pk === 'edit' && !canEdit) return false;\n      if (pk === 'delete' && !canDelete) return false;\n      if (!checkPermission(can, action.permission, baseModuleName)) return false;\n      if (action.showInList === false) return false;\n      if (!action.allowedTabs) return true;\n      return action.allowedTabs.some((tab) => normalizeComparableText(tab) === normalizeComparableText(activeTab));\n    })\n  ), [actionItems, activeTab, can, canAdd, canEdit, canDelete, baseModuleName]);\n  const selectedActionItems = useMemo(() => filterActionTree(visibleActionItems, (action) => (\n    (selectedRowKeys.length === 1 || action.allowMultiple || action.danger)\n    && selectedRecordsAllowAction(action, selectedRows)\n    && !(\n      normalizeComparableText(baseModuleName) === 'submissions'\n      && isChangeStatusAction(action)\n      && selectedRecordsHaveTerminalClientStatus(\n        selectedRows,\n        terminalClientStatusIds,\n        terminalClientStatusNames,\n      )\n    )\n    && !isActionBlocked(action.key, selectedRows, configuredActionRules, activeTab)\n  )), [\n    activeTab,\n    baseModuleName,\n    configuredActionRules,\n    selectedRowKeys.length,\n    selectedRows,\n    terminalClientStatusIds,\n    terminalClientStatusNames,\n    visibleActionItems,\n  ]);\n\n  const hasModuleName = typeof moduleName === 'string'\n    ? moduleName.trim().length > 0\n    : Boolean(moduleName);\n  const createRoute = hasModuleName\n    ? `/${baseModuleName}-create${createAction ? `?action=${encodeURIComponent(createAction)}` : ''}`\n    : '';\n  useEffect(() => {\n    if (hasModuleName && !canView) {\n      navigate('/', { replace: true });\n    }\n  }, [canView, hasModuleName, navigate]);\n\n  const updatePageRoute = (page, { replace = false } = {}) => {\n    const nextSearchParams = new URLSearchParams(searchParams);\n\n    removePageSearchParams(nextSearchParams);\n\n    const baseSearch = nextSearchParams.toString();\n    const pageSearch = page > 1 ? `p${page}` : '';\n    const nextSearch = [baseSearch, pageSearch].filter(Boolean).join('&');\n    const currentSearch = location.search.replace(/^\\?/, '');\n\n    if (nextSearch !== currentSearch) {\n      navigate(\n        {\n          pathname: location.pathname,\n          search: nextSearch ? `?${nextSearch}` : '',\n        },\n        { replace },\n      );\n    }\n  };\n\n  const setPaginationPage = (page, options) => {\n    setPagination((current) => ({ ...current, current: page }));\n    updatePageRoute(page, options);\n  };\n\n  const resetPaginationPage = () => {\n    setPaginationPage(1, { replace: true });\n  };\n\n  const { config, loading: configLoading, error } = useFieldConfig(!isControlled && hasModuleName ? moduleName : null);\n\n  const handleSortChange = useCallback((fieldKey) => {\n    const sameField = sortConfig.sort === fieldKey;\n    const nextSortDir = getNextSortDirection(sortConfig.sortDir, sameField);\n    const nextSort = nextSortDir ? String(fieldKey) : '';\n\n    setSortConfig({\n      sort: nextSort,\n      sortDir: nextSortDir,\n    });\n\n    if (typeof onSearch === 'function') {\n      onSearch(nextSort, nextSortDir);\n    }\n\n    resetPaginationPage();\n  }, [onSearch, resetPaginationPage, sortConfig.sort, sortConfig.sortDir]);\n\n  useEffect(() => {\n    setPagination((current) => (\n      current.current === routePage ? current : { ...current, current: routePage }\n    ));\n  }, [routePage]);\n\n  useEffect(() => {\n    if (!isControlled) return;\n\n    setPagination((current) => {\n      const nextCurrent = getPositivePage(externalCurrent ?? current.current);\n      const nextPageSize = Number(externalPageSize) > 0 ? Number(externalPageSize) : current.pageSize;\n\n      return current.current === nextCurrent && current.pageSize === nextPageSize\n        ? current\n        : { current: nextCurrent, pageSize: nextPageSize };\n    });\n  }, [externalCurrent, externalPageSize, isControlled]);\n\n  const refreshTimestamp = location.state?.refreshTimestamp;\n  useEffect(() => {\n    if (!refreshTimestamp) return;\n    updateSelection([], []);\n    setRefreshKey((k) => k + 1);\n  }, [refreshTimestamp]);\n\n  const activeTabConfig = useMemo(() => {\n    const availableTabs = [\n      ...(Array.isArray(tabs) ? tabs : []),\n      ...moduleTabs,\n    ];\n\n    const normalizedActiveTab = normalizeTabKey(activeTab);\n    return availableTabs.find((tab, index) => normalizeTabKey(getTabKey(tab, index)) === normalizedActiveTab);\n  }, [activeTab, moduleTabs, tabs]);\n  const activeTabField = activeTabConfig?.field\n    ?? activeTabConfig?.fieldName\n    ?? activeTabConfig?.filterField\n    ?? activeTabConfig?.dataIndex\n    ?? moduleTabField;\n  const activeTabScope = isAllTabKey(activeTab) ? '' : activeTab;\n  const canFilterActiveTab = !activeTabScope\n    && !isAllTabKey(activeTab)\n    && normalizeComparableText(activeTabField).length > 0;\n  const hasActiveSearch = committedSearch.trim().length >= 3;\n  // Committed term sent to the API (server-side search across visible +\n  // lookup-resolved fields, e.g. clientName); empty until 3+ chars committed.\n  const activeSearchTerm = hasActiveSearch ? committedSearch.trim() : '';\n  const hasActiveFieldFilters = appliedFilterRows.some((row) => row.field);\n  const defaultListSnapshotKey = getDefaultListSnapshotKey({\n    moduleName,\n    activeTabScope,\n    pageSize: pagination.pageSize,\n    sort: sortConfig.sort,\n    sortDir: sortConfig.sortDir,\n    queryParams: stableQueryParams,\n  });\n  const hasUsableDefaultSnapshot = pagination.current === 1 && defaultListSnapshot?.key === defaultListSnapshotKey;\n  const knownDefaultTotal = Number(defaultListSnapshot?.total);\n  const searchFetchTotal = hasActiveSearch\n    ? (\n      Number.isFinite(knownDefaultTotal) && knownDefaultTotal > 0\n        ? knownDefaultTotal\n        : moduleTotal\n    )\n    : 0;\n\n  useEffect(() => {\n    if (isControlled) return undefined;\n\n    if (!hasModuleName) {\n      setModuleRows([]);\n      setModuleTotal(0);\n      setModuleTabs([]);\n      setModuleFields([]);\n      setModuleTabField('');\n      setModuleActions([]);\n      setModuleActionRules([]);\n      setModuleError(null);\n      return undefined;\n    }\n\n    const normalizedActiveTabScope = normalizeTabKey(activeTabScope);\n    if (\n      skipNextImplicitScopeFetchRef.current\n      && skipNextImplicitScopeFetchRef.current === normalizedActiveTabScope\n    ) {\n      skipNextImplicitScopeFetchRef.current = '';\n      return undefined;\n    }\n\n    let cancelled = false;\n    // Fetch all rows only when a local search is active so it can match across\n    // the full result set. Field filters are handled server-side, so normal\n    // pagination applies even while they're active.\n    const shouldFetchAllRows = hasActiveSearch && searchFetchTotal > pagination.pageSize;\n    const limit = shouldFetchAllRows ? searchFetchTotal : pagination.pageSize;\n    const offset = shouldFetchAllRows ? 0 : (pagination.current - 1) * pagination.pageSize;\n    setModuleLoading(!(!hasActiveSearch && !hasActiveFieldFilters && pagination.current === 1 && hasUsableDefaultSnapshot));\n    setModuleError(null);\n    fetchData(moduleName, limit, offset, {\n      scope: activeTabScope,\n      sort: sortConfig.sort,\n      sortDir: sortConfig.sortDir,\n      search: activeSearchTerm,\n      filters: appliedFilterRows,\n      queryParams: stableQueryParams,\n    })\n      .then((response) => {\n        if (cancelled) return;\n        const {\n          rows,\n          total,\n          tabs: responseTabs,\n          fields: responseFields,\n          tabField,\n          actions: responseActions,\n          actionRules: responseActionRules,\n        } = responseMapper(response, moduleName);\n        const shouldAdoptImplicitScope = (\n          !selectedSource\n          && isAllTabKey(activeTab)\n          && Array.isArray(responseTabs)\n          && responseTabs.length > 0\n          && !responseTabs.some((tab, index) => isAllTabKey(getTabKey(tab, index)))\n        );\n        const implicitScopeTabKey = shouldAdoptImplicitScope\n          ? getTabKey(responseTabs[0], 0)\n          : '';\n        const snapshotScope = implicitScopeTabKey ? String(implicitScopeTabKey) : activeTabScope;\n        const snapshotKey = getDefaultListSnapshotKey({\n          moduleName,\n          activeTabScope: snapshotScope,\n          pageSize: pagination.pageSize,\n          sort: sortConfig.sort,\n          sortDir: sortConfig.sortDir,\n          queryParams: stableQueryParams,\n        });\n\n        setModuleRows(rows);\n        setModuleTotal(total);\n        setModuleTabs(responseTabs);\n        setModuleFields(responseFields);\n        setModuleTabField(tabField);\n        setModuleActions(responseActions);\n        setModuleActionRules(responseActionRules);\n\n        if (implicitScopeTabKey) {\n          skipNextImplicitScopeFetchRef.current = normalizeTabKey(implicitScopeTabKey);\n          setActiveTab((current) => (\n            normalizeTabKey(current) === normalizeTabKey(implicitScopeTabKey)\n              ? current\n              : String(implicitScopeTabKey)\n          ));\n        }\n\n        if (!hasActiveSearch && !hasActiveFieldFilters && pagination.current === 1) {\n          setDefaultListSnapshot({\n            key: snapshotKey,\n            rows,\n            total,\n            tabs: responseTabs,\n            fields: responseFields,\n            tabField,\n            actions: responseActions,\n            actionRules: responseActionRules,\n          });\n        }\n      })\n      .catch((err) => {\n        if (cancelled) return;\n        setModuleRows([]);\n        setModuleTotal(0);\n        setModuleTabs([]);\n        setModuleFields([]);\n        setModuleTabField('');\n        setModuleActions([]);\n        setModuleActionRules([]);\n        setModuleError(err.message);\n        if (hasModuleName) {\n          message.error('Invalid module name or data could not be loaded.');\n        }\n      })\n      .finally(() => {\n        if (!cancelled) setModuleLoading(false);\n      });\n\n    return () => {\n      cancelled = true;\n    };\n  }, [activeSearchTerm, activeTab, activeTabScope, appliedFilterRows, fetchData, hasActiveFieldFilters, hasActiveSearch, hasModuleName, isControlled, moduleName, pagination.current, pagination.pageSize, refreshKey, responseMapper, searchFetchTotal, selectedSource, sortConfig.sort, sortConfig.sortDir, stableQueryParams]);\n\n  const normalizedFields = useMemo(() => {\n    const usesExternalFields = isControlled && Array.isArray(externalFields) && externalFields.length;\n    const usesModuleFields = !isControlled && Array.isArray(moduleFields) && moduleFields.length;\n    const usesConfigFields = !error && Array.isArray(config) && config.length;\n\n    const fieldSource = usesExternalFields\n      ? externalFields\n      : usesModuleFields\n        ? moduleFields\n        : (usesConfigFields ? config : []);\n\n    const moduleFieldByKey = new Map(\n      moduleFields\n        .map((field) => [getFieldValue(field), field])\n        .filter(([key]) => key)\n    );\n\n    const normalizedBase = fieldSource\n      .map((field) => {\n        const key = getFieldValue(field);\n        const moduleField = moduleFieldByKey.get(key) ?? {};\n        const override = key && fieldOverrides && typeof fieldOverrides === 'object' ? fieldOverrides[key] : null;\n        const renderConfig = override?.renderConfig\n          ? { ...(moduleField.renderConfig ?? field.renderConfig ?? {}), ...override.renderConfig }\n          : (field.renderConfig ?? moduleField.renderConfig ?? null);\n\n        return {\n          ...moduleField,\n          ...field,\n          ...(override ?? {}),\n          ...(renderConfig ? { renderConfig } : {}),\n          key,\n          label: getFieldLabel(override ?? field) ?? getFieldLabel(field) ?? getFieldLabel(moduleField),\n        };\n      })\n      .filter((field) => field.key && field.label);\n\n    const normalizedExtra = (Array.isArray(extraFields) ? extraFields : [])\n      .map((field, index) => {\n        const key = getFieldValue(field);\n        if (!key) return null;\n\n        return {\n          ...field,\n          key,\n          label: getFieldLabel(field) ?? `Field ${index + 1}`,\n          isVirtual: field.isVirtual ?? true,\n          isVisible: typeof field.isVisible === 'boolean' ? field.isVisible : true,\n        };\n      })\n      .filter(Boolean);\n\n    return getOrderedFields([...normalizedBase, ...normalizedExtra]);\n  }, [config, error, externalFields, extraFields, fieldOverrides, isControlled, moduleFields]);\n\n  const tableFields = useMemo(() => (\n    normalizedFields\n      .filter((field) => {\n        if (typeof field.isVisible === 'boolean') return field.isVisible;\n        if (typeof field.isVisible === 'string') return field.isVisible.toLowerCase() === 'true';\n        return true;\n      })\n      .map((field) => ({\n        key: field.key,\n        label: field.label,\n      }))\n  ), [normalizedFields]);\n\n  const tableFieldKeys = tableFields.map((field) => field.key);\n  const visibleTableColumnKeys = visibleColumnKeys.filter((key) => tableFieldKeys.includes(key));\n  const visibleKeys = visibleTableColumnKeys.length\n    ? visibleTableColumnKeys\n    : tableFields.slice(0, defaultVisibleColumnCount).map((field) => field.key);\n  const minimumVisibleColumns = Math.min(defaultVisibleColumnCount, tableFields.length);\n  const hasHorizontalScroll = visibleKeys.length > defaultVisibleColumnCount;\n\n  // Card view: tableHidden fields always show (they exist for cards only);\n  // all other fields respect the same visibility as list columns.\n  const visibleCardFields = useMemo(() => (\n    normalizedFields.filter((field) => !field.cardHidden && (field.tableHidden || visibleKeys.includes(field.key)))\n  ), [normalizedFields, visibleKeys]);\n\n  const filteredData = useMemo(() => {\n    const q = search.toLowerCase();\n    const sourceData = effectiveRows;\n    const tabbedData = canFilterActiveTab\n      ? sourceData.filter((record) => (\n        recordMatchesTab(record, activeTab, activeTabConfig, normalizedFields, activeTabField)\n      ))\n      : sourceData;\n\n    // When searchFields is provided, only those field keys participate in the\n    // text search; otherwise every configured field is searchable.\n    const searchableFields = searchFields.length\n      ? normalizedFields.filter((field) => searchFields.includes(field.key))\n      : normalizedFields;\n\n    const searchedData = !q || q.length < 3\n      ? tabbedData\n      : tabbedData.filter((record) => (\n        searchableFields.some((field) => (\n          String(getRecordValue(record, field.key)).toLowerCase().includes(q)\n          // Secondary display values (e.g. the client name shown under the\n          // job title) must be searchable too, not just the column's own key.\n          || getSecondaryFieldKeys(field).some((secondaryKey) => (\n            String(getRecordValue(record, secondaryKey)).toLowerCase().includes(q)\n          ))\n        ))\n      ));\n\n    // Field filters are evaluated server-side (sent via the API call); only\n    // the local text search needs client-side narrowing here.\n    return searchedData;\n  }, [activeTab, activeTabConfig, activeTabField, canFilterActiveTab, effectiveRows, normalizedFields, search, searchFields]);\n\n  const pagedFilteredData = useMemo(() => {\n    if (!hasActiveSearch) return filteredData;\n\n    const start = (pagination.current - 1) * pagination.pageSize;\n    return filteredData.slice(start, start + pagination.pageSize);\n  }, [filteredData, hasActiveSearch, pagination.current, pagination.pageSize]);\n\n  // When searching locally, use the client-filtered count. Otherwise the API\n  // already returns the correct total (accounting for server-side filters).\n  const tableTotal = hasActiveSearch ? filteredData.length : effectiveTotal;\n  const showSearchResultsCount = committedSearch.trim().length >= 3;\n  const searchResultsCount = String(filteredData.length).padStart(2, '0');\n  const hasSourceRows = effectiveTotal > 0 || effectiveRows.length > 0;\n  const shouldShowSearchInput = hasSourceRows || search.trim().length > 0 || committedSearch.trim().length > 0;\n  const emptyMessage = !hasModuleName\n    ? 'Please provide a module name to view data.'\n    : moduleError\n      ? 'Invalid module name or data could not be loaded.'\n      : error\n        ? 'Field configuration failed to load.'\n        : 'No data found.';\n  const normalizedTabTitleOverrides = useMemo(() => {\n    if (!tabTitleOverrides || typeof tabTitleOverrides !== 'object') return null;\n\n    return Object.entries(tabTitleOverrides).reduce((acc, [key, value]) => {\n      if (value === null || value === undefined) return acc;\n      acc[String(key)] = String(value);\n      return acc;\n    }, {});\n  }, [tabTitleOverrides]);\n  const listTabs = useMemo(() => {\n    const providedTabs = Array.isArray(tabs) ? tabs : [];\n    const baseTabs = providedTabs.length\n      ? providedTabs\n      : moduleTabs.length\n        ? moduleTabs\n        : [{ key: 'all', title: moduleName ?? 'List', count: tableTotal }];\n\n    if (!normalizedTabTitleOverrides || !Object.keys(normalizedTabTitleOverrides).length) {\n      return baseTabs;\n    }\n\n    return baseTabs.map((tab, index) => {\n      if (!tab || typeof tab !== 'object') return tab;\n\n      const tabKey = getTabKey(tab, index);\n      const overrideTitle = normalizedTabTitleOverrides[String(tabKey)];\n\n      if (!overrideTitle) return tab;\n\n      return {\n        ...tab,\n        title: overrideTitle,\n      };\n    });\n  }, [moduleName, moduleTabs, normalizedTabTitleOverrides, tableTotal, tabs]);\n\n  useEffect(() => {\n    if (!listTabs.length) return;\n\n    // Only reconcile against REAL tabs. Until the first response lands,\n    // `listTabs` is a synthesised placeholder (a lone \"all\"), and treating that\n    // as authoritative made this guard fight the tab the page actually asked\n    // for: it saw \"myJobs\" was not in [\"all\"], reset to \"all\", and the sync\n    // effect below then put \"myJobs\" back once the true tabs arrived — a third\n    // fetch, with the middle one unscoped and discarded.\n    const hasRealTabs = (moduleTabs?.length ?? 0) > 0 || (Array.isArray(tabs) && tabs.length > 0);\n    if (!hasRealTabs) return;\n\n    const normalizedActiveTab = normalizeTabKey(activeTab);\n    const activeTabExists = listTabs.some((tab, index) => normalizeTabKey(getTabKey(tab, index)) === normalizedActiveTab);\n\n    if (!activeTabExists) {\n      const firstTabKey = getTabKey(listTabs[0], 0);\n      if (firstTabKey) setActiveTab(String(firstTabKey));\n    }\n  }, [activeTab, listTabs, moduleTabs, tabs]);\n\n  // Tracks the last `selectedSource` value already synced into `activeTab`,\n  // so this effect only reacts to genuine external changes (a parent driving\n  // the active tab from elsewhere) instead of re-running on every internal\n  // activeTab change. It used to depend on `activeTab` and re-check against\n  // `selectedSource` on every click; if the consumer's `onTabChange` didn't\n  // echo `selectedSource` back in the same tick, that comparison would see\n  // the optimistic click as \"wrong\" and immediately snap it back to the\n  // stale prop, making tab clicks look like they did nothing.\n  useEffect(() => {\n    if (selectedSource === undefined || !listTabs.length) return;\n\n    const matchingTab = listTabs.find((tab, index) => (\n      normalizeTabKey(getTabKey(tab, index)) === normalizeTabKey(selectedSource)\n    ));\n\n    // During the first render the API-backed tabs may not be loaded yet and\n    // ListView can temporarily contain only its fallback tab. Do not cache the\n    // URL/parent-selected source until the corresponding real tab exists.\n    if (!matchingTab) return;\n\n    const nextActiveTab = String(getTabKey(matchingTab, listTabs.indexOf(matchingTab)));\n\n    if (\n      selectedSource === syncedSourceRef.current\n      && normalizeTabKey(activeTab) === normalizeTabKey(nextActiveTab)\n    ) {\n      return;\n    }\n\n    syncedSourceRef.current = selectedSource;\n    setActiveTab((current) => (\n      normalizeTabKey(current) === normalizeTabKey(nextActiveTab)\n        ? current\n        : nextActiveTab\n    ));\n  }, [activeTab, listTabs, selectedSource]);\n\n  const handlePreviewOpen = (record) => {\n    // History's pushState needs serializable state — strip any\n    // function-valued field properties (e.g. a card's custom `render`)\n    // before handing normalizedFields to navigate(), or a field with a\n    // real function attached throws DataCloneError and crashes the page.\n    const serializableFields = normalizedFields.map((field) => {\n      const clean = {};\n      Object.entries(field).forEach(([key, value]) => {\n        if (typeof value !== 'function') clean[key] = value;\n      });\n      return clean;\n    });\n    navigate('/popup/preview', {\n      state: {\n        background: location,\n        moduleName: baseModuleName,\n        record,\n        fields: serializableFields,\n      },\n    });\n  };\n\n  // openRowPopup — fires a per-row \"popup\" action button (Admin > Users >\n  // List View > Action Buttons, type=\"popup\"), reusing the exact route-based\n  // modal mechanism the toolbar bulk actions use (see handleActionClick's\n  // action.route branch below), just scoped to this single record instead of\n  // the current multi-row selection.\n  const openRowPopup = (routeUrl, record, action = {}) => {\n    const resolvedRoute = fillLinkTemplate(routeUrl, record);\n    const normalizedRoute = resolvedRoute.startsWith('/') ? resolvedRoute : `/${resolvedRoute}`;\n    const recordId = record?._id ?? record?.id;\n\n    navigate(normalizedRoute, {\n      state: {\n        background: location,\n        selectedIds: recordId !== undefined ? [recordId] : [],\n        selectedRecords: [record],\n        moduleName: baseModuleName,\n        popupContext: action.popupState ?? {},\n        popupAction: {\n          key: action.key,\n          apiMethod: action.apiMethod,\n          apiPath: action.apiPath,\n          defaultTemplateId: action.defaultTemplateId,\n          requireJobId: action.requireJobId,\n          popupKey: action.popupKey,\n          actionType: action.actionType ?? action.type,\n          popupFieldOverrides: action.popupFieldOverrides,\n        },\n        requireJobId: action.requireJobId,\n        ...action.popupState,\n      },\n    });\n  };\n\n  const columns = useMemo(() => {\n    const iconColumn = {\n      dataIndex: 'icons',\n      key: 'icons',\n      visibilityKey: 'jobsGroup',\n      fixed: 'left',\n      width: 25,\n      render: (_, record) => (\n        <Space size={4} className=\"job-row-icons\">\n          <button\n            type=\"button\"\n            className=\"job-row-eye-button\"\n            aria-label=\"Preview job\"\n            onClick={() => handlePreviewOpen(record)}\n          >\n            <img src={eyeOutlinedIcon} alt=\"\" className=\"job-row-eye-icon\" />\n          </button>\n\n          {record.hasLinkedIn && (\n            <Tooltip title=\"LinkedIn\">\n              <LinkedinFilled className=\"job-row-linkedin-icon\" />\n            </Tooltip>\n          )}\n        </Space>\n      ),\n    };\n\n    const dataColumns = normalizedFields\n      .filter((field) => visibleKeys.includes(field.key))\n      .map((field, idx) => {\n        const sortDir = sortConfig.sort === field.key ? sortConfig.sortDir : '';\n\n        return {\n          title: renderSortHeader({\n            label: field.label,\n            sortDir,\n            sortable: hasSourceRows,\n            onSort: () => handleSortChange(field.key),\n          }),\n          dataIndex: field.key,\n          key: field.key,\n          fixed: idx === 0 ? 'left' : undefined,\n          ellipsis: { showTitle: false },\n          width: estimateColumnWidth(field, pagedFilteredData),\n          render: (_, record) => renderFieldValue(field, record, committedSearch, openRowPopup, { canAdd, canEdit, canDelete }, configuredActionRules, activeTabScope),\n        };\n      });\n\n    // Grow the data columns to fill any leftover horizontal space instead of\n    // leaving a gap after the last column — the extra width is shared out in\n    // proportion to each column's own content-based width, so on wide\n    // screens (or pages with only a handful of columns) every column widens\n    // together rather than the table stopping short of the container edge.\n    // Only applies when the table isn't already horizontally scrolling\n    // (scroll.x unset, columns fit the viewport) and the container has been\n    // measured.\n    if (!(hasHorizontalScroll || isControlled) && tableContainerWidth > 0 && dataColumns.length > 0) {\n      // Reserve room for the table's own vertical scrollbar (it eats into\n      // the table's content width from the inside, after tableContainerWidth\n      // was measured on the outer wrapper) — otherwise columns are sized to\n      // the full wrapper width, overflow by the scrollbar's width, and a\n      // fixed column then forces an unwanted horizontal scrollbar just to\n      // reach those last few pixels.\n      const reservedWidth = iconColumn.width\n        + (hasSourceRows && selectionMode === 'checkbox' ? 48 : 0)\n        + VERTICAL_SCROLLBAR_GUTTER_PX;\n      const naturalTotal = dataColumns.reduce((sum, col) => sum + col.width, 0);\n      const availableWidth = tableContainerWidth - reservedWidth - naturalTotal;\n\n      if (availableWidth > 0 && naturalTotal > 0) {\n        dataColumns.forEach((col) => {\n          col.width = Math.floor(col.width + (availableWidth * (col.width / naturalTotal)));\n        });\n      }\n    }\n\n    return [\n      iconColumn,\n      ...dataColumns,\n    ];\n  }, [activeTab, canAdd, canDelete, canEdit, committedSearch, configuredActionRules, handleSortChange, hasHorizontalScroll, hasSourceRows, isControlled, location, moduleName, navigate, normalizedFields, pagedFilteredData, selectionMode, sortConfig.sort, sortConfig.sortDir, tableContainerWidth, visibleActionItems, visibleKeys]);\n\n  const handleTabChangeInternal = useCallback((key) => {\n    const selectedTab = listTabs.find((tab, index) => normalizeTabKey(getTabKey(tab, index)) === normalizeTabKey(key));\n    const nextKey = String(selectedTab ? getTabKey(selectedTab, listTabs.indexOf(selectedTab)) : key);\n\n    setActiveTab(nextKey);\n    setSelectedRowKeys([]);\n    setSelectedRows([]);\n    resetPaginationPage();\n\n    // Tab syncing (selectedSource/onTabChange) is its own controlled-mode\n    // concern, independent of pagination — gating this on `isControlled`\n    // (which only reflects onPageChange/onPageSizeChange/onSearch) meant a\n    // consumer could pass selectedSource for tab tracking without pagination\n    // control and never get notified, or the reverse. Call it whenever it's\n    // actually provided.\n    if (typeof onTabChange === 'function') {\n      const newSource = selectedTab?.key ?? selectedTab?.value ?? selectedTab?.id ?? nextKey;\n      // Mark this as already-synced so the selectedSource effect above\n      // doesn't treat the parent's echoed-back value as a fresh external\n      // change and re-run redundantly.\n      syncedSourceRef.current = newSource;\n      onTabChange(newSource);\n    }\n  }, [onTabChange, listTabs, resetPaginationPage]);\n\n  // handleActionClickForRecords is the action-execution body, parameterized\n  // over which ids/records it acts on. handleActionClick (the bulk toolbar\n  // handler) and the per-row action column both delegate to it, so a single\n  // row's action click behaves exactly like selecting just that one row.\n  // Declared as a function (not `const fn = () => {}`) so it's hoisted within\n  // this component body — the columns useMemo above references\n  // handleRowActionClick, which delegates here, even though this definition\n  // appears later in source order.\n  function handleActionClickForRecords(key, ids, records) {\n    const action = actionByKey.get(String(key));\n\n    if (!action) return;\n    // Group actions (e.g. \"Shortlist\") only render a submenu of their\n    // children — clicking the group itself is a no-op.\n    if (action.actionType === 'group') return;\n\n    if (typeof onAction === 'function') {\n      onAction({ key: action.key, label: action.label, selectedIds: ids, selectedRecords: records });\n    }\n\n    if (typeof action.onClick === 'function') {\n      action.onClick({ action, selectedIds: ids, selectedRecords: records });\n      return;\n    }\n    if (action.actionType === 'copy') {\n      const values = records\n        .map((record) => getNestedRecordValue(record, action.copyField || 'id') ?? record?._id)\n        .filter((value) => value !== undefined && value !== null);\n      navigator.clipboard.writeText(values.join('\\n'))\n        .then(() => message.success('Copied to clipboard'))\n        .catch(() => message.error('Could not copy to clipboard'));\n      return;\n    }\n    if (action.actionType === 'api' && action.apiPath) {\n      const firstRecord = records[0] ?? {};\n      const apiPath = fillLinkTemplate(action.apiPath, firstRecord);\n      fetchJsonWithAuth(AUTH_URL, apiPath.startsWith('/') ? apiPath : `/${apiPath}`, {\n        method: action.apiMethod || 'POST',\n        body: ['GET', 'DELETE'].includes(String(action.apiMethod).toUpperCase())\n          ? undefined\n          : JSON.stringify({ ids, records }),\n      })\n        .then(() => {\n          message.success(`${action.label} completed`);\n          setRefreshKey((value) => value + 1);\n        })\n        .catch((error) => message.error(error.message || `${action.label} failed`));\n      return;\n    }\n    if (action.route) {\n      const firstRecord = records[0] ?? {};\n      const resolvedRoute = fillLinkTemplate(action.route, firstRecord);\n      const normalizedRoute = resolvedRoute.startsWith('/') ? resolvedRoute : `/${resolvedRoute}`;\n\n      if (action.route.startsWith('/popup/') || action.route.startsWith('popup/')) {\n        const popupKeyPath = action.popupKey || action.route?.replace(/^\\/popup\\//i, '') || '';\n        const isQuickSubmitPopup = /(?:^|\\/)(?:quick(?:-|_)?submit|submit)(?:$|\\/)/i.test(popupKeyPath);\n        const urlJobId = new URLSearchParams(location.search).get('jobId');\n        const quickSubmitJobId = action.popupState?.jobId\n          ?? action.popupState?.jobID\n          ?? action.popupState?.jobId\n          ?? firstRecord.jobId\n          ?? firstRecord.job?.id\n          ?? firstRecord.job?._id\n          ?? urlJobId;\n        const quickSubmitCandidateId = action.popupState?.candidateId\n          ?? action.popupState?.applicantId\n          ?? firstRecord.id\n          ?? firstRecord._id\n          ?? firstRecord.applicantId\n          ?? firstRecord.candidateId;\n\n        if (isQuickSubmitPopup && quickSubmitJobId && quickSubmitCandidateId) {\n          const params = new URLSearchParams();\n          params.set('candidateId', String(quickSubmitCandidateId));\n          params.set('isFromSubmission', 'false');\n          navigate(`/submission-create/${encodeURIComponent(String(quickSubmitJobId))}?${params.toString()}`);\n          return;\n        }\n\n        navigate(normalizedRoute, {\n          state: {\n            background: location,\n            selectedIds: ids,\n            selectedRecords: records,\n            moduleName: baseModuleName,\n            popupContext: action.popupState ?? {},\n            popupAction: {\n              key: action.key,\n              apiMethod: action.apiMethod,\n              apiPath: action.apiPath,\n              defaultTemplateId: action.defaultTemplateId,\n              requireJobId: action.requireJobId,\n              popupFieldOverrides: action.popupFieldOverrides,\n            },\n            ...action.popupState,\n          },\n        });\n        return;\n      }\n      navigate(normalizedRoute);\n    }\n  }\n\n  function handleActionClick({ key }) {\n    const action = flattenActions(selectedActionItems).find((a) => String(a.key) === String(key));\n    // A \"done\" toolbar action is a disabled success label, not a trigger.\n    if (action && bulkDoneState(action, selectedRows, activeTab)) return;\n    handleActionClickForRecords(key, selectedRowKeys, selectedRows);\n  }\n  function handleRowActionClick(record, index) {\n    return ({ key }) => handleActionClickForRecords(key, [resolveRecordId(record, index)], [record]);\n  }\n\n  const allColumnsVisible = visibleKeys.length === tableFields.length;\n  const someColumnsVisible = visibleKeys.length > 0 && !allColumnsVisible;\n\n  const toggleColumn = (key, checked) => {\n    setVisibleColumnKeys((current) => {\n      const defaultKeys = tableFields.slice(0, defaultVisibleColumnCount).map((field) => field.key);\n      const currentKeys = current.length ? current : defaultKeys;\n\n      if (checked) return currentKeys.includes(key) ? currentKeys : [...currentKeys, key];\n      if (currentKeys.length <= minimumVisibleColumns) return currentKeys;\n\n      return currentKeys.filter((columnKey) => columnKey !== key);\n    });\n  };\n\n  const handleSummaryClick = () => {\n    if (typeof onSummaryClick === 'function') {\n      onSummaryClick();\n      return;\n    }\n    if (summaryRoute) {\n      navigate(summaryRoute);\n      return;\n    }\n    setSummaryOpen(true);\n  };\n\n  const handleFieldButtonClick = () => {\n    if (fieldButtonRoute) {\n      navigate(fieldButtonRoute);\n    }\n  };\n\n  useEffect(() => {\n    if (!summaryOpen) return undefined;\n\n    const handleKeyDown = (event) => {\n      if (event.key === 'Escape') setSummaryOpen(false);\n    };\n\n    window.addEventListener('keydown', handleKeyDown);\n    return () => window.removeEventListener('keydown', handleKeyDown);\n  }, [summaryOpen]);\n\n  const restoreDefaultListSnapshot = () => {\n    if (hasUsableDefaultSnapshot) {\n      setModuleRows(defaultListSnapshot.rows);\n      setModuleTotal(defaultListSnapshot.total);\n      setModuleTabs(defaultListSnapshot.tabs);\n      setModuleFields(defaultListSnapshot.fields);\n      setModuleTabField(defaultListSnapshot.tabField);\n      setModuleActions(defaultListSnapshot.actions ?? []);\n      setModuleActionRules(defaultListSnapshot.actionRules ?? []);\n      setModuleError(null);\n      setModuleLoading(false);\n    }\n  };\n\n  const handleSearchChange = (event) => {\n    const nextSearch = event.target.value;\n    const searchWillBeInactive = nextSearch.trim().length < 3;\n    const hasAppliedFieldFilters = appliedFilterRows.some((row) => row.field);\n\n    if (searchWillBeInactive) {\n      setCommittedSearch('');\n      if (!hasAppliedFieldFilters) {\n        restoreDefaultListSnapshot();\n      }\n    }\n\n    setSearch(nextSearch);\n    resetPaginationPage();\n  };\n\n  const handleSearchEnter = () => {\n    const q = search.trim();\n    if (q.length >= 3) {\n      setCommittedSearch(q);\n      resetPaginationPage();\n    }\n  };\n\n  const handleFilterReset = () => {\n    restoreDefaultListSnapshot();\n    setAppliedFilterRows([]);\n    updateSelection([], []);\n    resetPaginationPage();\n  };\n\n  // Clear card selection when the user navigates to a different page or tab\n  // so the Actions dropdown never carries stale records from the previous page.\n  useEffect(() => {\n    if (resolvedActiveView === 'card') {\n      setSelectedCardIds([]);\n      updateSelection([], []);\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [pagination.current, pagination.pageSize, activeTab, resolvedActiveView]);\n\n  // --------------------------------------------------------------------------\n  // 4g. NEW — Card View Handlers\n  //     handleCardSelect: toggles a card's checked state and mirrors it into\n  //     selectedRowKeys / selectedRows so the shared Actions dropdown fires\n  //     identically in both List and Card views.\n  // --------------------------------------------------------------------------\n  const handleCardSelect = (key) => {\n    setSelectedCardIds((prev) => {\n      const next = prev.includes(key)\n        ? prev.filter((id) => id !== key)\n        : [...prev, key];\n      const nextRows = pagedFilteredData.filter((record, idx) =>\n        next.includes(String(getRowKey(record, idx, rowKey)))\n      );\n      updateSelection(next, nextRows);\n      return next;\n    });\n  };\n\n  const columnVisibilityContent = (\n    <div className=\"column-visibility-menu\" onClick={(event) => event.stopPropagation()}>\n      <Checkbox\n        checked={allColumnsVisible}\n        indeterminate={someColumnsVisible}\n        onChange={(event) => {\n          setVisibleColumnKeys(\n            event.target.checked\n              ? tableFields.map((field) => field.key)\n              : tableFields.slice(0, defaultVisibleColumnCount).map((field) => field.key)\n          );\n        }}\n      >\n        Select All\n      </Checkbox>\n      <div className=\"column-visibility-menu__list\">\n        {tableFields.map((field) => (\n          <Checkbox\n            key={field.key}\n            checked={visibleKeys.includes(field.key)}\n            disabled={visibleKeys.includes(field.key) && visibleKeys.length <= minimumVisibleColumns}\n            onChange={(event) => toggleColumn(field.key, event.target.checked)}\n          >\n            {field.label}\n          </Checkbox>\n        ))}\n      </div>\n    </div>\n  );\n  return (\n    <div\n      className={`antd dynamic-list-view${compact ? ' list-view--compact' : ''}${shouldLockOuterPageScroll ? ' list-view--page-scroll-lock' : ''} ${className}`.trim()}\n    >\n      {breadcrumbItems.length > 0 && (\n        <div className=\"job-list-header\">\n          <AppBreadcrumb items={breadcrumbItems} />\n        </div>\n      )}\n      <Card className=\"job-tabs-card\">\n        <Flex align=\"center\" justify=\"space-between\">\n          <DynamicTabs\n            activeKey={activeTab}\n            tabs={listTabs}\n            onChange={handleTabChangeInternal}\n          />\n          <Flex align=\"center\" gap={8}>\n            {toolbarExtra}\n            {shouldShowSearchInput && (\n              <Input\n                prefix={<SearchOutlined className=\"job-search-icon\" />}\n                placeholder={searchPlaceholder}\n                value={search}\n                onChange={handleSearchChange}\n                onPressEnter={handleSearchEnter}\n                allowClear\n                className=\"job-search-input\"\n              />\n            )}\n            {!isControlled && canAdd && showAdd && (\n              <Tooltip title=\"Add\">\n                <Button\n                  aria-label=\"Add\"\n                  className=\"job-toolbar-icon-button\"\n                  icon={<PlusOutlined />}\n                  onClick={() => {\n                    if (createRoute) navigate(createRoute);\n                  }}\n                />\n              </Tooltip>\n            )}\n            {hasSourceRows && (<Tooltip title=\"Filter\">\n              <Badge\n                count={appliedFilterRows.filter((r) => r.field && hasFilterValue(r)).length}\n                size=\"small\"\n                offset={[-2, 2]}\n              >\n                <Button\n                  aria-label=\"Filter\"\n                  className=\"job-toolbar-icon-button\"\n                  icon={<FilterOutlined />}\n                  onClick={() => setFiltersOpen(true)}\n                />\n              </Badge>\n            </Tooltip>)}\n\n            {showViewToggle && hasSourceRows && (\n              <Flex align=\"center\" gap={6}>\n                <Tooltip title=\"List View\">\n                  <Button\n                    className={`job-toolbar-icon-button param-view-toggle-btn${resolvedActiveView === 'list' ? ' param-view-toggle-btn--active' : ''}`}\n                    icon={<UnorderedListOutlined />}\n                    onClick={() => { onViewChange?.('list'); setSelectedCardIds([]); updateSelection([], []); }}\n                  />\n                </Tooltip>\n                <Tooltip title=\"Card View\">\n                  <Button\n                    className={`job-toolbar-icon-button param-view-toggle-btn${resolvedActiveView === 'card' ? ' param-view-toggle-btn--active' : ''}`}\n                    icon={<AppstoreOutlined />}\n                    onClick={() => { onViewChange?.('card'); setSelectedCardIds([]); updateSelection([], []); }}\n                  />\n                </Tooltip>\n              </Flex>\n            )}\n\n            {showSummaryButton && (\n              <Button\n                className=\"job-summary-button\"\n                type=\"primary\"\n                onClick={handleSummaryClick}\n              >\n                {summaryButtonLabel}\n              </Button>\n            )}\n            {showFieldButton && fieldButtonRoute && (\n              <Button\n                className=\"job-summary-button\"\n                type=\"primary\"\n                onClick={handleFieldButtonClick}\n              >\n                {fieldButtonLabel}\n              </Button>\n            )}\n          </Flex>\n        </Flex>\n      </Card>\n      {hasSourceRows && (\n        <>\n          <Card className=\"job-toolbar-card\">\n            <Flex className=\"p-flex\" align=\"center\" justify=\"space-between\">\n              <Flex align=\"center\" gap={3}>\n                {resolvedActiveView === 'card' && (\n                  <Checkbox\n                    checked={pagedFilteredData.length > 0 && selectedCardIds.length >= pagedFilteredData.length}\n                    indeterminate={selectedCardIds.length > 0 && selectedCardIds.length < pagedFilteredData.length}\n                    className=\"param-card-view__select-all\"\n                    onChange={() => {\n                      if (selectedCardIds.length > 0) {\n                        setSelectedCardIds([]);\n                        updateSelection([], []);\n                      } else {\n                        const allKeys = pagedFilteredData.map((record, idx) => String(getRowKey(record, idx, rowKey)));\n                        setSelectedCardIds(allKeys);\n                        updateSelection(allKeys, [...pagedFilteredData]);\n                      }\n                    }}\n                  >\n                    Select All\n                  </Checkbox>\n                )}\n                <Dropdown\n                  open={columnMenuOpen}\n                  onOpenChange={setColumnMenuOpen}\n                  trigger={['click']}\n                  dropdownRender={() => columnVisibilityContent}\n                  placement=\"bottomLeft\"\n                  overlayClassName=\"column-visibility-dropdown\"\n                >\n                  <Button\n                    aria-label=\"Display columns\"\n                    type=\"text\"\n                    icon={<img src={unorderedListOutlinedIcon} alt=\"\" className=\"job-action-list-icon\" />}\n                    size=\"small\"\n                    className=\"job-actions-button job-column-display-button\"\n                  >\n                    <DownOutlined className=\"job-actions-caret\" />\n                  </Button>\n                </Dropdown>\n                {selectedActionItems.length > 0 && selectedRowKeys.length > 0 && (\n                  <Dropdown\n                    menu={{\n                      items: selectedActionItems.map((action) => toMenuItem(action, bulkDoneState(action, selectedRows, activeTab))),\n                      onClick: handleActionClick,\n                    }}\n                    trigger={['click']}\n                  >\n                    <Button\n                      type=\"text\"\n                      size=\"small\"\n                      className=\"job-actions-button job-actions-menu-button\"\n                    >\n                      <img src={frameIcon} alt=\"\" className=\"job-actions-frame-icon\" />\n                      Actions <DownOutlined className=\"job-actions-caret\" />\n                    </Button>\n                  </Dropdown>\n                )}\n                {selectedRowKeys.length > 0 && (\n                  <Text className=\"job-selected-count\">\n                    Selected ({selectedRowKeys.length})\n                  </Text>\n                )}\n              </Flex>\n              {showSearchResultsCount && (\n                <Text className=\"job-search-results-count\">\n                  Search Results ({searchResultsCount})\n                </Text>\n              )}\n            </Flex>\n          </Card>\n        </>)}\n\n      {hasActiveFieldFilters && (\n        <FilterChipsBar\n          filters={appliedFilterRows}\n          onRemove={(originalIdx) => {\n            const next = appliedFilterRows.filter((_, i) => i !== originalIdx);\n            setAppliedFilterRows(next);\n            resetPaginationPage();\n          }}\n          onClearAll={handleFilterReset}\n        />\n      )}\n\n      <div ref={tableContainerRef} className=\"job-table-measure\">\n        <Spin spinning={isControlled ? propLoading : (configLoading || moduleLoading)}>\n          {resolvedActiveView === 'card' ? (\n            pagedFilteredData.length === 0 ? (\n              <Empty\n                image={Empty.PRESENTED_IMAGE_SIMPLE}\n                description={emptyMessage}\n                className=\"param-card-view__empty\"\n              >\n                {!isControlled && canAdd && showAdd && createRoute && !moduleError && (\n                  <Button\n                    type=\"primary\"\n                    icon={<PlusOutlined />}\n                    onClick={() => navigate(createRoute)}\n                  >\n                    Add New\n                  </Button>\n                )}\n              </Empty>\n            ) : (\n              <div className=\"param-card-view__grid\">\n                {pagedFilteredData.map((record, idx) => {\n                  const key = String(getRowKey(record, idx, rowKey));\n                  return (\n                    <RecordCard\n                      key={key}\n                      record={record}\n                      fields={visibleCardFields}\n                      selected={selectionMode === 'checkbox' ? selectedCardIds.includes(key) : isRecordSelected(record, idx)}\n                      isControlled={isControlled}\n                      onPreview={() => handlePreviewOpen(record)}\n                      onSelect={() => handleCardSelect(key)}\n                      onPopupAction={openRowPopup}\n                      onRecordClick={onRecordClick ? () => handleRecordClick(record, idx) : undefined}\n                      selectionMode={selectionMode}\n                      permissions={{ canAdd, canEdit, canDelete }}\n                    />\n                  );\n                })}\n              </div>\n            )\n          ) : (\n            // <Table\n            //   rowSelection={hasSourceRows ? {\n            //     type: 'checkbox',\n            //     selectedRowKeys,\n            //     onChange: (keys, rows) => {\n            //       setSelectedRowKeys(keys);\n            //       setSelectedRows(rows);  \n            //     },\n            //     columnTitle: (() => {\n            //       const totalOnPage = pagedFilteredData.length;\n            //       const allSelected = totalOnPage > 0 && selectedRowKeys.length >= totalOnPage;\n            //       const someSelected = selectedRowKeys.length > 0 && !allSelected;\n            //       return (\n            //         <Checkbox\n            //           checked={allSelected}\n            //           indeterminate={someSelected}\n            //           onChange={() => {\n            //             if (someSelected || allSelected) {\n            //               setSelectedRowKeys([]);\n            //               setSelectedRows([]);\n            //             } else {\n            //               const allKeys = pagedFilteredData.map((record, idx) => getRowKey(record, idx, rowKey));\n            //               setSelectedRowKeys(allKeys);\n            //               setSelectedRows([...pagedFilteredData]);\n            //             }\n            //           }}\n            //         />\n            //       );\n            //     })(),\n            //   } : undefined}\n            //   columns={columns}\n            //   dataSource={pagedFilteredData}\n            //   size=\"middle\"\n            //   showSorterTooltip={false}\n            //   tableLayout=\"fixed\"\n            //   scroll={(hasHorizontalScroll || isControlled) ? { x: 'max-content' } : undefined}\n            //   pagination={false}\n            //   onChange={handleTableChange}\n            //   locale={{\n            //     emptyText: (\n            //       <Empty\n            //         image={Empty.PRESENTED_IMAGE_SIMPLE}\n            //         description={emptyMessage}\n            //       />\n            //     ),\n            //   }}\n            //   className={tableClassName}\n            //   rowKey={(record, index) => getRowKey(record, index, rowKey)}\n            // />\n            <Table\n              rowSelection={hasSourceRows && selectionMode === 'checkbox' ? {\n                type: 'checkbox',\n                fixed: true,\n                columnWidth: 48,\n                selectedRowKeys,\n                onChange: (keys, rows) => {\n                  updateSelection(keys, rows);\n                },\n                columnTitle: (() => {\n                  const totalOnPage = pagedFilteredData.length;\n                  const allSelected = totalOnPage > 0 && selectedRowKeys.length >= totalOnPage;\n                  const someSelected = selectedRowKeys.length > 0 && !allSelected;\n                  return (\n                    <Checkbox\n                      checked={allSelected}\n                      indeterminate={someSelected}\n                      onChange={() => {\n                        if (someSelected || allSelected) {\n                          updateSelection([], []);\n                        } else {\n                          const allKeys = pagedFilteredData.map((record, idx) => getRowKey(record, idx, rowKey));\n                          updateSelection(allKeys, [...pagedFilteredData]);\n                        }\n                      }}\n                    />\n                  );\n                })(),\n              } : undefined}\n              columns={columns}\n              dataSource={pagedFilteredData}\n              size=\"middle\"\n              tableLayout=\"fixed\"\n              scroll={{ x: (hasHorizontalScroll || isControlled) ? 'max-content' : undefined, y: 'calc(100vh - 300px)' }}\n              pagination={false}\n              locale={{\n                emptyText: (\n                  <Empty\n                    image={Empty.PRESENTED_IMAGE_SIMPLE}\n                    description={emptyMessage}\n                  />\n                ),\n              }}\n              className={`${tableClassName} ${compact ? 'list-view-table--compact' : ''}`.trim()}\n              onRow={onRecordClick ? (record, index) => ({\n                onClick: (event) => {\n                  if (isInteractiveClickTarget(event.target)) return;\n                  handleRecordClick(record, index);\n                },\n                'aria-selected': isRecordSelected(record, index),\n              }) : undefined}\n              rowClassName={selectedRecordId != null ? (record, index) => (\n                isRecordSelected(record, index) ? 'list-view-row--active' : ''\n              ) : undefined}\n              rowKey={(record, index) => getRowKey(record, index, rowKey)}\n            />\n          )}\n        </Spin>\n      </div>\n\n      {hasSourceRows ? <CustomPagination\n        current={pagination.current}\n        pageSize={pagination.pageSize}\n        total={tableTotal}\n        onChange={(page, nextPageSize) => {\n          if (isControlled && typeof onPageChange === 'function') {\n            onPageChange(page, nextPageSize ?? pagination.pageSize);\n            return;\n          }\n          setPaginationPage(page);\n        }}\n        onPageSizeChange={(size) => {\n          if (isControlled && typeof onPageSizeChange === 'function') {\n            onPageSizeChange(size);\n            return;\n          }\n          setPagination({ current: 1, pageSize: size });\n          updatePageRoute(1, { replace: true });\n        }}\n      /> : undefined}\n\n      <DynamicFieldFilter\n        moduleName={baseModuleName}\n        open={filtersOpen}\n        filters={appliedFilterRows}\n        onClose={() => setFiltersOpen(false)}\n        onApply={({ filters }) => {\n          setAppliedFilterRows(filters);\n          resetPaginationPage();\n        }}\n        onReset={handleFilterReset}\n      />\n      <ViewSummaryWidget\n        moduleName={baseModuleName}\n        open={summaryOpen}\n        rows={moduleRows}\n        tabs={listTabs}\n        total={tableTotal}\n        onClose={() => setSummaryOpen(false)}\n      />\n    </div>\n  );\n}\n","// pendingHandoff — pass an in-flight Promise from one route to the next.\n//\n// react-router's navigate(path, { state }) stores `state` via\n// history.pushState, which requires the value to be STRUCTURED-CLONEABLE.\n// A Promise is not: passing one directly throws\n// \"Failed to execute 'pushState' on 'History': #<Promise> could not be\n// cloned\" — silently killing the navigation itself, not just the feature that\n// tried to carry the promise.\n//\n// The fix is a token indirection: stash the promise in an in-memory map and\n// hand nav state a plain string key instead. Both routes live in the same SPA\n// runtime, so the map survives the navigation; a hard reload or a link opened\n// in a new tab naturally has no entry, which callers must treat as \"nothing to\n// wait for\" (never as an error).\nconst pending = new Map();\nlet counter = 0;\n\n/**\n * Stash a promise and return a token to carry through navigate(path, { state }).\n * @param {Promise<any>} promise\n * @returns {string} token\n */\nexport function stashPendingPromise(promise) {\n  const token = `ph_${Date.now()}_${(counter += 1)}`;\n  pending.set(token, promise);\n  // Self-cleaning: if the destination never mounts to consume it (the user\n  // cancels, or navigates elsewhere first), don't hold the promise forever.\n  promise.finally(() => {\n    setTimeout(() => pending.delete(token), 0);\n  }).catch(() => {}); // already-handled elsewhere; this is only cleanup\n  return token;\n}\n\n/**\n * Retrieve and remove a stashed promise by token. Returns undefined for an\n * unknown/already-consumed token — callers must treat that as \"nothing to\n * wait for\", not as an error (e.g. the page was reloaded, or opened directly).\n * @param {string | undefined} token\n * @returns {Promise<any> | undefined}\n */\nexport function takePendingPromise(token) {\n  if (!token) return undefined;\n  const promise = pending.get(token);\n  pending.delete(token);\n  return promise;\n}\n","import { ensureToken } from './authApi';\nimport { AUTH_URL } from './apiConfig';\n\n// ── Relevant-skill matching ─────────────────────────────────────────────────\n// Which of a candidate's skills does this job actually need?\n//\n// Sends IDS ONLY. The gateway reads both records from the caller's own\n// tenant-scoped database and calls the configured AI service, so this file —\n// like every other service module here — never holds a service URL or a\n// credential.\n//\n// NEVER THROWS and never rejects: the only caller is a submission flow, and a\n// failed match must degrade to \"the recruiter fills Relevant Skills by hand\",\n// exactly as today. An empty list is the honest answer for every failure.\n\n/**\n * @param {Object} args\n * @param {string} args.jobId\n * @param {string} args.applicantId\n * @param {number} [args.timeoutMs=15000] give up and return [] after this\n * @returns {Promise<string[]>} the candidate's skills this job asks for\n */\nexport async function matchRelevantSkills({ jobId, applicantId, timeoutMs = 15000 }) {\n  if (!jobId || !applicantId) return [];\n\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), timeoutMs);\n  try {\n    const token = await ensureToken();\n    const res = await fetch(`${AUTH_URL}/skill-match`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${token}`,\n      },\n      body: JSON.stringify({ jobId, applicantId }),\n      signal: controller.signal,\n    });\n    if (!res.ok) return [];\n    const json = await res.json();\n    const skills = json?.data?.relevantSkills ?? json?.relevantSkills;\n    return Array.isArray(skills) ? skills.filter((s) => typeof s === 'string' && s.trim()) : [];\n  } catch {\n    // Aborted, offline, 5xx, malformed body — all the same outcome.\n    return [];\n  } finally {\n    clearTimeout(timer);\n  }\n}\n","import { apiGetWithAuth, fetchJsonWithAuth, ensureToken } from './authApi';\nimport { AUTH_URL, CANDIDATES_URL, JOBS_URL } from './apiConfig';\n\nexport async function getCandidateSummary(startDate, endDate) {\n  const params = new URLSearchParams();\n  if (startDate) params.set('startDate', startDate);\n  if (endDate) params.set('endDate', endDate);\n  const query = params.toString();\n  return apiGetWithAuth(CANDIDATES_URL, `/profile-summary${query ? `?${query}` : ''}`);\n}\n\nexport async function getQuickSubmitCandidates({ isFromSubmission, jobId, submissionId, search = '' } = {}) {\n  const body = { search };\n  if (isFromSubmission) {\n    body.submissionId = submissionId;\n  } else {\n    body.jobId = jobId;\n  }\n  const json = await fetchJsonWithAuth(CANDIDATES_URL, '/quicksubmit/list', {\n    method: 'POST',\n    body: JSON.stringify(body),\n  });\n  return json.data ?? json;\n}\n\nexport async function getCandidateFormGroups(options = {}) {\n  const token = await ensureToken();\n  const params = new URLSearchParams({ module: 'candidates' });\n  if (options.id) params.set('id', options.id);\n  const res = await fetch(`${AUTH_URL}/admin/form-groups?${params}`, {\n    method: 'GET',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n  });\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  const json = await res.json();\n  return json.data ?? json;\n}\n\nexport async function getMentionUsers(search = '') {\n  const params = search ? `?search=${encodeURIComponent(search)}` : '';\n  return apiGetWithAuth(JOBS_URL, `/users/any${params}`);\n}\n\nexport async function migrateDiceCandidate(diceId) {\n  if (!diceId) throw new Error('Dice candidate ID is required');\n\n  const token = await ensureToken();\n  const url = `${AUTH_URL}/dicemigrate/${encodeURIComponent(String(diceId))}`;\n  // const url = `http://localhost:9009/v1/dicemigrate/${encodeURIComponent(String(diceId))}`;\n  if (process.env.NODE_ENV === 'development') {\n    console.log('[DiceMigration] Request URL:', url);\n  }\n  const response = await fetch(\n    url,\n    {\n      method: 'GET',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${token}`,\n      },\n    },\n  );\n\n  const payload = await response.json().catch(() => null);\n  if (!response.ok) {\n    const error = new Error(\n      payload?.message\n      ?? payload?.error\n      ?? `Failed to migrate candidate (${response.status})`,\n    );\n    error.status = response.status;\n    throw error;\n  }\n\n  return payload;\n}\n","import { migrateDiceCandidate } from './candidatesApi';\nimport { resolveDiceProfileId } from './diceCandidateMapper';\n\nexport function normalizeSourceKey(value) {\n  if (value && typeof value === 'object') {\n    return normalizeSourceKey(value.value ?? value.key ?? value.id ?? value.label ?? value.name);\n  }\n\n  return String(value ?? '').trim().toLowerCase();\n}\n\nexport function getSearchSources(value) {\n  return (Array.isArray(value) ? value : [value])\n    .flat()\n    .map(normalizeSourceKey)\n    .filter((item, index, source) => item && item !== 'all' && source.indexOf(item) === index);\n}\n\nexport function resolveSearchSource(value, fallback = 'internal') {\n  const sources = getSearchSources(value);\n  if (sources.includes('internal')) return 'internal';\n  const normalizedFallback = normalizeSourceKey(fallback);\n  if (sources[0]) return sources[0];\n  if (normalizedFallback) return normalizedFallback;\n  return fallback === '' ? '' : 'internal';\n}\n\n// Which module key answers for each source tab, as { [sourceKey]: moduleKey }.\n// A source with no entry uses the form's own module, which is every source on\n// every form until someone configures otherwise.\n//\n// Two places can declare it and BOTH are honoured, config last so it wins:\n//   1. a `sourceModules` prop, for a host app that wants to say so in code\n//      before the option key is persisted backend-side;\n//   2. the source option itself ({ value:'dice', module:'dice' }), which is what\n//      the Admin option editor writes.\n//\n// Built once and shared, because the module has to be identical on both request\n// paths — the `/module-data-list` call and the unified search endpoint. They\n// each used to work it out for themselves, and only one of the two read config,\n// so the Dice tab asked for Candidates' columns and actions.\nexport function buildSourceModuleMap(fields, sourceModules) {\n  const map = { ...(sourceModules ?? {}) };\n\n  (Array.isArray(fields) ? fields : [])\n    .flatMap((field) => (Array.isArray(field?.options) ? field.options : []))\n    .forEach((option) => {\n      const key = normalizeSourceKey(option?.value);\n      // Blank is not a value: it means \"use the form's module\", the same reading\n      // the Admin editor gives it by refusing to store an empty module.\n      const module = String(option?.module ?? '').trim();\n      if (key && module) map[key] = module;\n    });\n\n  return map;\n}\n\nfunction toTitle(value) {\n  return String(value ?? '')\n    .replace(/[-_]+/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim()\n    .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n// The key a tab is MATCHED by — lowercased, so a configured source and the\n// backend's spelling of it land on the same map entry.\nfunction getTabKey(tab) {\n  return normalizeSourceKey(rawTabKey(tab));\n}\n\n// The key a tab is EMITTED with, which is what goes back to the API when the tab\n// is clicked. It has to survive verbatim: a source key is lowercase either way,\n// but a field-based tab like \"myJobs\" is not, and sending \"myjobs\" would filter\n// on a value no record has.\nfunction rawTabKey(tab) {\n  const key = tab?.key ?? tab?.value ?? tab?.id ?? tab?.source ?? tab?.name ?? tab?.title ?? tab?.label;\n  return String(key ?? '').trim();\n}\n\nfunction getTabCount(tab) {\n  const count = tab?.count ?? tab?.countValue;\n  const number = Number(count);\n  return Number.isFinite(number) ? number : undefined;\n}\n\nfunction getSourceCount(source, responseCounts, currentCounts, activeSource, activeCount) {\n  // Both endpoints report a count for EVERY requested source, not just the one\n  // being viewed — module-data-list in `count.internal`/`count.dice`, boolean\n  // search in the same shape. So the live response wins for any tab; restricting\n  // this to the active source left the other tab showing a stale cached figure\n  // (or none) even though the number was sitting right there in the response.\n  const responseCount = Number(responseCounts?.[source]);\n  if (Number.isFinite(responseCount)) return responseCount;\n\n  if (source === activeSource) {\n    const activeTotal = Number(activeCount);\n    if (Number.isFinite(activeTotal)) return activeTotal;\n  }\n\n  const currentCount = currentCounts.get(source);\n  if (currentCount !== undefined) return currentCount;\n\n  return undefined;\n}\n\nexport function buildSourceTabs({\n  sources = [],\n  activeSource = 'internal',\n  activeCount = 0,\n  responseCounts = {},\n  currentTabs = [],\n  backendTabs = [],\n} = {}) {\n  const currentCounts = new Map(\n    (Array.isArray(currentTabs) ? currentTabs : [])\n      .map((tab) => [getTabKey(tab), getTabCount(tab)])\n      .filter(([source, count]) => source && count !== undefined),\n  );\n\n  const sourceMap = new Map();\n\n  // Pass 1 — the CONFIGURED sources define the order. Seeding from backendTabs\n  // instead put whichever tab was active first, because the backend only ever\n  // returns a tab for the active source — so the strip reordered on every\n  // switch. A Map keeps insertion order, and set() on an existing key updates\n  // the value without moving it, which is what makes pass 2 order-safe.\n  // Falling back to [activeSource] when nothing is configured used to invent an\n  // \"Internal\" tab on every form, including modules with no source picker at\n  // all — it would sit beside a Jobs form's real My Jobs / All Jobs tabs. With\n  // no configured sources there is nothing to seed, and pass 2 lets the\n  // backend's own tabs stand on their own.\n  const selectedSources = getSearchSources(sources);\n  const activeKey = normalizeSourceKey(activeSource);\n  const seeds = selectedSources.length\n    ? selectedSources\n    : (activeKey ? [activeKey] : []);\n\n  seeds.forEach((source) => {\n    if (!source || sourceMap.has(source)) return;\n    const count = getSourceCount(source, responseCounts, currentCounts, activeSource, activeCount);\n    sourceMap.set(source, {\n      key: source,\n      title: toTitle(source),\n      ...(count !== undefined ? { count } : {}),\n    });\n  });\n\n  // Pass 2 — the backend contributes a real label and count, never a position.\n  // Falling back to the previous count keeps a known figure on screen instead\n  // of blanking it out the moment you switch away from that tab.\n  (Array.isArray(backendTabs) ? backendTabs : []).forEach((tab) => {\n    const key = getTabKey(tab);\n    if (!key) return;\n    const previous = sourceMap.get(key);\n    const count = getTabCount(tab) ?? previous?.count ?? currentCounts.get(key);\n    sourceMap.set(key, {\n      // Matched case-insensitively, emitted as the backend spelled it.\n      key: previous ? previous.key : rawTabKey(tab),\n      title: tab.title ?? tab.label ?? tab.name ?? previous?.title ?? toTitle(key),\n      ...(count !== undefined ? { count } : {}),\n    });\n  });\n\n  return Array.from(sourceMap.values());\n}\n\nfunction collectSourceValues(record) {\n  return [\n    record?.sourceType,\n    record?.profileSource,\n    record?.selectedSource,\n    record?.source,\n    record?.provider,\n    record?.customFields?.sourceType,\n    record?.customFields?.profileSource,\n    record?.customFields?.source,\n    record?.customFields?.provider,\n  ].flat().map(normalizeSourceKey).filter(Boolean);\n}\n\nfunction recordMatchesSource(record, sourceKey, marker) {\n  const normalizedSource = normalizeSourceKey(sourceKey);\n  if (!normalizedSource) return false;\n  if (collectSourceValues(record).includes(normalizedSource)) return true;\n  return typeof marker === 'function' ? marker(record) : false;\n}\n\nconst SOURCE_ACTIONS = [\n  {\n    source: 'dice',\n    field: '__sourceAction_dice_migrate',\n    label: 'Action',\n    buttonLabel: 'Migrate',\n    completedLabel: 'Migrated',\n    successMessage: 'Candidate migrated successfully.',\n    errorMessage: 'Failed to migrate candidate.',\n    isRecordFromSource: (record) => Boolean(record?.customFields?.diceProfileData),\n    getRecordId: resolveDiceProfileId,\n    execute: migrateDiceCandidate,\n  },\n];\n\nexport function getAvailableSourceActions({ rows = [], selectedSource = '' } = {}) {\n  return SOURCE_ACTIONS.filter((action) => {\n    const selectedMatches = normalizeSourceKey(selectedSource) === action.source;\n    return selectedMatches || rows.some((record) => recordMatchesSource(record, action.source, action.isRecordFromSource));\n  });\n}\n\nexport function sourceActionAppliesToRecord(action, record, selectedSource = '') {\n  return normalizeSourceKey(selectedSource) === action.source\n    || recordMatchesSource(record, action.source, action.isRecordFromSource);\n}\n\nexport function getSourceActionInstanceKey(action, record) {\n  const id = action?.getRecordId?.(record);\n  return id ? `${action.source}:${action.field}:${id}` : '';\n}\n\nexport async function runSourceAction(action, record) {\n  const id = action?.getRecordId?.(record);\n  if (!id) throw new Error(`${action?.buttonLabel ?? 'Action'} ID is required`);\n  return action.execute(id, record);\n}\n","import { Fragment, createContext, forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState, useCallback } from 'react';\nimport dayjs from 'dayjs';\nimport {\n    Alert,\n    Button,\n    Card,\n    Checkbox,\n    Col,\n    DatePicker,\n    Form,\n    Input,\n    message,\n    Radio,\n    Row,\n    Select,\n    Space,\n    Spin,\n    Switch,\n    TimePicker,\n    Tooltip,\n    Typography,\n    Upload,\n} from 'antd';\nimport {\n    CalendarOutlined,\n    CloudUploadOutlined,\n    DeleteOutlined,\n    DownOutlined,\n    EnvironmentOutlined,\n    EyeOutlined,\n    FileExcelOutlined,\n    FileImageOutlined,\n    FileOutlined,\n    FilePdfOutlined,\n    FileTextOutlined,\n    FileWordOutlined,\n    InfoCircleOutlined,\n    LockOutlined,\n    MailOutlined,\n    PhoneOutlined,\n    PlusOutlined,\n    SolutionOutlined,\n    TagsOutlined,\n    UpOutlined,\n    UserOutlined,\n} from '@ant-design/icons';\nimport TipTapEditor from './TipTapEditor';\nimport DocumentViewer from './DocumentViewer';\nimport { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom';\nimport { fetchJsonWithAuth, getActingIdentity } from '../services/authApi';\nimport { autoValueFor } from '../utils/autoValueRules';\nimport { AUTH_URL } from '../services/apiConfig';\nimport { getDropdownValues, searchModuleData } from '../services/moduleDataApi';\nimport { getFormGroups, createModuleRecord } from '../services/addFormApi';\nimport { verifyEmail, getModuleDefaultFields } from '../services/adminApi';\nimport { uploadModuleDocuments } from '../services/documentApi';\nimport { getAdminClients, getCustomForms, getRoleFormPermissions } from '../services/adminApi';\nimport { updateRecord } from '../services/detailedViewApi';\nimport { loadDetailDefaults, formatPhone, phoneDigits, parsePhoneFormat } from '../services/detailDefaults';\nimport { groupAllowedByRole, fieldAllowedByRole, fieldEditableByRole } from '../utils/roleFormPermissionGate';\nimport { buildPayload, buildInitialValue, buildRepeatFieldInitial, singleFieldOf, collectFileParts, effectiveDataType, getDeep, toSelectControlValue, usesLabeledSelectValue, rowDefaultsFor } from './form/payloadTransformer';\nimport { computeLinkedSets, findLinkedSet, padLinkedInitialValues } from './form/linkedAddRowGroups';\nimport useAiActions, { groupActionsByPosition } from './form/useAiActions';\nimport AiActionButtonGroup from './form/AiActionButtons';\nimport { applyInputValidator, getKeyPattern } from './form/inputValidator';\nimport { configuredEmailRule, isValidConfiguredEmail } from './form/emailValidator';\nimport { securityValidationRule } from './form/inputSecurity';\nimport {\n    buildUniqueValidationRule,\n    attachUniqueSyncGuards,\n    collectUniqueRules,\n    createUniqueChecker,\n    extractDuplicateFieldErrors,\n} from './form/uniqueFieldValidation';\nimport { checkFieldUnique } from '../services/uniqueValidationApi';\nimport { uploadAcceptCategory } from './form/uploadAccept';\nimport { useQuickField } from './form/QuickCreateEditField';\nimport { maxFromFieldRule, maxFromFieldDependency, resolveScopedFieldPath } from './form/crossFieldRules';\nimport { checkMaxWithFallback, parseCompareFields, readCompareValue, resolveCompareFieldName } from './form/maxCeiling';\nimport { contextRecordId } from './form/contextPrefill';\nimport ValidationOverrideCheckbox from './form/ValidationOverrideCheckbox';\nimport {\n    overrideConfig,\n    overrideFlagPath,\n    overrideRuleMapper,\n} from './form/validationOverride';\nimport { prefillWhenWatchFields, prefillWhenWatchPaths, resolvePrefillWhen } from './form/prefillWhenRules';\nimport { narrowOptionsByConstraint, stripExclusivePrefillOptions } from './form/optionConstraints';\nimport { filterLookupOptionRows, lookupExtraFieldKeys } from './form/optionRowFilters';\nimport { fieldTooltipText } from './form/fieldTooltip';\nimport { writeFormValue } from './form/applyGroupValues';\nimport { PARENT_FILTER_UNSEEN, shouldClearDependentValue } from './form/dependentLookupReset';\nimport { roleAllowsAction } from '../utils/roleAllowsAction';\nimport { resolveAfterSubmit, safeNavTarget } from '../utils/afterSubmitNav';\nimport { goBackOrTo } from '../utils/backNav';\nimport useDuplicateCheck from './form/useDuplicateCheck';\nimport {\n    resolveRegionRules,\n    inProgressAllowed,\n    inProgressBlocks,\n    inProgressError,\n    buildInProgressValidator,\n    levelRuleVerdict,\n    promptRowMove,\n} from './form/educationRules';\nimport { getDefaults } from '../services/detailDefaults';\nimport { openFormNotice, openFormDecision } from './form/formDecisionDialog';\nimport { applyGroupClear } from './form/clearGroupOnChange';\nimport { storedFileName, storedFileUrl } from './form/storedFileName';\nimport { fetchLookupLabels, mergeResolvedOptions, missingOptionValues } from './form/resolveStoredOptions';\nimport {\n    buildPairValidator,\n    buildRowHierarchyValidator,\n    buildDisabledDate,\n    defaultPickerValue,\n    getComparableDateTime,\n    getComparableTimeOfDay,\n} from './form/dateRules';\nimport { submitSuccessMessage, submitErrorMessage } from '../utils/submitMessages';\nimport { scrollToFirstFormError } from '../utils/scrollToFirstFormError';\nimport { conditionFieldPath, configuredFieldLabel, conditionMatches as labelConditionMatches, colWhenRules, resolveColSpan } from './form/conditionalFieldLabel';\nimport AppBreadcrumb from '../components/Breadcrumb';\nimport ListView from './ListView';\nimport { clearAuthTokenOverride, setAuthTokenOverride } from '../services/authApi';\nimport { takePendingPromise } from '../services/pendingHandoff';\nimport { matchRelevantSkills } from '../services/skillMatchApi';\nimport {\n    buildSourceTabs,\n    getAvailableSourceActions,\n    getSearchSources,\n    getSourceActionInstanceKey,\n    resolveSearchSource,\n    runSourceAction,\n    sourceActionAppliesToRecord,\n} from '../services/sourceProviderActions';\n\nconst { Text } = Typography;\nconst { TextArea } = Input;\nconst emptyGroups = [];\n\nconst sectionIcons = [\n    <UserOutlined />,\n    <EnvironmentOutlined />,\n    <SolutionOutlined />,\n    <InfoCircleOutlined />,\n    <FileTextOutlined />,\n];\n\nconst fieldIcons = {\n    email: <MailOutlined className=\"v1-input-icon\" />,\n    contactNumber: <PhoneOutlined className=\"v1-input-icon\" />,\n    phone: <PhoneOutlined className=\"v1-input-icon\" />,\n    currentLocation: <EnvironmentOutlined className=\"v1-input-icon\" />,\n    preferredLocation: <EnvironmentOutlined className=\"v1-input-icon\" />,\n    skills: <TagsOutlined className=\"v1-input-icon\" />,\n    firstName: <UserOutlined className=\"v1-input-icon\" />,\n    lastName: <UserOutlined className=\"v1-input-icon\" />,\n};\n\nconst truthy = (value) => value === true || value === 1 || value === '1';\nconst editable = (field, moduleName) => (field?.edit === undefined || truthy(field.edit))\n    && (!field?.editablePermission || roleAllowsAction(field.editablePermission, moduleName));\n\nfunction normalizeOptions(options = []) {\n    return options.map((option) => {\n        if (typeof option === 'string') return { label: option, value: option };\n        return {\n            label: option.label ?? option.name ?? option.value,\n            value: option.value ?? option.id ?? option.name ?? option.label,\n        };\n    });\n}\n\nfunction namePathFromString(path) {\n    return String(path ?? '').split('.').map((part) => part.trim()).filter(Boolean);\n}\n\nfunction siblingFieldPath(absoluteName, key) {\n    return Array.isArray(absoluteName) && absoluteName.length > 1\n        ? [...absoluteName.slice(0, -1), key]\n        : [key];\n}\n\n// VerifyFieldButton — admin-configured \"Verify\" button beside a field\n// (field.verifyAction, e.g. \"email\"). Calls the generic /email-verify\n// endpoint and writes the boolean result + a timestamp into two sibling\n// fields (verifyResultField/verifyTimestampField), within the same addRow\n// row when nested. Not specific to \"recruiter\" or any module — any field\n// can opt in.\nfunction VerifyFieldButton({ form, field, absoluteName }) {\n    const [checking, setChecking] = useState(false);\n    const [verdict, setVerdict] = useState(null);\n    const verifiedValueRef = useRef(null);\n    const resultValue = Form.useWatch(\n        field.verifyResultField ? siblingFieldPath(absoluteName, field.verifyResultField) : ['__noop_verify__'],\n        { form, preserve: true },\n    );\n    const currentValue = Form.useWatch(absoluteName, form);\n\n    // A successful result belongs to the exact value that was checked. Existing\n    // Edit records hydrate once; later source-value changes invalidate the\n    // configured result so the form gate cannot accept a different email.\n    useEffect(() => {\n        const normalized = String(currentValue ?? '').trim();\n        if (resultValue === true && verifiedValueRef.current === null && normalized) {\n            verifiedValueRef.current = normalized;\n            return;\n        }\n        if (resultValue === true && verifiedValueRef.current !== null && normalized !== verifiedValueRef.current) {\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), false);\n            if (field.verifyTimestampField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), undefined);\n            verifiedValueRef.current = null;\n        }\n    }, [absoluteName, currentValue, field.verifyResultField, field.verifyTimestampField, form, resultValue]);\n\n    if (field.verifyAction !== 'email') return null;\n\n    const runVerify = async () => {\n        const email = String(currentValue ?? '').trim();\n        if (!email) {\n            message.warning('Enter an email first');\n            return;\n        }\n        setChecking(true);\n        try {\n            const result = await verifyEmail(email);\n            verifiedValueRef.current = result.valid ? email : null;\n            setVerdict(result.valid ? result : null);\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), result.valid);\n            if (field.verifyTimestampField) {\n                form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), result.valid ? new Date().toISOString() : undefined);\n            }\n            // Three outcomes, not two. \"Accepted but unconfirmed\" is the common\n            // case on catch-all domains (Google Workspace's default, and most\n            // corporate mail) — reporting it as a plain success would tell the\n            // user the mailbox exists when nothing proved that.\n            if (!result.valid) {\n                message.error(result.reason ? `Invalid email: ${result.reason}` : 'Email could not be verified');\n            } else if (result.mailboxConfirmed) {\n                message.success('Email verified \\u2014 the mail server confirmed this mailbox');\n            } else {\n                message.warning(result.reason || 'The domain can receive mail, but this exact mailbox could not be confirmed');\n            }\n        } catch (err) {\n            verifiedValueRef.current = null;\n            setVerdict(null);\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), false);\n            if (field.verifyTimestampField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), undefined);\n            message.error(err?.message || 'Could not verify email');\n        } finally {\n            setChecking(false);\n        }\n    };\n\n    if (resultValue === true) {\n        // Accepted, but the mailbox itself was never proven (catch-all domain).\n        // Labelling that \"Valid\" would overstate what the check established, so\n        // it gets its own state. The address still passes the submit gate — the\n        // account email that follows is what ultimately proves delivery.\n        // Only positive evidence of \"unconfirmed\" downgrades the label. A\n        // response that simply doesn't carry the field (older backend, or a\n        // check that never reached the mailbox stage) keeps the plain success\n        // state rather than casting doubt the check never actually raised.\n        if (verdict && !verdict.mailboxConfirmed && (verdict.catchAll || verdict.result === 'risky')) {\n            return (\n                <Tooltip title={verdict.reason || 'This domain accepts every address, so the mailbox could not be confirmed. Delivery is proven only once the account email is actually sent.'}>\n                    <Text type=\"warning\" strong className=\"v1-verify-field-wrap\">\n                        {field.verifyUnconfirmedLabel || 'Accepted'}\n                    </Text>\n                </Tooltip>\n            );\n        }\n        return <Text type=\"success\" strong className=\"v1-verify-field-wrap\">{field.verifySuccessLabel || 'Valid'}</Text>;\n    }\n\n    return (\n        <Button size=\"small\" loading={checking} onClick={runVerify} className=\"v1-verify-field-wrap\">\n            {resultValue === false ? (field.verifyRetryLabel || 'Re Verify') : (field.verifyIdleLabel || 'Verify Email')}\n        </Button>\n    );\n}\n\nfunction ConfiguredFieldLabel({ form, field, siblingPrefix, locked, combined = false }) {\n    const watchedValue = Form.useWatch(conditionFieldPath(field?.labelWhen, siblingPrefix), form);\n    const label = configuredFieldLabel(field, watchedValue, combined);\n    return combined ? label : <FieldLabel field={field} label={label} locked={locked} />;\n}\n\n// An ADDITIONAL admin-configured submit button (group.formActions). Same\n// validation gate as the primary Create button, plus an optional enabledWhen\n// gate that keeps it disabled until a field satisfies the condition (e.g. only\n// once \"Assign To\" is filled). `tone` picks primary vs secondary styling.\nfunction FormActionButton({ form, groups, action, disabled, loading, onFire }) {\n    const unvalidated = Form.useWatch(\n        (values) => groups.some((group) => {\n            if (!group.addRow || !group.requireValidatedField) return false;\n            const rows = values?.[group.name] ?? [];\n            return rows.length === 0 || rows.some((row) => !row?.[group.requireValidatedField]);\n        }),\n        { form, preserve: true },\n    );\n    const gateValue = Form.useWatch(action?.enabledWhen?.field, form);\n    const gateOk = !action?.enabledWhen?.field || groupShowIfMatches(action.enabledWhen, gateValue);\n    return (\n        <Button\n            type={action?.tone === 'primary' ? 'primary' : 'default'}\n            onClick={onFire}\n            disabled={disabled || unvalidated || !gateOk}\n            loading={loading}\n        >\n            {action?.label || 'Submit'}\n        </Button>\n    );\n}\n\nfunction ValidationGatedSubmitButton({ form, groups, disabled, loading, onClick, children }) {\n    const unvalidated = Form.useWatch(\n        (values) => groups.some((group) => {\n            if (!group.addRow || !group.requireValidatedField) return false;\n            const rows = values?.[group.name] ?? [];\n            return rows.length === 0 || rows.some((row) => !row?.[group.requireValidatedField]);\n        }),\n        { form, preserve: true },\n    );\n    const isDisabled = disabled || unvalidated;\n    // Config-driven \"why is this disabled\" tooltip: an admin sets\n    // group.submitDisabledMessage (Admin → Form Groups). When a row-validation\n    // gate is what's blocking, the more specific requireValidatedFieldMessage\n    // (or a sensible default) is shown instead. Only rendered while disabled.\n    const groupMsg = groups.find((g) => g.submitDisabledMessage)?.submitDisabledMessage;\n    const validatedMsg = groups.find((g) => g.requireValidatedField)?.requireValidatedFieldMessage;\n    const reason = unvalidated\n        ? (validatedMsg || groupMsg || 'Verify every required row before submitting.')\n        : (groupMsg || 'Complete all mandatory fields before submitting.');\n    const button = (\n        <Button type=\"primary\" onClick={onClick} disabled={isDisabled} loading={loading}>\n            {children}\n        </Button>\n    );\n    // A disabled antd Button has pointer-events:none, so the Tooltip must wrap a\n    // span to receive hover.\n    return isDisabled && !loading\n        ? <Tooltip title={reason}><span style={{ display: 'inline-flex', cursor: 'not-allowed' }}>{button}</span></Tooltip>\n        : button;\n}\n\n// PrefillWhenWatcher — sets ITS OWN field's value when a referenced field's\n// value matches a configured rule (e.g. contractType=\"W2\" forces employerId to\n// a fixed record id), and clears it back out when a rule says so or when no\n// rule matches any more. Opposite direction from autofillFrom (which pushes\n// into siblings when the changed field is a lookup select) — this field PULLS\n// its value from a field changing elsewhere. A tiny standalone component (not\n// inline logic) because Form.useWatch is a hook and must run in component\n// scope, not inside the plain renderField() function.\n//\n// ALL of the decision-making lives in form/prefillWhenRules.js so this form and\n// EditFormV1 can never disagree about what a rule means, and so the rules can\n// be unit-tested without importing either form (any render test that touches\n// them dies on jsdom's missing DOMMatrix, via react-pdf).\n//\n// `watchPaths` carries EVERY field a rule references — rules may point at\n// different fields, and each path was already resolved through renderField's\n// `prefixFor` closure so a rule reaching out of an addRow row lands on the\n// top-level field (see prefillWhenWatchPaths).\nfunction PrefillWhenWatcher({ form, rules, watchPaths, targetPath, resetOnNoMatch = true }) {\n    // A selector useWatch (not one path per hook — hook count must be stable)\n    // reduced to a STRING so the effect dependency stays a primitive; a fresh\n    // array every render would re-run the effect on every keystroke anywhere.\n    const watchedKey = Form.useWatch(\n        (values) => JSON.stringify(\n            watchPaths.map(({ path }) => path.reduce((acc, key) => (acc == null ? acc : acc[key]), values) ?? null),\n        ),\n        { form, preserve: true },\n    );\n    // Tracks the value WE last set via a matching rule (e.g. the W2 default\n    // employer), so a later \"no rule matches\" tick (contractType switched away\n    // from W2) can tell \"still exactly what we set\" apart from \"the user picked\n    // something else since\" — only the former gets cleared. Without this guard,\n    // switching e.g. W2 → C2C left the W2 default employer stuck in the field\n    // forever (admin config `prefillWhenReset`, default on).\n    const lastAppliedRef = useRef(undefined);\n    // First tick = the form settling into its initial values, never a user\n    // decision, so a clear rule must not fire on it (it would delete stored\n    // data on the edit form). See prefillWhenRules.js for the full rationale.\n    const initialRef = useRef(true);\n    useEffect(() => {\n        const values = watchedKey ? JSON.parse(watchedKey) : [];\n        const watched = {};\n        watchPaths.forEach(({ field }, i) => { watched[field] = values[i]; });\n        const initial = initialRef.current;\n        initialRef.current = false;\n        const outcome = resolvePrefillWhen({\n            rules,\n            watched,\n            current: form.getFieldValue(targetPath),\n            lastApplied: lastAppliedRef.current,\n            clearOnMismatch: resetOnNoMatch,\n            initial,\n        });\n        if (outcome.action === 'set') {\n            form.setFieldValue(targetPath, outcome.value);\n            lastAppliedRef.current = outcome.value;\n        } else if (outcome.action === 'clear') {\n            form.setFieldValue(targetPath, undefined);\n            lastAppliedRef.current = undefined;\n        }\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [watchedKey]);\n    return null;\n}\n\n// AutoFillFromApiWatcher — watches THIS field's own live value and, when it\n// changes to a non-empty value, calls a REST endpoint and populates one or\n// more sibling fields from the JSON response. Unlike prefillWhen (a static\n// value → value map), this does a real API round-trip — e.g. auto-loading a\n// campaign's Subject/Message from an admin-configured email template the\n// moment Type is set. A failed/404 lookup (no template configured yet) is\n// treated as a silent no-op, matching how callers of this endpoint already\n// tolerate a missing template elsewhere.\nfunction AutoFillFromApiWatcher({ form, config, watchPath }) {\n    const watched = Form.useWatch(watchPath, form);\n    const lastFetchedRef = useRef(undefined);\n    useEffect(() => {\n        if (empty(watched) || watched === lastFetchedRef.current) return;\n        lastFetchedRef.current = watched;\n\n        const url = config.endpointTemplate\n            ? `${config.endpointTemplate.replace('{value}', encodeURIComponent(String(watched)))}`\n            : `${config.endpoint}?${new URLSearchParams({ [config.queryParam]: String(watched) }).toString()}`;\n\n        fetchJsonWithAuth(AUTH_URL, url)\n            .then((json) => {\n                const data = json?.data ?? json;\n                if (config.substituteTokens) {\n                    (config.substituteInFields || []).forEach((targetField) => {\n                        const targetPath = namePathFromString(targetField);\n                        let current = form.getFieldValue(targetPath) || '';\n                        Object.entries(config.substituteTokens).forEach(([token, responseKey]) => {\n                            const inner = token.replace(/^\\{\\{|\\}\\}$/g, '').trim();\n                            const pattern = new RegExp(`\\\\{\\\\{\\\\s*${inner.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\s*\\\\}\\\\}`, 'gi');\n                            current = current.replace(pattern, data?.[responseKey] ?? '');\n                        });\n                        form.setFieldValue(targetPath, current);\n                    });\n                    return;\n                }\n                Object.entries(config.mapResponseToFields).forEach(([targetField, responseKey]) => {\n                    const targetPath = namePathFromString(targetField);\n                    if (config.onlyIfEmpty && !empty(form.getFieldValue(targetPath))) return;\n                    form.setFieldValue(targetPath, data?.[responseKey]);\n                });\n            })\n            .catch(() => {\n                // No template configured for this value yet, or the call\n                // failed — leave existing field values untouched.\n            });\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [watched]);\n    return null;\n}\n// Group-level showIf: the whole group renders only when the referenced field's\n// live value satisfies the condition (same operators as field-level showIf).\n// Kept as a module-level helper so both AddFormV1 and EditFormV1 evaluate it\n// identically.\nfunction groupShowIfMatches(showIf, value) {\n    if (!showIf?.field) return true;\n    const actual = String(value ?? '');\n    const expected = String(showIf.value ?? '');\n    const list = () => expected.split(',').map((v) => v.trim());\n    switch (showIf.operator) {\n        case 'eq': return actual === expected;\n        case 'neq': return actual !== expected;\n        case 'in': return list().includes(actual);\n        case 'notIn': return !list().includes(actual);\n        case 'truthy': return truthy(value);\n        case 'falsy': return !truthy(value);\n        case 'empty':\n        case 'isEmpty':\n            return value === undefined || value === null || actual.trim() === '' || (Array.isArray(value) && value.length === 0);\n        case 'notEmpty':\n            return !(value === undefined || value === null || actual.trim() === '' || (Array.isArray(value) && value.length === 0));\n        default: return true;\n    }\n}\n\n// A group with a `showIf` renders through this gate so its visibility reacts to\n// the referenced field changing. `render` is only invoked when visible, so a\n// hidden group's fields never register (nothing to validate or submit) — exactly\n// like a hidden field-level showIf. Groups without showIf bypass this entirely.\nfunction GroupShowIfGate({ form, showIf, render }) {\n    const watched = Form.useWatch(showIf.field, form);\n    if (!groupShowIfMatches(showIf, watched)) return null;\n    return render();\n}\n\n// Group-level disable: the whole card (every field in it) goes read-only when\n// the group's `disabled` flag is set OR its `disabledIf` condition matches — the\n// group counterpart of FieldControl's field-level disabled/disabledIf. Provided\n// through context so each FieldControl in the group ORs it into its own disabled\n// state without threading a prop through renderGroup→renderFields→renderField.\n// Nested/merged groups inherit the parent's disabled state (never re-enable).\nconst GroupDisabledContext = createContext(false);\n\nfunction GroupDisabledProvider({ form, group, children, inheritParent = true }) {\n    const parentDisabled = useContext(GroupDisabledContext);\n    const path = group?.disabledIf?.field ? namePathFromString(group.disabledIf.field) : ['__noop_group_disabled__'];\n    const watched = Form.useWatch(path, form);\n    const conditionDisabled = group?.disabledIf?.field\n        ? groupShowIfMatches(group.disabledIf, watched)\n        : false;\n    // `inheritParent: false` is used for a MERGED child (group.mergeInto).\n    // mergeInto is presentation only — the child borrows the host's card and\n    // nothing else — so inheriting the host's disabled state would give a\n    // display relationship real behaviour.\n    //\n    // It is also the difference between working and deadlocked: the Employer\n    // section is disabled until a Contract Type is chosen, and Contract Type is\n    // rendered INSIDE that section. Inheriting would disable the very control\n    // that enables the card, with no way out.\n    const disabled = (inheritParent && parentDisabled)\n        || Boolean(group?.disabled)\n        || conditionDisabled;\n    return <GroupDisabledContext.Provider value={disabled}>{children}</GroupDisabledContext.Provider>;\n}\n\nfunction getNestedProp(obj, dotPath) {\n    return String(dotPath ?? '').split('.').reduce((cur, k) => cur?.[k], obj);\n}\n\nfunction hasMeaningfulValue(value) {\n    if (value === undefined || value === null || value === '') return false;\n    if (Array.isArray(value)) return value.length > 0 && value.some(hasMeaningfulValue);\n    if (typeof value === 'object') return Object.values(value).some(hasMeaningfulValue);\n    return true;\n}\n\nfunction extractGroups(formGroups) {\n    if (Array.isArray(formGroups)) return formGroups;\n    if (Array.isArray(formGroups?.groups)) return formGroups.groups;\n    if (Array.isArray(formGroups?.data)) return formGroups.data;\n    if (Array.isArray(formGroups?.data?.groups)) return formGroups.data.groups;\n    return emptyGroups;\n}\n\nfunction normalizeGroups(formGroups = [], moduleName, rolePerms, defaultFieldSet) {\n    const dset = defaultFieldSet ?? new Set();\n    return [...extractGroups(formGroups)]\n        // hideGroup hides everywhere; hideGroupInForm is the form-only mirror of\n        // DetailViewV1's hideGroupInDetail — for server-owned groups that must be\n        // read on the detail view but never typed here.\n        .filter((group) => !truthy(group.hideGroup) && !truthy(group.hideGroupInForm)\n            && groupAllowedByRole(rolePerms, group.name))\n        .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n        .map((group) => ({\n            ...group,\n            fields: [...(group.fields ?? [])]\n                // A \"default field\" (Form Groups → Default Fields, OTP-gated) is\n                // ALWAYS shown + required regardless of its own show flag, so it\n                // survives the hidden-field filter below and is forced show/req in\n                // the map that follows.\n                .map((field) => (\n                    dset.has(field.field) ? { ...field, show: 1, req: 1 } : field\n                ))\n                // Drop blank-keyed fields (a stray admin-config row can't render or\n                // submit), any client-scope \"gate\" field (rendered as the top\n                // \"Select Client\" picker, never as a body field), any field whose\n                // visiblePermission the current role doesn't hold, and any field\n                // this role's Form Configuration (Role Configure → Form, derived\n                // from this same Form Groups config) has turned off.\n                //\n                // A field with show:0 (\"hidden\") is intentionally KEPT here even\n                // though it must never render — this same fields array also feeds\n                // buildPayload/buildRowObject (the payload engine has no other way\n                // to know a hidden carrier field like isValid/isAccountCreate\n                // exists). Dropping it here silently threw away every hidden\n                // field's value at submit time, even one just set moments earlier\n                // in this session (e.g. a Verify Email click stamping isValid on a\n                // brand-new recruiter row) — see renderFields, which is what\n                // actually keeps hidden fields off the screen.\n                .filter((field) =>\n                    String(field.field ?? '').trim() !== ''\n                    && field.showOnAdd !== false\n                    && !truthy(field.clientScope)\n                    && (!field.visiblePermission || roleAllowsAction(field.visiblePermission, moduleName))\n                    && fieldAllowedByRole(rolePerms, group.name, field.field))\n                // Role \"disable\": a group/field the role has marked non-editable\n                // still renders but read-only. FieldControl honours field.disabled.\n                .map((field) => (\n                    fieldEditableByRole(rolePerms, group.name, field.field)\n                        ? field\n                        : { ...field, disabled: true }\n                ))\n                .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0)),\n        }))\n        .filter((group) => group.fields.length);\n}\n\n// pickPrefillValue reads a field's initial value from a prefill SOURCE record,\n// honouring the admin-config `prefillFrom` mapping FIRST (so a target field can\n// inherit from a differently-named source key — e.g. submission.totalExperience\n// ← candidate.yearOfExperience), then falling back to field.field and payloadKey.\n// Tolerates both flat dotted keys (the getFormGroups flat record) and nested\n// objects (addRow rows). Entirely config-driven — no field-name logic here.\n// Flattens a form-groups response (scalar fields with embedded values) into a\n// plain { fieldKey: value } record. Shared by the default prefill source and\n// the cross-module context prefill (field.prefillFromModule).\nfunction flatRecordFromGroups(groups) {\n    if (!Array.isArray(groups)) return null;\n    const rec = {};\n    groups.forEach(group => {\n        if (group.addRow) return;\n        (group.fields ?? []).forEach(field => {\n            if (!field.field || field.value === undefined || field.value === null) return;\n            rec[field.field] = field.value;\n            if (field.payloadKey && field.payloadKey !== field.field) {\n                rec[field.payloadKey] = field.value;\n            }\n        });\n    });\n    return Object.keys(rec).length > 0 ? rec : null;\n}\n\nfunction pickPrefillValue(record, field) {\n    if (!record || !field) return undefined;\n    for (const path of [field.prefillFrom, field.field, field.payloadKey]) {\n        if (!path) continue;\n        let v = record[path];\n        if (v === undefined || v === null) v = getDeep(record, path);\n        if (v !== undefined && v !== null) return v;\n    }\n    return undefined;\n}\n\n// Convert a stored file-reference object to an Ant Design fileList entry so\n// file fields pre-show previously uploaded files when prefilling. Handles:\n//   resume:   { location, uploadedFileName, uniqueName }\n//   passport: { passportCopyLocation, passportUploadName, … }\n//   visa/alternateVisa: same *CopyLocation / *UploadName pattern\nfunction toFileListValue(value) {\n    // A multi-file field prefills from a stored ARRAY: map each element through\n    // the same single-file logic so every entry keeps its `stored` original too\n    // (it used to be handed to the control raw, which showed the files but lost\n    // them on save).\n    if (Array.isArray(value)) return value.flatMap((item) => toFileListValue(item));\n    if (!value || typeof value !== 'object') return [];\n    // Legacy schemas disagree about which key holds the original filename —\n    // passport uses passportUploadName, visa uses visaUniqueName. Matching only\n    // \"*UploadName\" found nothing for a visa, so it rendered as \"file\".\n    // See form/storedFileName.js.\n    const name = storedFileName(value);\n    const url = storedFileUrl(value);\n    if (!name && !url) return [];\n    // `stored` keeps the ORIGINAL container exactly as the record holds it\n    // (passportCopyLocation / passportUploadName / …). The payload engine writes\n    // it straight back when the user leaves the prefilled file untouched, so a\n    // Quick Submit from a previous submission carries its documents into the new\n    // record without re-uploading and without guessing at the stored shape.\n    return [{ uid: url || name || '-1', name: name || 'file', status: 'done', url, existing: true, stored: value }];\n}\n\nconst empty = (value) => value === undefined || value === null || value === '';\n\nconst REGION_OPTIONS = [\n    { label: 'US', value: 'US' },\n    { label: 'UK', value: 'UK' },\n    { label: 'India', value: 'INDIA' },\n];\n\n// Strip HTML tags and decode common entities — used so min/max validation\n// checks visible character count, not raw markup length.\nconst stripHtml = (html) =>\n    String(html)\n        .replace(/<[^>]*>/g, '')\n        .replace(/&nbsp;/g, ' ')\n        .replace(/&amp;/g, '&')\n        .replace(/&lt;/g, '<')\n        .replace(/&gt;/g, '>')\n        .trim();\n\nconst numberRangeRule = ({ label, message, value, compare, text }) => ({\n    validator: (_, input) => {\n        if (empty(input)) return Promise.resolve();\n        return compare(Number(input), Number(value))\n            ? Promise.resolve()\n            : Promise.reject(new Error(message ?? `${label} ${text} ${value}`));\n    },\n});\n\n// Date comparison + picker-constraint helpers now live in ONE place\n// (components/form/dateRules.js) and are imported at the top of this file.\n// They used to be duplicated verbatim between AddFormV1 and EditFormV1, which\n// is how a fix lands on Add and silently misses Edit.\n\n// Same resolution both forms have always used, now shared (form/maxCeiling.js)\n// so it can be unit tested: a DOTTED reference is absolute (reaches out of the\n// validated field's container), a bare one is a sibling.\nfunction getSiblingFieldName(currentName, compareField) {\n    return resolveCompareFieldName(currentName, compareField);\n}\n\nconst crossFieldNumberRule = ({ label, message, value, rule, form, name, compare, text }) => ({\n    validator: async (_, input) => {\n        const compareField = value ?? rule.compareField ?? rule.field;\n        if (!compareField || empty(input)) return Promise.resolve();\n        const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n        if (empty(compareValue)) return Promise.resolve();\n        const inputNumber = Number(input);\n        const compareNumber = Number(compareValue);\n        if (Number.isNaN(inputNumber) || Number.isNaN(compareNumber)) return Promise.resolve();\n        return compare(inputNumber, compareNumber)\n            ? Promise.resolve()\n            : Promise.reject(new Error(message ?? `${label} ${text} ${compareField}`));\n    },\n});\n\nconst validationRulesByType = {\n    noPastDate: ({ label, message }) => ({\n        validator: (_, value) => {\n            if (empty(value)) return Promise.resolve();\n            const time = getComparableDateTime(value);\n            if (time === null) return Promise.resolve();\n            const today = new Date();\n            today.setHours(0, 0, 0, 0);\n            return time < today.getTime()\n                ? Promise.reject(new Error(message ?? `${label} cannot be a past date`))\n                : Promise.resolve();\n        },\n    }),\n    noFutureDate: ({ label, message }) => ({\n        validator: (_, value) => {\n            if (empty(value)) return Promise.resolve();\n            const time = getComparableDateTime(value);\n            if (time === null) return Promise.resolve();\n            const endOfDay = new Date();\n            endOfDay.setHours(23, 59, 59, 999);\n            return time > endOfDay.getTime()\n                ? Promise.reject(new Error(message ?? `${label} cannot be a future date`))\n                : Promise.resolve();\n        },\n    }),\n    minAge: ({ label, message, value }) => ({\n        validator: (_, input) => {\n            if (empty(input)) return Promise.resolve();\n            const time = getComparableDateTime(input);\n            if (time === null) return Promise.resolve();\n            const years = Number(value ?? 18);\n            const cutoff = new Date();\n            cutoff.setFullYear(cutoff.getFullYear() - years);\n            cutoff.setHours(23, 59, 59, 999);\n            return time > cutoff.getTime()\n                ? Promise.reject(new Error(message ?? `Must be at least ${years} years old`))\n                : Promise.resolve();\n        },\n    }),\n    // Both date-pair rules delegate to the shared engine, so `strict` (reject an\n    // equal date — the 7-July bug) and `minGap`/`minGapFrom` (the duration\n    // dropdown) behave identically on Add and Edit, and the SAME rule object\n    // also drives the picker's disabledDate below.\n    dateAfterField: ({ label, message, value, rule, form, name }) => buildPairValidator({\n        type: 'dateAfterField',\n        label,\n        rule: { ...rule, value: value ?? rule?.compareField ?? rule?.field, message },\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n    }),\n    dateBeforeField: ({ label, message, value, rule, form, name }) => buildPairValidator({\n        type: 'dateBeforeField',\n        label,\n        rule: { ...rule, value: value ?? rule?.compareField ?? rule?.field, message },\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n    }),\n    timeAfterField: ({ label, message, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const compareField = value ?? rule.compareField ?? rule.field;\n            if (!compareField || empty(input)) return Promise.resolve();\n            const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n            if (empty(compareValue)) return Promise.resolve();\n            const inputTime = getComparableTimeOfDay(input);\n            const compareTime = getComparableTimeOfDay(compareValue);\n            if (inputTime === null || compareTime === null || inputTime > compareTime) return Promise.resolve();\n            return Promise.reject(new Error(message ?? `${label} must be after ${compareField}`));\n        },\n    }),\n    timeBeforeField: ({ label, message, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const compareField = value ?? rule.compareField ?? rule.field;\n            if (!compareField || empty(input)) return Promise.resolve();\n            const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n            if (empty(compareValue)) return Promise.resolve();\n            const inputTime = getComparableTimeOfDay(input);\n            const compareTime = getComparableTimeOfDay(compareValue);\n            if (inputTime === null || compareTime === null || inputTime < compareTime) return Promise.resolve();\n            return Promise.reject(new Error(message ?? `${label} must be before ${compareField}`));\n        },\n    }),\n    greaterThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input >= other, text: 'must be greater than or equal to' }),\n    strictGreaterThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input > other, text: 'must be greater than' }),\n    strictLessThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input < other, text: 'must be less than' }),\n    lessThanOrEqualField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input <= other, text: 'must be less than or equal to' }),\n    // maxFromField — { type:'maxFromField', field:'<otherKey>', message }. The\n    // ONLY cross-field rule here that can reach OUT of its addRow row: it\n    // resolves the referenced key through renderField's `prefixFor` closure,\n    // i.e. exactly the scoping a Show Condition uses (row when the key is one of\n    // the row's own fields, top level otherwise). That is what lets a per-row\n    // \"experience\" be capped by a top-level overall-experience field, with which\n    // field caps which left entirely to Form Groups config.\n    maxFromField: (args) => maxFromFieldRule(args),\n    // maxFieldWithFallback — cap against the FIRST compare field carrying a\n    // usable maximum (\"cap at the To value, else the From value\"). Decision\n    // logic (incl. why a 0 ceiling means \"no ceiling\") lives in form/maxCeiling.js.\n    maxFieldWithFallback: ({ label, message, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const compareFields = parseCompareFields(value ?? rule.compareFields);\n            const result = checkMaxWithFallback({\n                input,\n                compareFields,\n                readValue: (fieldName) => readCompareValue(form, name, fieldName),\n            });\n            if (result.ok) return Promise.resolve();\n            return Promise.reject(new Error(message ?? `${label} must not exceed ${result.field}`));\n        },\n    }),\n    required: ({ field, message }) => ({\n        validator: (_, value) => {\n            let isEmpty = value === undefined || value === null || value === ''\n                || (Array.isArray(value) && value.length === 0);\n            if (!isEmpty && field?.type === 'text-editor') {\n                isEmpty = stripHtml(value) === '';\n            }\n            return isEmpty\n                ? Promise.reject(new Error(message ?? 'Mandatory Field'))\n                : Promise.resolve();\n        },\n    }),\n    email: ({ label, message }) => configuredEmailRule(label, message),\n    // Admin-configured \"already present\" check. Everything about it — the\n    // trigger, the blank handling, the normalizer, the message — comes from the\n    // validations entry; the server resolves the collection and the scope.\n    unique: ({ field, rule, uniqueContext }) => buildUniqueValidationRule({\n        field, validation: rule, context: uniqueContext,\n    }),\n\n    emailTags: ({ label, message }) => ({\n        validator: (_, value) => {\n            const tags = Array.isArray(value) ? value : [];\n            const invalid = tags.find((tag) => !isValidConfiguredEmail(tag));\n            return invalid\n                ? Promise.reject(new Error(message ?? `${label} contains an invalid email: ${invalid}`))\n                : Promise.resolve();\n        },\n    }),\n\n    noHtml: ({ label, message }) => ({\n        validator: (_, value) => {\n            if (value === undefined || value === null || value === '') return Promise.resolve();\n            const hasHtmlTag = /<\\/?[a-z][\\s\\S]*>/i.test(String(value));\n            return hasHtmlTag\n                ? Promise.reject(new Error(message ?? `${label} cannot contain HTML tags`))\n                : Promise.resolve();\n        },\n    }),\n    url: ({ label, message }) => ({ type: 'url', message: message ?? `Enter valid ${label}` }),\n    number: ({ label, message }) => ({ pattern: /^[0-9]+$/, message: message ?? `${label} must be a number` }),\n    phone: ({ message }) => ({\n        // Accepts the configured mask (e.g. 999-878-3413) — validates on the\n        // stripped digits so the separators the formatter inserts don't fail it.\n        validator: (_, value) => {\n            if (value === undefined || value === null || value === '') return Promise.resolve();\n            const { total } = parsePhoneFormat();\n            return phoneDigits(value).length === total\n                ? Promise.resolve()\n                : Promise.reject(new Error(message ?? `Phone number must contain exactly ${total} digits`));\n        },\n    }),\n\n    // The pre-existing minLength3 / minLength5 pair baked the threshold into the\n    // TYPE NAME, and existed only in AddFormV1 — configuring one on a field did\n    // nothing at all on the Edit form. Both now delegate to the generic `min`\n    // rule (admin: \"Min length/value\"), which already implements exactly this\n    // for non-number fields and is present in BOTH forms.\n    minLength3: (args) => validationRulesByType.min({ ...args, value: 3 }),\n    minLength5: (args) => validationRulesByType.min({ ...args, value: 5 }),\n\n    len: ({ label, message, value }) => ({ len: Number(value), message: message ?? `${label} must be ${value} characters` }),\n    pattern: ({ label, message, rule }) => ({\n        pattern: new RegExp(rule.pattern ?? rule.value, rule.flags),\n        message: message ?? `Enter valid ${label}`,\n    }),\n    min: ({ field, label, message, value }) => (\n        field.type === 'number'\n            ? numberRangeRule({ label, message, value, compare: (input, min) => input >= min, text: 'must be at least' })\n            : {\n                validator: (_, input) => {\n                    if (input == null || input === '') return Promise.resolve();\n                    const content = field.type === 'text-editor' ? stripHtml(input) : String(input);\n                    if (content === '') return Promise.resolve();\n                    return content.length >= Number(value)\n                        ? Promise.resolve()\n                        : Promise.reject(new Error(message ?? `${label} must be at least ${value} characters`));\n                },\n            }\n    ),\n    max: ({ field, label, message, value }) => (\n        field.type === 'number'\n            ? numberRangeRule({ label, message, value, compare: (input, max) => input <= max, text: 'must not exceed' })\n            : {\n                validator: (_, input) => {\n                    if (input == null || input === '') return Promise.resolve();\n                    const content = field.type === 'text-editor' ? stripHtml(input) : String(input);\n                    if (content === '') return Promise.resolve();\n                    return content.length <= Number(value)\n                        ? Promise.resolve()\n                        : Promise.reject(new Error(message ?? `${label} must not exceed ${value} characters`));\n                },\n            }\n    ),\n};\n\n// `prefixFor` is renderField's showIf prefix resolver; it is forwarded so a rule\n// that references another field resolves it with the same row-vs-top-level\n// scoping the Show Conditions use. Undefined for call sites that have no row\n// context (a repeat-scalar item), where the rules keep their sibling behaviour.\nfunction validationToRule(validation, field, form, name, prefixFor, uniqueContext) {\n    const rule = typeof validation === 'string' ? { type: validation } : validation;\n    const type = rule.type ?? rule.rule ?? rule.name;\n    const value = rule.value ?? rule.length ?? rule.min ?? rule.max;\n    const label = field.label ?? field.field ?? 'Field';\n    const factory = validationRulesByType[type];\n\n    return factory\n        ? factory({ field, label, message: rule.message, rule, value, form, name, prefixFor, uniqueContext })\n        : rule;\n}\n\nfunction getSiblingFieldPath(name, siblingField) {\n    return Array.isArray(name) && name.length > 1\n        ? [...name.slice(0, -1), siblingField]\n        : [siblingField];\n}\n\n// A field is required either via the simple \"req\" toggle or via a \"required\"\n// entry in the admin-configured validations list — the Form.Item asterisk and\n// the addRow \"at least one row\" check must honour both, not just field.req.\nfunction isFieldRequired(field, form, name) {\n    if (truthy(field?.req)) return true;\n    const apiRules = field?.validations ?? field?.validation ?? field?.rules ?? [];\n    if (apiRules.some((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'required')) return true;\n    if (field?.requiredIfField && form && name) {\n        return truthy(form.getFieldValue(getSiblingFieldPath(name, field.requiredIfField)));\n    }\n    return false;\n}\n\n// `uniqueContext` ({ checker, module, clientId, region }) is what turns a\n// configured `unique` validation into a live preflight check. Call sites with\n// no context (search forms, repeat-scalar items) still render the field; the\n// unique rule degrades to a no-op there and the server stays authoritative.\nfunction getRules(field, form, name, skipRequired = false, prefixFor = undefined, uniqueContext = undefined,\n    extraRules = undefined) {\n    const label = field.label ?? field.field ?? 'Field';\n    const apiRules = field.validations ?? field.validation ?? field.rules ?? [];\n    const hasApiRequired = apiRules.some((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'required');\n    const hasApiEmail = apiRules.some((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'email');\n    const rules = [];\n\n    // Rules the CALLER resolved because they need the group, which this\n    // function never sees — today, a region that refuses an in-progress entry.\n    // They go first so a blocked row reports that before anything else.\n    if (extraRules?.length) rules.push(...extraRules);\n\n    // Cross-row hierarchy: a newest-first list constrains each row against its\n    // NEIGHBOURS. The picker already greys the impossible dates out; this\n    // catches one that arrived another way — typed, pasted, prefilled from a\n    // résumé, or entered before the neighbouring row was filled in.\n    if (field.rowHierarchy) {\n        const ctx = rowContext(form, name);\n        if (ctx.rows) rules.push(buildRowHierarchyValidator({ field, ...ctx }));\n    }\n\n\n    // `requiredIfField` (e.g. \"make this mandatory once its sibling has a\n    // value\") stands on its own — it must not need field.req ALSO set, or a\n    // field configured with only requiredIfField silently never validates.\n    if (!skipRequired && !hasApiRequired && truthy(field.req) && field.disabledByField) {\n        // A field disabled via disabledByField (e.g. endDate while\n        // currentlyPursuing is checked) must not block submit with a\n        // \"required\" error the user has no way to satisfy.\n        rules.push({\n            validator: (_, input) => {\n                const disabledNow = truthy(form.getFieldValue(getSiblingFieldPath(name, field.disabledByField)));\n                if (disabledNow) return Promise.resolve();\n                return (input === undefined || input === null || input === '')\n                    ? Promise.reject(new Error('Mandatory Field'))\n                    : Promise.resolve();\n            },\n        });\n    } else if (!skipRequired && !hasApiRequired && field.requiredIfField) {\n        rules.push({\n            validator: (_, input) => {\n                const triggerValue = form.getFieldValue(getSiblingFieldPath(name, field.requiredIfField));\n                if (!truthy(triggerValue)) return Promise.resolve();\n                return (input === undefined || input === null || input === '')\n                    ? Promise.reject(new Error('Mandatory Field'))\n                    : Promise.resolve();\n            },\n        });\n    } else if (!skipRequired && truthy(field.req) && !hasApiRequired) {\n        rules.push({ required: true, message: 'Mandatory Field' });\n    }\n    if ((field.type === 'email' || field.formatter === 'email') && !hasApiEmail) {\n        rules.push(configuredEmailRule(label));\n    }\n    // Number fields are whole-number-only unless the admin marks them decimal\n    // (e.g. a commission of 5.5). Both patterns still reject any non-numeric\n    // character, so \"float only\" stays enforced either way.\n    if (field.type === 'number') {\n        rules.push(truthy(field.decimal)\n            ? { pattern: /^\\d+(\\.\\d+)?$/, message: `${label} must be a number` }\n            : { pattern: /^[0-9]+$/, message: `${label} must be a number` });\n    }\n\n    // attachUniqueSyncGuards re-wraps any `unique` rule so it only calls the\n    // server once every synchronous rule in this same list has passed.\n    // An admin-configured override checkbox (field.overrideCheckbox) suspends\n    // the validation TYPES it names while it is ticked. Applied here, over the\n    // built rules, so a gated rule is withheld at validation time rather than\n    // at render time — see form/validationOverride.js.\n    const buildRule = (rule) => validationToRule(rule, field, form, name, prefixFor, uniqueContext);\n    const mapRule = overrideRuleMapper(field, name, prefixFor, buildRule);\n\n    return attachUniqueSyncGuards([\n        ...rules,\n        ...apiRules.map(mapRule),\n        securityValidationRule(field),\n    ]);\n}\n\nfunction getValidationValue(field, type) {\n    const rules = field.validations ?? field.validation ?? field.rules ?? [];\n    const rule = rules.find((item) => (typeof item === 'string' ? item : item?.type) === type);\n    if (!rule || typeof rule === 'string') return undefined;\n    return rule.value ?? rule.length ?? rule[type];\n}\n\nfunction getInputLimits(field) {\n    const len = field.len ?? getValidationValue(field, 'len');\n    const min = field.min ?? getValidationValue(field, 'min');\n    const max = field.max ?? getValidationValue(field, 'max');\n\n    if (field.type === 'number') {\n        return {\n            min: min ?? undefined,\n            max: max ?? undefined,\n        };\n    }\n\n    return {\n        minLength: min ?? undefined,\n        maxLength: field.maxLength ?? len ?? max ?? undefined,\n    };\n}\n\n// Thin adapters over the shared engine (components/form/dateRules.js). The\n// bodies used to live here AND in EditFormV1; the picker's greyed-out range and\n// the submit-time error are now generated from the same rule object, so a\n// calendar that disagrees with its own error message is structurally impossible.\n// rowContext — the sibling ROWS of the repeatable group this field sits in,\n// plus this field's row index.\n//\n// A per-row `readSibling` can only see the row it is in, but a newest-first\n// list constrains a row against its NEIGHBOURS. Inside a Form.List the field\n// path is [listName, rowIndex, fieldKey], which is exactly what is needed to\n// read the whole list and locate this row within it.\n//\n// Returns {} outside a repeatable group, so the hierarchy simply never applies.\nfunction rowContext(form, name) {\n    if (!Array.isArray(name) || name.length < 3 || typeof name[1] !== 'number') return {};\n    const rows = form.getFieldValue(name[0]);\n    if (!Array.isArray(rows)) return {};\n    return { rows, rowIndex: name[1] };\n}\n\nfunction getDisabledDate(field, form, name) {\n    return buildDisabledDate({\n        field,\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n        ...rowContext(form, name),\n    });\n}\n\nfunction getDefaultPickerValue(field) {\n    return defaultPickerValue(field);\n}\n\nfunction cleanValue(value, formatter) {\n    if (!formatter) return value;\n    // Phone gets the common, config-driven mask (default 3-3-4 → 999-878-3413).\n    // \"digits\" stays a bare digit string (no separators).\n    if (formatter === 'phone') return formatPhone(value);\n    if (formatter === 'digits') return value.replace(/\\D/g, '').slice(0, 10);\n    if (formatter === 'email' || formatter === 'noSpaces') return value.replace(/\\s/g, '');\n    if (formatter === 'name') return value.replace(/\\s+/g, ' ').trimStart().replace(/\\b\\w/g, (char) => char.toUpperCase());\n    return value;\n}\n\nfunction normalizeModule(moduleName = '') {\n    const normalized = String(moduleName).toLowerCase();\n    if (normalized === 'job') return 'jobs';\n    if (normalized === 'candidate') return 'candidates';\n    if (normalized === 'submissions') return 'submission';\n    return normalized;\n}\n\nconst SEARCH_SOURCE_ONLY_FIELDS = new Set([\n    'selectedSource',\n    'source',\n    'sourceType',\n    'scope',\n]);\n\nfunction hasSearchCriterionValue(value) {\n    if (value === null || value === undefined) return false;\n    if (typeof value === 'string') return value.trim().length > 0;\n    if (typeof value === 'number') return Number.isFinite(value);\n    if (typeof value === 'boolean') return value;\n    if (dayjs.isDayjs(value)) return value.isValid();\n    if (Array.isArray(value)) return value.some(hasSearchCriterionValue);\n    if (typeof value === 'object') {\n        if ('value' in value || 'label' in value || 'name' in value) {\n            return hasSearchCriterionValue(value.value ?? value.label ?? value.name);\n        }\n        return Object.entries(value).some(([key, nestedValue]) => (\n            !SEARCH_SOURCE_ONLY_FIELDS.has(key) && hasSearchCriterionValue(nestedValue)\n        ));\n    }\n\n    return false;\n}\n\nfunction hasSearchCriteria(values = {}) {\n    return Object.entries(values ?? {}).some(([key, value]) => (\n        !SEARCH_SOURCE_ONLY_FIELDS.has(key) && hasSearchCriterionValue(value)\n    ));\n}\n\n// buildDynamicFormData — builds the multipart FormData payload to send to the\n// Auth gateway.\n//\n//   • File fields are appended as separate FormData parts. The part name is the\n//     field's `fileKey` if configured, else the first segment of its path\n//     (e.g. \"passport.passportUploadName\" → \"passport\"). Files nested inside an\n//     addRow group array are collected from every row.\n//   • All other fields are turned into the JSON \"json\" part by the shared,\n//     config-driven payload engine (buildPayload). There is ZERO field-name or\n//     module-specific logic here — payloadKey / dataType / payloadMode / template\n//     are all read from the admin form-group config.\n//\n// Dynamic by design: any new field added in the admin panel is automatically\n// included — no code change required. New modules work the same way.\nfunction buildDynamicFormData(values, groups, extraPayload = {}, module = '') {\n    const formData = new FormData();\n\n    // New files → multipart parts, via the SHARED engine helper. On CREATE we\n    // attach only the flat (non-repeatable) file fields — resume, photo, jobs\n    // \"file\", passport, visa. Repeatable (addRow) document files are uploaded in\n    // a follow-up update (see submit) because the create handler mishandles them;\n    // the indexed update path is the reliable one. The document METADATA still\n    // rides along in the JSON payload here, so the rows are created on insert and\n    // the follow-up update just attaches each file to its row by index.\n    collectFileParts(values, groups, { scope: 'flat', module }).forEach(({ formKey, file }) => {\n        formData.append(formKey, file);\n    });\n\n    // Config-driven JSON payload (file fields are skipped by the engine).\n    // extraPayload carries linkage/context keys that are NOT form fields but the\n    // downstream create requires (e.g. submission needs jobId + applicantId). These\n    // are merged first so a real form field of the same name still wins.\n    const payload = { ...extraPayload, ...buildPayload(values, groups, { module }) };\n    payload.schemaVersion = 1;\n\n    formData.append('json', JSON.stringify(payload));\n    return formData;\n}\n\nfunction FieldControl({ field, form, name, moduleName, value, checked, onChange, scopeValues = {}, onAiUpload, onDuplicateBlur, onRegionBlocked, onRowOrderChange, formDisabled, rowFieldKeys }) {\n    const type = field.type ?? 'text';\n    const baseDisabled = !editable(field, moduleName);\n    const [dynamicOptions, setDynamicOptions] = useState(null);\n    const [optionsLoading, setOptionsLoading] = useState(false);\n    const [locationSearch, setLocationSearch] = useState('');\n    const [lookupSearch, setLookupSearch] = useState('');\n    const [masterSearch, setMasterSearch] = useState('');\n    // Bumped after a quick create/edit (\"Add More\") so the dropdown refetches its\n    // options and the freshly created/edited record appears immediately.\n    const [refetchNonce, setRefetchNonce] = useState(0);\n    const [viewer, setViewer] = useState({ open: false, docs: [], index: 0 });\n    const [inputError, setInputError] = useState(null);\n    const rawLookupRef = useRef([]);\n    // lookupFilterValueFrom resolves against the SAME addRow row first (so a\n    // per-row cascade like employerId → that row's recruiter list works), then\n    // falls back to the top-level path — which is what every pre-existing\n    // top-level config used. Both are always watched (hooks can't be\n    // conditional); the row value wins whenever it is non-empty.\n    const insideListRow = Array.isArray(name) && name.length >= 3 && typeof name[1] === 'number';\n    const topFilterPath = field.lookupFilterValueFrom ? namePathFromString(field.lookupFilterValueFrom) : [`__lookup_filter_${field.field}`];\n    const rowFilterPath = (field.lookupFilterValueFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.lookupFilterValueFrom)]\n        : ['__noop_row_filter__'];\n    const topFilterValue = Form.useWatch(topFilterPath, form);\n    const rowFilterValue = Form.useWatch(rowFilterPath, form);\n    const formFilterValue = !empty(rowFilterValue) ? rowFilterValue : topFilterValue;\n    // Watch sibling field for disabledByField — e.g. endDate disabled when currentlyPursuing is checked\n    const disabledBySiblingPath = field.disabledByField\n        ? (Array.isArray(name) && name.length > 1 ? [...name.slice(0, -1), field.disabledByField] : [field.disabledByField])\n        : ['__noop_disabled_watch__'];\n    const disabledByValue = Form.useWatch(disabledBySiblingPath, form);\n    // disabledIf — conditional read-only, same operator set as showIf (eq/neq/\n    // truthy/falsy/in/notIn), e.g. lock the Employer to the configured default\n    // when Contract Type is W2. The row value wins when the condition field\n    // lives in this row; otherwise the top-level field drives it.\n    const disabledIfTopPath = field.disabledIf?.field ? namePathFromString(field.disabledIf.field) : ['__noop_disabled_if__'];\n    const disabledIfRowPath = (field.disabledIf?.field && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.disabledIf.field)]\n        : ['__noop_disabled_if_row__'];\n    const disabledIfTop = Form.useWatch(disabledIfTopPath, form);\n    const disabledIfRow = Form.useWatch(disabledIfRowPath, form);\n    const conditionallyDisabled = field.disabledIf?.field\n        ? labelConditionMatches(field.disabledIf, !empty(disabledIfRow) ? disabledIfRow : disabledIfTop)\n        : false;\n    // optionsFromField (admin config) — narrow this select's options to the live\n    // value of ANOTHER field (e.g. the candidate rate unit may only be the unit\n    // the linked job was raised in, which prefillFromModule already puts on the\n    // form). Resolved with the same scoping a Show Condition uses: the row's own\n    // field when the key belongs to this row (rowFieldKeys), the top-level field\n    // otherwise — with a row-first fallback when membership is unknown, matching\n    // lookupFilterValueFrom above. Both paths are always watched (hooks cannot be\n    // conditional) so the dropdown re-narrows the moment the source changes.\n    const constraintKey = field.optionsFromField || '';\n    const constraintTopPath = constraintKey ? namePathFromString(constraintKey) : ['__noop_options_from__'];\n    const constraintRowPath = (constraintKey && insideListRow && (!rowFieldKeys || rowFieldKeys.has(constraintKey)))\n        ? [...name.slice(0, 2), ...namePathFromString(constraintKey)]\n        : ['__noop_options_from_row__'];\n    const constraintTopValue = Form.useWatch(constraintTopPath, form);\n    const constraintRowValue = Form.useWatch(constraintRowPath, form);\n    const constraintValue = !empty(constraintRowValue) ? constraintRowValue : constraintTopValue;\n    // prefillWhenExclusive (admin config) — \"a value a Conditional Default rule\n    // would SET is EXCLUSIVE to that rule's condition\". While the rule matches,\n    // its value is offered (and PrefillWhenWatcher auto-selects it, as today);\n    // while it does not, the value is REMOVED from the list instead of merely\n    // being a stale default. Reuses field.prefillWhen so the hidden value and\n    // the auto-filled value can never drift apart. Default off — a field\n    // without the flag offers exactly what it offers today.\n    //\n    // HOOK SAFETY: the rule list is admin data, so it must never decide how\n    // many hooks run. ONE selector-form useWatch reads every referenced field\n    // out of the whole store and reduces them to a STRING (a fresh array each\n    // render would churn the memo); the rule count changes what the selector\n    // reads, never the hook count. Same row-vs-top-level scoping as\n    // optionsFromField above: a rule key belonging to this addRow row resolves\n    // to the row's own field, anything else (the top-level contract type read\n    // from inside repeatable employer rows) to the top-level path.\n    const exclusivePrefillRules = (truthy(field.prefillWhenExclusive) && field.prefillWhen?.length)\n        ? field.prefillWhen\n        : null;\n    const exclusivePrefillKey = Form.useWatch(\n        (values) => (exclusivePrefillRules\n            ? JSON.stringify(prefillWhenWatchFields(exclusivePrefillRules).map((key) => {\n                const read = (path) => path.reduce((acc, k) => (acc == null ? acc : acc[k]), values);\n                const rowValue = (insideListRow && (!rowFieldKeys || rowFieldKeys.has(key)))\n                    ? read([...name.slice(0, 2), ...namePathFromString(key)])\n                    : undefined;\n                return (!empty(rowValue) ? rowValue : read(namePathFromString(key))) ?? null;\n            }))\n            : ''),\n        { form, preserve: true },\n    );\n    const exclusivePrefillWatched = useMemo(() => {\n        if (!exclusivePrefillRules || !exclusivePrefillKey) return null;\n        const values = JSON.parse(exclusivePrefillKey);\n        const watched = {};\n        prefillWhenWatchFields(exclusivePrefillRules).forEach((key, i) => { watched[key] = values[i]; });\n        return watched;\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [exclusivePrefillKey]);\n    const groupDisabled = useContext(GroupDisabledContext);\n    // exclusiveInGroup — only ONE row of a repeatable group may hold this flag\n    // (e.g. \"Currently Working Here\" / \"Currently Pursuing\": a person has one\n    // current employer and one course in progress). Once any row claims it, the\n    // control is disabled on every OTHER row, so the state cannot become\n    // ambiguous. The claiming row keeps its control enabled — that is how the\n    // user releases the claim and moves it elsewhere.\n    //\n    // Watching the whole Form.List (not one sibling) is what makes this react\n    // to a change in a DIFFERENT row.\n    const exclusiveListPath = (field.exclusiveInGroup && insideListRow)\n        ? [name[0]]\n        : ['__noop_exclusive_watch__'];\n    const exclusiveRows = Form.useWatch(exclusiveListPath, form);\n    const claimedByAnotherRow = useMemo(() => {\n        if (!field.exclusiveInGroup || !insideListRow || !Array.isArray(exclusiveRows)) return false;\n        const myIndex = name[1];\n        const leaf = name[name.length - 1];\n        return exclusiveRows.some((row, index) => index !== myIndex && truthy(row?.[leaf]));\n    }, [field.exclusiveInGroup, insideListRow, exclusiveRows, name]);\n    // scopeValues only wins when it actually carries a value — a key present\n    // but undefined/empty must fall back to the field's own live form value,\n    // or the lookup filter is permanently starved and never resolves options.\n    const scopeFilterValue = field.lookupFilterValueFrom\n        ? scopeValues[field.lookupFilterValueFrom]\n        : undefined;\n    const lookupFilterValue = !empty(scopeFilterValue) ? scopeFilterValue : formFilterValue;\n    // ---- Dependent-lookup staleness guard (generic; see also EditFormV1) ----\n    // A lookup scoped by `lookupFilterValueFrom` must not keep a value that was\n    // chosen under a DIFFERENT parent. Changing the parent refetches the OPTIONS\n    // (lookupFilterValue is a dependency of that effect) but used to leave this\n    // field's own value untouched — so picking client A's contact \"Naveen\" and\n    // then switching to client B left A's contact id sitting on the form.\n    //\n    // That went unnoticed because a nested reference id is only unique WITHIN\n    // its parent: clientContact.clientContactId is a per-client sequence\n    // (1, 2, 3 ...), so the orphaned id still resolved against the new client —\n    // to a DIFFERENT person — and saved looking perfectly valid. A wrong name\n    // that looks right is worse than a blank one.\n    //\n    // Only a genuine CHANGE clears. The first observed value is recorded without\n    // clearing, so edit prefill (which sets parent and child together) and the\n    // initial mount are untouched; and a parent going from empty -> known never\n    // clears, because nothing can have been chosen under an unknown parent yet.\n    const parentFilterRef = useRef(PARENT_FILTER_UNSEEN);\n    useEffect(() => {\n        if (!field.lookupFilterField || !field.lookupFilterValueFrom) return;\n        const previous = parentFilterRef.current;\n        parentFilterRef.current = lookupFilterValue;\n        if (!shouldClearDependentValue({\n            previous,\n            next: lookupFilterValue,\n            currentValue: form.getFieldValue(name),\n        })) return;\n        form.setFields([{ name, value: undefined, errors: [] }]);\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [lookupFilterValue]);\n\n\n    // locationMaster cascade (Country → State → City, sourced from the\n    // locationMasters collection). Same top/row watch pattern as\n    // lookupFilterValueFrom above: the sibling holding the PARENT level's\n    // selected value, watched so options refetch — and the control disables —\n    // the moment it changes. `locationCountryFrom` feeds a \"state\" level\n    // field; \"city\" needs both `locationCountryFrom` and `locationStateFrom`.\n    const locCountryTopPath = field.locationCountryFrom ? namePathFromString(field.locationCountryFrom) : ['__noop_loc_country__'];\n    const locCountryRowPath = (field.locationCountryFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.locationCountryFrom)]\n        : ['__noop_loc_country_row__'];\n    const locCountryTop = Form.useWatch(locCountryTopPath, form);\n    const locCountryRow = Form.useWatch(locCountryRowPath, form);\n    const locCountryValue = !empty(locCountryRow) ? locCountryRow : locCountryTop;\n    const locStateTopPath = field.locationStateFrom ? namePathFromString(field.locationStateFrom) : ['__noop_loc_state__'];\n    const locStateRowPath = (field.locationStateFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.locationStateFrom)]\n        : ['__noop_loc_state_row__'];\n    const locStateTop = Form.useWatch(locStateTopPath, form);\n    const locStateRow = Form.useWatch(locStateRowPath, form);\n    const locStateValue = !empty(locStateRow) ? locStateRow : locStateTop;\n    const locationLocked = field.dataSource === 'locationMaster' && (\n        (field.locationLevel === 'state' && empty(locCountryValue))\n        || (field.locationLevel === 'city' && (empty(locCountryValue) || empty(locStateValue)))\n    );\n    const disabled = baseDisabled || Boolean(field.disabled) || conditionallyDisabled || (field.disabledByField ? truthy(disabledByValue) : false) || Boolean(formDisabled) || groupDisabled || claimedByAnotherRow || locationLocked;\n\n    // Fetch options dynamically when dataSource is master / module / lookup.\n    // Static and undefined sources skip the API call and use field.options directly.\n    useEffect(() => {\n        if (type === 'location') {\n            let cancelled = false;\n            setOptionsLoading(true);\n\n            async function fetchLocations() {\n                try {\n                    const params = new URLSearchParams({\n                        search: locationSearch,\n                        limit: String(field.limit ?? 50),\n                        offset: '0',\n                    });\n                    const json = await fetchJsonWithAuth(AUTH_URL, `/admin/location-dropdown-values?${params}`);\n                    const raw = json?.data ?? json ?? [];\n                    if (!cancelled) setDynamicOptions(normalizeOptions(Array.isArray(raw) ? raw : []));\n                } catch (err) {\n                    console.error(`[AddFormV1] Failed to fetch locations for \"${field.field}\":`, err);\n                    if (!cancelled) setDynamicOptions([]);\n                } finally {\n                    if (!cancelled) setOptionsLoading(false);\n                }\n            }\n\n            fetchLocations();\n            return () => { cancelled = true; };\n        }\n        const ds = field.dataSource;\n        if (!['select', 'radio', 'checkbox'].includes(type)) return undefined;\n        if (!ds || ds === 'static') return undefined;\n        if (ds === 'lookup' && field.lookupFilterField && empty(lookupFilterValue)) {\n            setDynamicOptions([]);\n            setOptionsLoading(false);\n            return undefined;\n        }\n\n        // lookupMinSearchLength (opt-in): don't preload the full list on\n        // mount — wait until the user has actually typed enough characters.\n        // Existing lookup fields without this flag keep today's behavior\n        // (full list shown immediately) untouched.\n        if (ds === 'lookup' && field.lookupMinSearchLength && lookupSearch.trim().length < field.lookupMinSearchLength) {\n            setDynamicOptions([]);\n            setOptionsLoading(false);\n            return undefined;\n        }\n\n        let cancelled = false;\n        setOptionsLoading(true);\n\n        async function fetchOptions() {\n            try {\n                let raw = [];\n                if (ds === 'master' || ds === 'module') {\n                    raw = await getDropdownValues(\n                        moduleName,\n                        field.field,\n                        ds === 'master' ? masterSearch : '',\n                        field.limit ?? 50,\n                        0,\n                        {\n                            dataSource: ds,\n                            masterName: field.masterName,\n                            groupName: field.groupName,\n                        },\n                    );\n                } else if (ds === 'lookup') {\n                    const params = new URLSearchParams({\n                        collection: field.lookupCollection ?? '',\n                        displayField: field.displayField ?? '',\n                        valueField: field.valueField ?? '_id',\n                    });\n                    if (field.displayField2) params.set('displayField2', field.displayField2);\n                    if (lookupSearch) params.set('search', lookupSearch);\n                    if (field.lookupFilterField && !empty(lookupFilterValue)) {\n                        params.set('filterField', field.lookupFilterField);\n                        params.set('filterValue', String(lookupFilterValue));\n                    }\n                    if (Array.isArray(field.filters) && field.filters.length > 0) {\n                        params.set('filters', JSON.stringify(field.filters));\n                    }\n                    // The row-filter config, rebuilt from the individual keys\n                    // rather than passing `field` itself: every key here is a\n                    // dependency of this effect, so the options refetch and\n                    // re-filter whenever an admin changes one of them.\n                    const rowFilterConfig = {\n                        field: field.field,\n                        extraFields: field.extraFields,\n                        optionsRequireExtraField: field.optionsRequireExtraField,\n                        optionsRequireExtraValue: field.optionsRequireExtraValue,\n                        optionsHierarchyParentField: field.optionsHierarchyParentField,\n                        optionsHierarchySelfFrom: field.optionsHierarchySelfFrom,\n                    };\n                    // Every extraData key the row filters need is requested\n                    // automatically alongside the explicit extraFields, so a\n                    // filter key can never be configured without its data.\n                    const extraKeys = lookupExtraFieldKeys(rowFilterConfig);\n                    if (extraKeys.length) params.set('extraFields', extraKeys.join(','));\n                    const json = await fetchJsonWithAuth(AUTH_URL, `/admin/lookup-dropdown-values?${params}`);\n                    raw = json?.data ?? json ?? [];\n                    // Config-driven row filters: value match on an extraData key\n                    // (e.g. only list a recruiter once verified, or only a given\n                    // role) and/or the signed-in user's reporting downline.\n                    raw = filterLookupOptionRows(raw, rowFilterConfig, { source: 'AddFormV1' });\n                } else if (ds === 'locationMaster') {\n                    const level = field.locationLevel || 'country';\n                    if (level === 'state' && empty(locCountryValue)) {\n                        raw = [];\n                    } else if (level === 'city' && (empty(locCountryValue) || empty(locStateValue))) {\n                        raw = [];\n                    } else {\n                        const params = new URLSearchParams({ level, limit: String(field.limit ?? 250), offset: '0' });\n                        if (!empty(locCountryValue)) params.set('country', String(locCountryValue));\n                        if (!empty(locStateValue)) params.set('state', String(locStateValue));\n                        if (lookupSearch) params.set('search', lookupSearch);\n                        const json = await fetchJsonWithAuth(AUTH_URL, `/admin/location-dropdown-values?${params}`);\n                        raw = json?.data ?? json ?? [];\n                    }\n                } else if (ds === 'group') {\n                    const gn = (field.groupName ?? '').toLowerCase().trim();\n                    if (gn === 'users' || gn === 'user') {\n                        const json = await fetchJsonWithAuth(AUTH_URL, '/get-all-users?limit=500&offset=0');\n                        const users = json?.data?.users ?? json?.users ?? json?.data ?? [];\n                        // groupRoleContains (admin config) — e.g. \"manager\" lists every\n                        // user whose role NAME contains that word (Delivery Manager,\n                        // Onboarding Manager, Submission Manager, …), not just a single\n                        // exact role. `/get-all-users` already returns each user's\n                        // roleName, so this narrows client-side with no extra request.\n                        const roleContains = String(field.groupRoleContains ?? '').trim().toLowerCase();\n                        const filteredUsers = roleContains\n                            ? (Array.isArray(users) ? users.filter((u) => String(u.roleName ?? '').toLowerCase().includes(roleContains)) : [])\n                            : users;\n                        raw = Array.isArray(filteredUsers) ? filteredUsers.map((u) => ({\n                            label: [u.firstName, u.lastName].filter(Boolean).join(' ').trim() || u.userName || u.email || String(u.userId),\n                            value: u.userId ?? u.id,\n                        })) : [];\n                    }\n                }\n                if (!cancelled) {\n                    rawLookupRef.current = Array.isArray(raw) ? raw : [];\n                    setDynamicOptions(normalizeOptions(rawLookupRef.current));\n                }\n            } catch (err) {\n                console.error(`[AddFormV1] Failed to fetch options for \"${field.field}\":`, err);\n                if (!cancelled) setDynamicOptions([]);\n            } finally {\n                if (!cancelled) setOptionsLoading(false);\n            }\n        }\n\n        fetchOptions();\n        return () => { cancelled = true; };\n    }, [type, field.dataSource, field.field, field.limit, field.lookupCollection, field.displayField, field.displayField2, field.valueField, field.lookupFilterField, lookupFilterValue, field.groupName, field.groupRoleContains, field.masterName, locationSearch, lookupSearch, masterSearch, moduleName, field.extraFields, field.optionsRequireExtraField, field.optionsRequireExtraValue, field.optionsHierarchyParentField, field.optionsHierarchySelfFrom, refetchNonce, field.lookupMinSearchLength, field.locationLevel, field.locationCountryFrom, field.locationStateFrom, locCountryValue, locStateValue]);\n\n    const staticOptions = normalizeOptions(field.options ?? field.values ?? []);\n    const baseOptions = dynamicOptions ?? staticOptions;\n\n    // ── Stored values outside the filtered option list ──────────────────────\n    // `lookupFilters` decide what may be PICKED. They must not decide what an\n    // already-assigned value is allowed to SHOW — a job assigned to somebody\n    // outside the current user's reporting chain rendered its raw id (\"149\")\n    // instead of a name. Resolved separately, unfiltered, and appended.\n    const [resolvedOptions, setResolvedOptions] = useState([]);\n    const missingValues = missingOptionValues(value, baseOptions);\n    // Joined into a string: the array identity changes every render, and a raw\n    // array dependency would refetch forever.\n    const missingKey = missingValues.join(',');\n    useEffect(() => {\n        if (!missingKey || field.dataSource !== 'lookup' || optionsLoading) return undefined;\n        let cancelled = false;\n        fetchLookupLabels(field, missingKey.split(','))\n            .then((rows) => { if (!cancelled) setResolvedOptions(rows); })\n            // Best effort. Failing to resolve a label must never break the\n            // field — the value is still there and still submits.\n            .catch(() => { if (!cancelled) setResolvedOptions([]); });\n        return () => { cancelled = true; };\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [missingKey, field.dataSource, field.lookupCollection, field.displayField,\n        field.displayField2, field.valueField, optionsLoading]);\n    // optionsFromField constraint applied here so EVERY option-driven control\n    // (select, radio, checkbox group, location…) is narrowed the same way.\n    // Fails open — see narrowOptionsByConstraint. prefillWhenExclusive then\n    // COMPOSES on top of that narrowing (it removes, it never restores).\n    const optionsWithStored = mergeResolvedOptions(baseOptions, resolvedOptions);\n    const constrainedOptions = constraintKey ? narrowOptionsByConstraint(optionsWithStored, constraintValue) : optionsWithStored;\n    const options = exclusivePrefillRules\n        ? stripExclusivePrefillOptions(constrainedOptions, exclusivePrefillRules, exclusivePrefillWatched ?? {})\n        : constrainedOptions;\n\n    // Select multiplicity is config-driven: multiSelect flag → explicit mode →\n    // field.multiple → array dataType. No field-name list. \"tags\" is opt-in via\n    // an explicit field.mode === \"tags\".\n    const selectMode = field.multiSelect\n        ? 'multiple'\n        : (field.mode ?? (truthy(field.multiple) ? 'multiple' : undefined));\n    const inferredSelectMode = selectMode ?? (effectiveDataType(field) === 'array' ? 'multiple' : undefined);\n    // allowCustomValues (admin config) — the field keeps a value the user TYPED\n    // even when it is not in the list (Candidate → Skills is the first user, but\n    // nothing here is module- or field-specific: any select/lookup field can opt\n    // in from Form Groups). Until now free entry existed only for the hardcoded\n    // `type: 'tagify'` control, which is not per-field selectable and loses every\n    // other select behaviour (lookup, autofill, quick-create).\n    const allowCustomValues = truthy(field.allowCustomValues);\n    // antd's \"tags\" mode is what keeps a typed value; it always emits an ARRAY,\n    // so a single-valued field has to be unwrapped again on the way out (see\n    // handleSelectChange) and wrapped on the way in.\n    const effectiveSelectMode = allowCustomValues ? 'tags' : inferredSelectMode;\n    const isArrayValued = Boolean(field.multiSelect) || truthy(field.multiple)\n        || effectiveDataType(field) === 'array' || inferredSelectMode === 'multiple';\n    // Config-driven separators that commit a typed entry (default comma).\n    const tokenSeparators = allowCustomValues\n        ? (typeof field.tokenSeparators === 'string' && field.tokenSeparators\n            ? field.tokenSeparators.split('')\n            : [','])\n        : undefined;\n\n    const isSelectLike = ['select', 'location'].includes(type);\n    const placeholder = field.hidePlaceholder\n        ? undefined\n        : (field.placeholder ?? `${isSelectLike ? 'Select' : 'Enter'} ${String(field.label ?? '').toLowerCase()}`);\n    const inputLimits = getInputLimits(field);\n    // Sets the value in the form store first, then re-validates.\n    // Required because FieldControl is a custom wrapper — Form.Item's injected\n    // onChange never reaches the inner Ant Design components, so the store\n    // would otherwise hold stale/undefined values when validation runs.\n    const updateAndValidate = (nextValue) => {\n        onChange?.(nextValue);\n\n        setTimeout(() => {\n            form.validateFields([name]).catch(() => { });\n        }, 0);\n    };\n\n    // Config-driven \"Add More\"/\"Edit\" quick actions inside a select dropdown.\n    // Called unconditionally (rules of hooks) — returns nulls unless the field\n    // opts in via quickCreate/quickEdit. On success, refetch options and (for a\n    // fresh create on a single select) select the new record.\n    const quick = useQuickField({\n        field, form, name, moduleName, scopeValues, ownValue: value,\n        onDone: (kind, newId) => {\n            setRefetchNonce((n) => n + 1);\n            const single = effectiveDataType(field) !== 'array' && !field.multiSelect && !field.multiple;\n            if (kind === 'create' && newId != null && single) {\n                // Same clearing the ordinary onChange does. Creating an employer\n                // from inside the dropdown IS changing the employer, so the rest\n                // of the group — recruiter, email, contact, VMS — still describes\n                // the PREVIOUS one and must go. This path set the new value and\n                // skipped the clear, so a brand-new employer kept the old\n                // employer's recruiter beside it, which reads as a real pairing.\n                //\n                // Cleared BEFORE the value is written, so anything the new\n                // selection autofills is preserved rather than wiped after.\n                if (field.clearGroupOnChange || field.linkedClearField) {\n                    applyGroupClear(form, field, name, rowFieldKeys);\n                }\n                updateAndValidate(usesLabeledSelectValue(field) ? { value: newId } : newId);\n            }\n        },\n    });\n\n    // Build validator config once (null when not set)\n    const validatorCfg = field.validator?.type\n        ? { ...field.validator, title: field.validator.title || field.label || 'Field' }\n        : null;\n\n    const inputProps = {\n        ...inputLimits,\n        disabled,\n        placeholder,\n        prefix: field.icon ? null : fieldIcons[field.field],\n        value: value ?? '',\n        onChange: (event) => {\n            let nextValue = field.formatter\n                ? cleanValue(event.target.value, field.formatter)\n                : event.target.value;\n\n            if (validatorCfg) {\n                const { cleaned, error } = applyInputValidator(nextValue, validatorCfg, 'change');\n                setInputError(error);\n                nextValue = cleaned;\n            }\n\n            updateAndValidate(nextValue);\n        },\n        // Composed, not conditional. The character-validator blur only exists\n        // when a validator is configured, so hanging the duplicate check off it\n        // would silently skip every field without one — including a plain email\n        // box, which is exactly the field this is for.\n        onBlur: (e) => {\n            if (validatorCfg) {\n                const { cleaned, error } = applyInputValidator(e.target.value, validatorCfg, 'blur');\n                setInputError(error);\n                if (cleaned !== e.target.value) updateAndValidate(cleaned);\n            }\n            // Typing an email that already exists should be caught here, not on\n            // submit after the whole form has been filled in.\n            if (field.checkDuplicateOnBlur && String(e.target.value ?? '').trim()) {\n                onDuplicateBlur?.(field);\n            }\n        },\n        ...(validatorCfg && {\n            onKeyPress: (e) => {\n                const pattern = getKeyPattern(validatorCfg.type);\n                if (!pattern) return;\n                if (e.which === 0 || e.keyCode === 8 || e.keyCode === 13) return;\n                const char = String.fromCharCode(e.which ?? e.keyCode);\n                if (!pattern.test(char)) {\n                    e.preventDefault();\n                    const hint = `${validatorCfg.title} — invalid character.`;\n                    setInputError(hint);\n                    setTimeout(() => setInputError((prev) => (prev === hint ? null : prev)), 1800);\n                }\n            },\n            maxLength: validatorCfg.maxLength ?? inputLimits.maxLength,\n        }),\n    };\n\n    if (type === 'tagify') {\n        return (\n            <Select\n                value={value}\n                allowClear\n                disabled={disabled}\n                mode=\"tags\"\n                placeholder={placeholder}\n                onChange={updateAndValidate}\n            />\n        );\n    }\n    if (type === 'location') {\n        return (\n            <Select\n                value={value}\n                allowClear\n                showSearch\n                filterOption={false}\n                disabled={disabled}\n                loading={optionsLoading}\n                // Single or multi is admin config (Form Groups → the field's\n                // \"Location selection\"). inferredSelectMode is the SAME resolver\n                // an ordinary select uses, so multiSelect / multiple / an array\n                // dataType all mean the same thing on a location field as they\n                // do everywhere else — and effectiveDataType already types a\n                // multiSelect field's payload as an array, so nothing extra is\n                // needed to store several locations.\n                mode={inferredSelectMode}\n                options={options}\n                placeholder={placeholder}\n                notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n                onSearch={setLocationSearch}\n                onFocus={() => setLocationSearch((current) => current)}\n                onChange={updateAndValidate}\n            />\n        );\n    }\n    if (type === 'select') {\n        const remoteLookup = field.dataSource === 'lookup';\n        const remoteMaster = field.dataSource === 'master';\n        const remoteSearch = remoteLookup || remoteMaster;\n        const keepLabel = usesLabeledSelectValue(field);\n        const rawControlValue = toSelectControlValue(field, value, options);\n        // \"tags\" mode renders from an array. A single-valued field that opted\n        // into allowCustomValues still stores a scalar, so wrap it for display\n        // only — the stored shape never changes.\n        const controlValue = (allowCustomValues && !isArrayValued)\n            ? (rawControlValue === undefined || rawControlValue === null || rawControlValue === ''\n                ? undefined\n                : (Array.isArray(rawControlValue) ? rawControlValue : [rawControlValue]))\n            : rawControlValue;\n        const handleSelectChange = (raw) => {\n            // …and unwrap on the way out: keep the LAST entry the user typed or\n            // picked, so a single-valued field never starts storing an array\n            // just because free entry was switched on.\n            const val = (allowCustomValues && !isArrayValued && Array.isArray(raw))\n                ? (raw.length ? raw[raw.length - 1] : undefined)\n                : raw;\n            updateAndValidate(val);\n            // Changing this field can invalidate the rest of its group: an\n            // employer's recruiter, email, contact and VMS all describe the\n            // PREVIOUS employer, and leaving them behind silently attaches one\n            // company's details to another. Cleared BEFORE autofill below, so a\n            // new selection's own values are written straight back in.\n            if (field.clearGroupOnChange || field.linkedClearField) {\n                applyGroupClear(form, field, name, rowFieldKeys);\n            }\n            if (field.autofillFrom?.length) {\n                const selectedValue = val && !Array.isArray(val) && typeof val === 'object' ? val.value : val;\n                const isInsideList = Array.isArray(name) && name.length >= 3 && typeof name[1] === 'number';\n                if (val == null) {\n                    // Cleared — wipe all autofill targets\n                    field.autofillFrom.forEach(({ targetField: tf }) => {\n                        const tp = isInsideList\n                            ? [...name.slice(0, 2), ...namePathFromString(tf)]\n                            : namePathFromString(tf);\n                        form.setFieldValue(tp, null);\n                    });\n                } else if (rawLookupRef.current.length > 0) {\n                    const vField = field.valueField ?? '_id';\n                    const rawItem = rawLookupRef.current.find(item =>\n                        getNestedProp(item, vField) === selectedValue || item._id === selectedValue || item.id === selectedValue || item.value === selectedValue\n                    );\n                    if (rawItem) {\n                        field.autofillFrom.forEach(({ optionKey, targetField: tf }) => {\n                            const v = getNestedProp(rawItem, optionKey) ?? rawItem.extraData?.[optionKey] ?? null;\n                            const tp = isInsideList\n                                ? [...name.slice(0, 2), ...namePathFromString(tf)]\n                                : namePathFromString(tf);\n                            form.setFieldValue(tp, v);\n                        });\n                    }\n                }\n            }\n        };\n        return (\n            <>\n                <Select\n                    value={controlValue}\n                    labelInValue={keepLabel || undefined}\n                    allowClear\n                    // Every select is type-to-search. It used to be enabled only\n                    // for remote/lookup/group sources, so a static-option field\n                    // (Currency, Unit, Work Mode, Status…) could only be picked\n                    // by scrolling — painful once a list runs to 30 entries, as\n                    // Relevant Experience does. Local lists filter on the LABEL\n                    // (optionFilterProp); remote ones keep filterOption=false\n                    // because the server already filtered.\n                    // `field.showSearch: false` turns it off for a specific field.\n                    showSearch={field.showSearch !== false}\n                    optionFilterProp=\"label\"\n                    filterOption={remoteSearch ? false : undefined}\n                    disabled={disabled}\n                    loading={optionsLoading}\n                    mode={effectiveSelectMode}\n                    tokenSeparators={tokenSeparators}\n                    options={options}\n                    placeholder={placeholder}\n                    notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n                    onSearch={remoteLookup ? setLookupSearch : remoteMaster ? setMasterSearch : undefined}\n                    onChange={handleSelectChange}\n                    dropdownRender={quick.footer ? (menu) => (<>{menu}{quick.footer}</>) : undefined}\n                />\n                {quick.modal}\n            </>\n        );\n    }\n    if (type === 'radio') {\n        return (\n            <Radio.Group\n                value={value}\n                disabled={disabled}\n                options={options}\n                onChange={(e) => updateAndValidate(e.target.value)}\n            />\n        );\n    }\n    if (type === 'checkbox') {\n        if (options.length > 0) {\n            return (\n                <Checkbox.Group\n                    value={value}\n                    disabled={disabled}\n                    options={options}\n                    onChange={updateAndValidate}\n                />\n            );\n        }\n        return (\n            <Checkbox\n                checked={Boolean(checked ?? value)}\n                disabled={disabled}\n                onChange={(e) => {\n                    const next = e.target.checked;\n                    // Region gate: some markets do not accept an entry that is\n                    // still in progress. The tick is REVERSED rather than left\n                    // standing with an error underneath — leaving it ticked\n                    // invites the user to try to submit and be refused twice.\n                    if (next && onRegionBlocked?.(field)) return;\n                    updateAndValidate(next);\n                    // Ticking \"still ongoing\" makes this the most recent entry,\n                    // so it may now belong at the top of a newest-first list.\n                    if (next) onRowOrderChange?.(field, name);\n                    if (field.linkedClearField && next) {\n                        const clearPath = Array.isArray(name) && name.length > 1\n                            ? [...name.slice(0, -1), field.linkedClearField]\n                            : [field.linkedClearField];\n                        form.setFieldValue(clearPath, null);\n                    }\n                }}\n            >\n                {field.checkboxLabel ?? field.label}\n            </Checkbox>\n        );\n    }\n    if (type === 'text-editor') {\n        return (\n            <>\n                <TipTapEditor\n                    value={value ?? form.getFieldValue(name) ?? ''}\n                    disabled={disabled}\n                    placeholder={placeholder}\n                    onChange={(html) => {\n                        if (validatorCfg) {\n                            const { error } = applyInputValidator(html, validatorCfg, 'change');\n                            setInputError(error);\n                        }\n                        updateAndValidate(html);\n                    }}\n                />\n                {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n            </>\n        );\n    }\n    if (type === 'textarea') {\n        return (\n            <>\n                <TextArea {...inputProps} rows={field.rows ?? 3} className=\"v1-scroll-textarea\" />\n                {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n            </>\n        );\n    }\n    if (type === 'date') {\n        return (\n            <DatePicker\n                disabled={disabled}\n                placeholder={placeholder}\n                style={{ width: '100%' }}\n                suffixIcon={<CalendarOutlined />}\n                value={value ?? null}\n                disabledDate={getDisabledDate(field, form, name)}\n                defaultPickerValue={getDefaultPickerValue(field)}\n                onChange={(date) => {\n                    updateAndValidate(date);\n                    // Dates are the other way a row becomes the most recent\n                    // one — the tick-box is not the only trigger.\n                    onRowOrderChange?.(field, name);\n                }}\n            />\n        );\n    }\n    if (type === 'time') return <TimePicker disabled={disabled} placeholder={placeholder} style={{ width: '100%' }} value={value ?? null} onChange={(time) => updateAndValidate(time)} />;\n    if (type === 'file') {\n        const fileRules = field.validations ?? field.validation ?? field.rules ?? [];\n        const fileTypeRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'fileType');\n        const fileSizeRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'fileSize');\n        const maxFilesRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'maxFiles');\n\n        // Admin \"Allowed Content\" category (field.accept) takes priority over the\n        // fine-grained fileType rule; 'any'/unset falls through to the rule.\n        const acceptCategory = uploadAcceptCategory(field);\n        const acceptTypes = acceptCategory\n            ? acceptCategory.exts.map((e) => `.${e}`).join(',')\n            : (fileTypeRule?.value\n                ? fileTypeRule.value.split(',').map((e) => `.${e.trim().replace(/^\\./, '')}`).join(',')\n                : undefined);\n        const maxSizeMB = fileSizeRule ? Number(fileSizeRule?.value ?? 5) : undefined;\n        // maxFiles validation rule takes top priority; otherwise use field.multiple/maxCount\n        // (set via admin panel toggle), falling back to single-file mode.\n        const maxFiles = maxFilesRule\n            ? Number(maxFilesRule?.value ?? 1)\n            : (truthy(field.multiple) ? (field.maxCount ?? 5) : 1);\n\n        const fileList = Array.isArray(value) ? value : [];\n        const canAddMore = fileList.length < maxFiles;\n\n        const formatFileSize = (bytes) => {\n            if (!bytes) return '';\n            if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n            return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n        };\n\n        const getFileIcon = (fileName) => {\n            const ext = String(fileName ?? '').split('.').pop()?.toLowerCase();\n            if (ext === 'pdf') return <FilePdfOutlined className=\"v1-file-type-icon v1-file-icon-pdf\" />;\n            if (['doc', 'docx'].includes(ext)) return <FileWordOutlined className=\"v1-file-type-icon v1-file-icon-word\" />;\n            if (['xls', 'xlsx', 'csv'].includes(ext)) return <FileExcelOutlined className=\"v1-file-type-icon v1-file-icon-excel\" />;\n            if (['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'].includes(ext)) return <FileImageOutlined className=\"v1-file-type-icon v1-file-icon-image\" />;\n            return <FileOutlined className=\"v1-file-type-icon v1-file-icon-default\" />;\n        };\n\n        const handleFileDelete = (index) => {\n            updateAndValidate(fileList.filter((_, i) => i !== index));\n        };\n\n        const handleFileView = (file, fileIdx) => {\n            const docs = fileList.map((f) => {\n                let url = f.url ?? f.thumbUrl ?? '';\n                if (!url && f.originFileObj instanceof File) url = URL.createObjectURL(f.originFileObj);\n                return { url, name: f.name ?? 'file' };\n            }).filter(d => d.url);\n            setViewer({ open: true, docs, index: fileIdx ?? 0 });\n        };\n\n        const isMulti = maxFiles > 1;\n        const remaining = maxFiles - fileList.length;\n\n        const typeHint = acceptCategory\n            ? acceptCategory.hint\n            : (acceptTypes\n                ? acceptTypes.split(',').map((t) => t.replace('.', '').toUpperCase()).join(', ')\n                : null);\n        const sizeHint = maxSizeMB ? `up to ${maxSizeMB} MB` : null;\n        const baseHint = [typeHint, sizeHint].filter(Boolean).join(' ');\n        const dropHint = isMulti && fileList.length > 0\n            ? [baseHint, `${remaining} of ${maxFiles} remaining`].filter(Boolean).join(' • ')\n            : baseHint;\n        const dropTitle = fileList.length > 0\n            ? `Add ${isMulti ? 'more files' : 'file'}`\n            : (field.buttonLabel ?? `Upload ${field.label ?? 'File'}`);\n\n        const beforeUploadHandler = (file) => {\n            if (fileList.length >= maxFiles) return Upload.LIST_IGNORE;\n            if (acceptTypes) {\n                const ext = (file.name.split('.').pop() ?? '').toLowerCase();\n                const allowed = acceptTypes.split(',').map((t) => t.replace(/^\\./, '').toLowerCase());\n                if (!allowed.includes(ext)) {\n                    message.error(acceptCategory\n                        ? acceptCategory.error\n                        : (fileTypeRule?.message ?? `Only ${fileTypeRule.value} files are allowed`));\n                    return Upload.LIST_IGNORE;\n                }\n            }\n            if (maxSizeMB !== undefined && file.size / 1024 / 1024 > maxSizeMB) {\n                message.error(fileSizeRule?.message ?? `File must be smaller than ${maxSizeMB} MB`);\n                return Upload.LIST_IGNORE;\n            }\n            return false;\n        };\n\n        // antd calls onChange once per file even in multi-select, each time with the\n        // full accumulated newList. Slicing to maxFiles guards against racing additions.\n        const handleUploadChange = ({ fileList: newList }) => {\n            const sliced = newList.slice(0, maxFiles);\n            updateAndValidate(sliced);\n            // An \"upload\"-trigger AI action (e.g. auto-parse a resume) fires once\n            // per newly-added file, using the raw browser File object.\n            if (onAiUpload && sliced.length > fileList.length) {\n                const added = sliced[sliced.length - 1];\n                if (added?.originFileObj) onAiUpload(added.originFileObj);\n            }\n        };\n\n        const multiUploadProps = {\n            accept: acceptTypes,\n            fileList,\n            showUploadList: false,\n            multiple: true,\n            maxCount: maxFiles,\n            beforeUpload: beforeUploadHandler,\n            onChange: handleUploadChange,\n            disabled,\n        };\n\n        const fileRows = fileList.map((file, index) => (\n            <div key={file.uid ?? index} className=\"v1-file-item\">\n                <div className=\"v1-file-item-icon\">{getFileIcon(file.name)}</div>\n                <div className=\"v1-file-item-info\">\n                    <span className=\"v1-file-item-name\" title={file.name}>{file.name}</span>\n                    <span className=\"v1-file-item-meta\">\n                        {file.existing\n                            ? 'Previously uploaded'\n                            : `${formatFileSize(file.size)}${file.size ? ' • ' : ''}Uploaded just now`}\n                    </span>\n                </div>\n                <Space size={6} className=\"v1-file-item-actions\">\n                    <Button\n                        size=\"small\"\n                        icon={<EyeOutlined />}\n                        onClick={() => handleFileView(file, index)}\n                        className=\"v1-file-view-btn\"\n                    >\n                        View\n                    </Button>\n                    <Button\n                        size=\"small\"\n                        danger\n                        icon={<DeleteOutlined />}\n                        onClick={() => handleFileDelete(index)}\n                        className=\"v1-file-delete-btn\"\n                    />\n                </Space>\n            </div>\n        ));\n\n        const viewerEl = (\n            <DocumentViewer\n                documents={viewer.docs}\n                open={viewer.open}\n                onClose={() => setViewer(v => ({ ...v, open: false }))}\n                initialIndex={viewer.index}\n            />\n        );\n\n        if (isMulti) {\n            const multiTitle = fileList.length > 0\n                ? `Upload more ${field.label ?? 'files'}`\n                : (field.buttonLabel ?? `Upload ${field.label ?? 'File'}`);\n\n            return (\n                <>\n                    <div className=\"v1-file-upload-wrapper\">\n                        {/* Centered dropzone — always at top in multiple mode */}\n                        {canAddMore && (\n                            <Upload {...multiUploadProps} style={{ width: '100%', display: 'block' }}>\n                                <div className={`v1-upload-dropzone v1-upload-dropzone-center${disabled ? ' v1-upload-dropzone-disabled' : ''}`}>\n                                    <div className=\"v1-upload-dropzone-title-row\">\n                                        <CloudUploadOutlined className=\"v1-upload-cloud-icon v1-upload-cloud-icon-sm\" />\n                                        <span className=\"v1-upload-dropzone-title v1-upload-dropzone-title-blue\">{multiTitle}</span>\n                                    </div>\n                                    <span className=\"v1-upload-dropzone-sub\">Drag & drop or click to upload</span>\n                                    {baseHint && <span className=\"v1-upload-dropzone-sub\">{baseHint}</span>}\n                                </div>\n                            </Upload>\n                        )}\n\n                        {/* Uploaded file rows — 2-column grid */}\n                        {fileList.length > 0 && (\n                            <div className=\"v1-file-grid\">\n                                {fileRows}\n                            </div>\n                        )}\n\n                        {/* \"+ Add more files\" text link at the bottom */}\n                        {canAddMore && fileList.length > 0 && (\n                            <Upload {...multiUploadProps} style={{ display: 'inline-block' }}>\n                                <Button type=\"link\" size=\"small\" icon={<PlusOutlined />} className=\"v1-add-more-files-btn\">\n                                    Add more files\n                                </Button>\n                            </Upload>\n                        )}\n                    </div>\n                    {viewerEl}\n                </>\n            );\n        }\n\n        return (\n            <>\n                <div className=\"v1-file-upload-wrapper\">\n                    {/* Single mode: compact file row at field height */}\n                    {fileList.length > 0 && <div className=\"v1-file-rows-single\">{fileRows}</div>}\n\n                    {canAddMore && (\n                        <Upload\n                            accept={acceptTypes}\n                            fileList={fileList}\n                            showUploadList={false}\n                            multiple={false}\n                            maxCount={1}\n                            beforeUpload={beforeUploadHandler}\n                            onChange={handleUploadChange}\n                            disabled={disabled}\n                            style={{ width: '100%', display: 'block' }}\n                        >\n                            <div className={`v1-upload-dropzone v1-upload-dropzone-single${disabled ? ' v1-upload-dropzone-disabled' : ''}`}>\n                                <CloudUploadOutlined className=\"v1-upload-cloud-icon\" />\n                                <span className=\"v1-upload-dropzone-title\">{dropTitle}</span>\n                                {dropHint && <span className=\"v1-upload-dropzone-sub\">— {dropHint}</span>}\n                            </div>\n                        </Upload>\n                    )}\n                </div>\n                {viewerEl}\n            </>\n        );\n    }\n\n    return (\n        <>\n            <Input\n                {...inputProps}\n                type={type === 'number' ? 'number' : type}\n                // step=\"any\" so the browser's own number input accepts a\n                // fractional value on a field the admin marked decimal.\n                {...(type === 'number' && truthy(field.decimal) ? { step: 'any' } : {})}\n                // Admin-configured unit shown inside the input (e.g. \"%\").\n                {...(field.suffix ? { suffix: field.suffix } : {})}\n            />\n            {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n        </>\n    );\n}\n\nfunction SectionTitle({ icon, title }) {\n    return (\n        <Space size={10} align=\"center\">\n            <div className=\"v1-section-icon-box\">{icon}</div>\n            <Text strong className=\"v1-section-label\">{title}</Text>\n        </Space>\n    );\n}\n\nfunction FieldLabel({ field, label, locked }) {\n    if (!label) return label;\n    // field.tooltip (admin config) OR the older infoEnabled/infoText pair — one\n    // resolver (fieldTooltipText) so both forms and every control type agree on\n    // where a field's help text comes from. The TEXT is always admin config.\n    const infoText = fieldTooltipText(field);\n    const showInfo = Boolean(infoText);\n    if (!showInfo && !locked) return label;\n    return (\n        <span className=\"v1-field-label-with-info\">\n            <span>{label}</span>\n            {showInfo && (\n                <Tooltip title={infoText}>\n                    <InfoCircleOutlined className=\"v1-field-info-icon\" />\n                </Tooltip>\n            )}\n            {locked && (\n                <Tooltip title=\"You don't have permission to edit this field\">\n                    <LockOutlined className=\"v1-field-info-icon\" />\n                </Tooltip>\n            )}\n        </span>\n    );\n}\n\nfunction GroupInfoMessage({ group }) {\n    if (!truthy(group?.infoEnabled) || empty(group?.infoText)) return null;\n    return <Text type=\"secondary\" className=\"v1-group-info-message\">{group.infoText}</Text>;\n}\n\nfunction GroupToggleControl({ group }) {\n    if (!truthy(group?.toggleEnabled) || empty(group?.toggleField)) return null;\n    return (\n        <Space size={6} align=\"center\" onClick={(event) => event.stopPropagation()}>\n            <Text type=\"secondary\" className=\"v1-combine-toggle-label\">{group.toggleLabel || 'Toggle'}</Text>\n            <Form.Item name={group.toggleField} valuePropName=\"checked\" initialValue={Boolean(group.toggleValue)} noStyle>\n                <Switch size=\"small\" />\n            </Form.Item>\n        </Space>\n    );\n}\n\n\n// renderFieldHelp — the guidance under a field.\n//\n// `helpText` accepts a STRING or an ARRAY of strings. An array renders as\n// stacked lines, which is what lets one field carry two different KINDS of\n// help without them running together: the mechanical constraint (\"Supports\n// .pdf, .doc, .docx up to 2MB\") and the reason to bother (\"Upload the résumé\n// first — we can read the details straight out of it\"). Jammed into one\n// paragraph they read as a wall and the second half is skipped.\n//\n// A plain string keeps rendering exactly as before, so nothing existing moves.\n// formatPrefillHint renders a previous value as one readable line.\n//\n// The label is admin config (`prefillHintLabel`, \"{value}\" substituted) so the\n// wording belongs to whoever configured the field, not to this file.\n//\n// A history container is the interesting case: an append-only field such as\n// candidateBudget stores an ARRAY of stamped entries, and the one worth showing\n// is the LAST. Rendering the raw array would print \"[object Object]\", which is\n// worse than showing nothing.\nfunction formatPrefillHint(field, stored) {\n    let value = stored;\n    if (Array.isArray(value)) value = value[value.length - 1];\n    if (value && typeof value === 'object') {\n        // Join the entry's meaningful leaves, skipping the audit stamps every\n        // history entry carries — they describe the WRITE, not the value.\n        const skip = new Set(['timestamp', 'updatedBy', 'updatedAt', 'createdAt', 'createdBy', '_id']);\n        const parts = Object.entries(value)\n            .filter(([k, v]) => !skip.has(k) && v !== null && v !== undefined && v !== ''\n                && typeof v !== 'object')\n            .map(([, v]) => String(v).trim())\n            .filter(Boolean);\n        if (!parts.length) return '';\n        value = parts.join(' ');\n    }\n    const text = String(value ?? '').trim();\n    if (!text) return '';\n    const label = String(field?.prefillHintLabel ?? 'Last recorded: {value}');\n    return label.includes('{value}') ? label.replace('{value}', text) : `${label} ${text}`;\n}\n\n// hint is an extra line appended under the field — used by `prefillAsHint`\n// (see the prefill effect) to SHOW a previous value instead of filling it in.\nfunction renderFieldHelp(field, hint) {\n    const raw = field?.helpText;\n    const lines = (Array.isArray(raw) ? raw : [raw])\n        .map((line) => (line == null ? '' : String(line).trim()))\n        .filter(Boolean);\n    if (hint) lines.push(hint);\n    if (!lines.length) return undefined;\n    return (\n        <span className=\"v1-field-help-text\">\n            {lines.map((line, i) => (\n                <Text key={i} type=\"secondary\" className=\"v1-field-help-line\">{line}</Text>\n            ))}\n        </span>\n    );\n}\n\n// forwardRef, not a plain `ref` prop: this package declares `react >=18` as its\n// peer, and on React 18 a function component does not receive `ref` as a prop.\n// React 19 no longer needs the wrapper but still honours it, so this is the one\n// form that works across the whole supported range.\n//\n// Exported inline rather than via a `const AddFormV1 = forwardRef(...)` binding:\n// a const of the same name shadows the render function, and the transform then\n// renames the inner one (\"AddFormV12\"), which is what DevTools and every error\n// stack would go on to display.\nexport default forwardRef(function AddFormV1({\n    moduleName,\n    action,\n    authToken,\n    clientId,\n    region,\n    formGroups: providedFormGroups,\n    loading: providedLoading = false,\n    error: providedError = '',\n    breadcrumbItems = [],\n    // formType — controls the mode of operation:\n    //   'add'    → Add Form (default, existing behavior)\n    //   'search' → Search Form (lighter validation, Reset button, no auto-create)\n    formType = 'add',\n    submitText: propSubmitText,\n    cancelPath = '/candidates',\n    onSubmit,\n    // initialRecord — prefill flat form fields from a plain record object.\n    // Matched by field.field / payloadKey / dot-path; best-effort, never required.\n    initialRecord = null,\n    // prefillFromUrl — when set (quickSubmit flow), AddFormV1 reads the route to\n    // decide the prefill source and the job/candidate linkage entirely on its own:\n    //   • isFromSubmission=true + submissionId → read the submissions collection\n    //   • otherwise candidateId                → read the candidates collection\n    // Both resolve through getFormGroups(id) (field.value + group.rows embedded) —\n    // no separate detail-view API. The linkage the submission create requires\n    // (applicantId + jobId) is derived from the same URL params.\n    prefillFromUrl = false,\n    // extraPayload — context/linkage keys merged into the create payload that are\n    // NOT form fields (e.g. submission needs { jobId, applicantId }). Kept out of\n    // the form so the config stays generic. Ignored when prefillFromUrl derives\n    // its own linkage from the route.\n    extraPayload = null,\n    // presetClientId — caller already knows the client (e.g. Quick Submit knows\n    // it from the selected job) so the client-scope gate should resolve silently\n    // instead of showing the manual \"Select Client\" picker.\n    presetClientId = null,\n    // ListView props for search mode — passed through from parent when search results\n    // should be displayed below the search form.\n    listViewProps = {},\n    // selectedScope — optional scope parameter for filtering search results\n    selectedScope = '',\n    // searchActionContext — page-level context (e.g. { jobId }) merged into every\n    // search-result row action's popupState, so a popup opened from here (like\n    // Source Candidates' \"Shortlisted\"/\"Tag to Jobs\") already knows what the\n    // caller knows instead of asking the user to re-select it. Mirrors the\n    // action.popupState convention ListView already spreads into the popup's\n    // navigation state — see ListView.jsx's handleActionClick.\n    searchActionContext = null,\n    // embedded — render the form for use inside a modal (quick \"Add More\" from a\n    // select dropdown). Suppresses page chrome/navigation; on a successful create\n    // onSuccess(newRecordId, values) is called instead of navigating away, and the\n    // Cancel button calls onCancel. Entirely opt-in; the standalone page path is\n    // unchanged when embedded is false.\n    embedded = false,\n    onSuccess = null,\n    onCancel = null,\n}, ref) {\n    useEffect(() => {\n        if (authToken) setAuthTokenOverride(authToken);\n        return () => {\n            if (authToken) clearAuthTokenOverride();\n        };\n    }, [authToken]);\n\n    const isSearch = formType === 'search';\n    const submitText = propSubmitText ?? (isSearch ? 'Search' : 'Create');\n    const navigate = useNavigate();\n    // Router location — nav state carries the in-flight relevant-skill match\n    // handed over by Quick Submit (see the prefill effect below).\n    const routerLocation = useLocation();\n    // Cache for the relevant-skill match promise, keyed by its token — see the\n    // prefill effect below and services/pendingHandoff.js.\n    const skillMatchTokenRef = useRef(null);\n    const skillMatchPromiseRef = useRef(null);\n    const routeParams = useParams();\n    const [searchParams] = useSearchParams();\n    const [form] = Form.useForm();\n\n    // ── Imperative handle ───────────────────────────────────────────────────\n    // Lets a host drive the form from outside it — submit it from its own\n    // button, validate before advancing a wizard step, read the current values\n    // for a preview, or reset it after a modal closes.\n    //\n    // Deliberately only these four. Exposing `form` itself would hand callers\n    // the entire antd API, including setFieldsValue — and a host writing\n    // directly into the store bypasses every conditional default, payload gate\n    // and linked-clear rule this component maintains, in ways nothing here\n    // could see or correct.\n    //\n    // submit() goes through form.submit() rather than calling the submit\n    // handler, so an imperative submit runs validation, the duplicate gate and\n    // the after-submit navigation exactly as pressing the button does.\n    useImperativeHandle(ref, () => ({\n        submit: () => form.submit(),\n        validate: () => form.validateFields(),\n        getValues: () => form.getFieldsValue(true),\n        reset: () => form.resetFields(),\n    }), [form]);\n\n    const searchFormValues = Form.useWatch([], form);\n    const [searchLoading, setSearchLoading] = useState(false);\n    const [collapsed, setCollapsed] = useState({});\n    const [apiFormGroups, setApiFormGroups] = useState([]);\n    const [apiLoading, setApiLoading] = useState(Boolean(moduleName));\n    const [apiError, setApiError] = useState('');\n    const [searchFormLabel, setSearchFormLabel] = useState('');\n    const [submitLoading, setSubmitLoading] = useState(false);\n    // Search results state — used when formType === 'search' to store and display results\n    const [searchResults, setSearchResults] = useState({\n        searched: false,\n        rows: [],\n        total: 0,\n        fields: [],\n        actions: [],\n        actionRules: [],\n        loading: false,\n    });\n    const [searchPagination, setSearchPagination] = useState({ current: 1, pageSize: 10 });\n    const [lastSearchValues, setLastSearchValues] = useState({});\n    const [selectedSource, setSelectedSource] = useState('internal');\n    const [tabs, setTabs] = useState([]);\n    const [sourceActionState, setSourceActionState] = useState({});\n    const [clientOptions, setClientOptions] = useState([]);\n    const [scopeClientId, setScopeClientId] = useState(clientId ?? '');\n    const [scopeRegion, setScopeRegion] = useState(region ?? '');\n    // URL-driven prefill state — populated when prefillFromUrl is set. Holds the\n    // source record's form groups (candidate OR submission) with values embedded.\n    const [prefillGroups, setPrefillGroups] = useState(null);\n    const [prefillLoading, setPrefillLoading] = useState(false);\n    // Role Configure → Form permissions for the CURRENT user's role, derived\n    // server-side from this module's Form Groups config (see\n    // GetRoleFormPermissions). null until loaded / when unavailable, in which\n    // case normalizeGroups' rolePerms checks fail open — no behavior change\n    // for a role/module that hasn't been configured.\n    const [rolePerms, setRolePerms] = useState(null);\n    // Default Fields (Form Groups → Default Fields) — always-shown + required\n    // field keys for this module. Empty set until loaded / when unconfigured.\n    const [defaultFieldSet, setDefaultFieldSet] = useState(() => new Set());\n    const formGroups = moduleName ? apiFormGroups : (providedFormGroups ?? emptyGroups);\n    const loading = moduleName ? apiLoading : providedLoading;\n    const error = moduleName ? apiError : providedError;\n    // ── Client-scoped form render, resolved from the linked JOB ──────────────\n    // A submission is always created against a job, and the job owns the client.\n    // So when the form is opened with a jobId (/submission-create/:jobId, Quick\n    // Submit, Source Candidates…) we look the job up, read its clientId, and use\n    // it as THIS form's client scope. getFormGroups then returns the client's\n    // Form Groups variant when the admin has configured one for that client, and\n    // transparently falls back to the module default when they haven't (the\n    // backend tries clientId+region → clientId → region → default), so this is\n    // safe for every client that has no override.\n    const [linkedClientId, setLinkedClientId] = useState('');\n    const linkedJobId = (routeParams?.jobId && routeParams.jobId !== '_')\n        ? routeParams.jobId\n        : (searchParams.get('jobId') || '');\n\n    useEffect(() => {\n        // An explicit client from the caller always wins — nothing to resolve.\n        if (clientId || presetClientId || !linkedJobId) return undefined;\n        let cancelled = false;\n        (async () => {\n            try {\n                const data = await getFormGroups({ module: 'jobs', id: linkedJobId });\n                const record = flatRecordFromGroups(extractGroups(data)) ?? {};\n                // A reference field comes back either as a raw id or {id,value}.\n                const raw = record.clientId ?? record.client ?? '';\n                const resolved = (raw && typeof raw === 'object') ? (raw.id ?? raw.value ?? '') : raw;\n                if (!cancelled && resolved) setLinkedClientId(String(resolved));\n            } catch (err) {\n                console.error('Client-scope resolve from job failed:', err);\n            }\n        })();\n        return () => { cancelled = true; };\n    }, [clientId, presetClientId, linkedJobId]);\n\n    const effectiveClientId = clientId || presetClientId || linkedClientId || scopeClientId;\n    const effectiveRegion = region || scopeRegion;\n\n    // Load the common display defaults (phone format, date format, …) once so a\n    // phone field re-formats to the admin-configured mask. Cached; safe to call.\n    useEffect(() => { loadDetailDefaults(); }, []);\n\n    useEffect(() => {\n        let cancelled = false;\n        queueMicrotask(() => {\n            if (cancelled) return;\n            if (!moduleName) { setRolePerms(null); return; }\n            // Same client/region scope the form's own structure is fetched\n            // with (getFormGroups below) — a client-scoped Form Groups\n            // override must gate the SAME scoped structure, not the\n            // tenant-wide default.\n            getRoleFormPermissions({ roleId: localStorage.getItem('roleId') }, moduleName, { clientId: effectiveClientId, region: effectiveRegion })\n                .then((data) => { if (!cancelled) setRolePerms(Array.isArray(data) && data.length ? data : null); })\n                .catch(() => { if (!cancelled) setRolePerms(null); });\n        });\n        return () => { cancelled = true; };\n    }, [moduleName, effectiveClientId, effectiveRegion]);\n\n    useEffect(() => {\n        let cancelled = false;\n        queueMicrotask(() => {\n            if (cancelled) return;\n            if (!moduleName) { setDefaultFieldSet(new Set()); return; }\n            getModuleDefaultFields(moduleName)\n                .then((keys) => { if (!cancelled) setDefaultFieldSet(new Set(Array.isArray(keys) ? keys : [])); })\n                .catch(() => { if (!cancelled) setDefaultFieldSet(new Set()); });\n        });\n        return () => { cancelled = true; };\n    }, [moduleName]);\n\n    const groups = useMemo(() => normalizeGroups(formGroups, moduleName, rolePerms, defaultFieldSet), [formGroups, moduleName, rolePerms, defaultFieldSet]);\n\n    // ── Config-driven field uniqueness ──────────────────────────────────────\n    // One checker per form session owns the request sequence, the\n    // normalized-value cache and the pending count (see\n    // form/uniqueFieldValidation.js). While a check is in flight the submit\n    // button is disabled so a record can never be created on a value whose\n    // answer has not come back yet. A search form never checks uniqueness.\n    const [uniquePending, setUniquePending] = useState(0);\n    const uniqueChecker = useMemo(\n        () => createUniqueChecker({ checkFieldUnique, onPendingChange: setUniquePending }),\n        [],\n    );\n    const uniqueContext = useMemo(() => (isSearch ? undefined : {\n        checker: uniqueChecker,\n        module: moduleName,\n        clientId: effectiveClientId || undefined,\n        region: effectiveRegion || undefined,\n        // NO recordId on the Add form — there is no record to exclude yet.\n    }), [isSearch, uniqueChecker, moduleName, effectiveClientId, effectiveRegion]);\n    // Every unique-configured field in this form, used to map a submit-time\n    // duplicate back onto its field when the response body was flattened.\n    const uniqueRuleIndex = useMemo(() => collectUniqueRules(groups), [groups]);\n\n    // group.linkGroup — addRow groups sharing the same value stay row-synced\n    // (see form/linkedAddRowGroups.js). Empty for every group with no\n    // linkGroup, i.e. every group that predates this feature.\n    const linkedGroupSets = useMemo(() => computeLinkedSets(groups), [groups]);\n    // Registry of each addRow group's live Form.List {add, remove}, written on\n    // every render from inside the Form.List's own render-prop (synchronous\n    // within the same commit, so it's fully populated before a user can click\n    // anything). A linked group's \"Add Row\" / row-delete calls every member's\n    // add()/remove() through this registry; unlinked groups just call their own.\n    const listControlsRef = useRef({});\n    // When an ADDITIONAL submit button (group.formActions, e.g. \"Create and\n    // Source Candidate\") is clicked, it stashes its own afterSubmit here so the\n    // shared submit() navigates per that button instead of the group default.\n    // Reset after every submit and by the plain Create button.\n    const pendingAfterSubmitRef = useRef(null);\n    const formActions = useMemo(() => groups.flatMap((g) => g.formActions ?? []), [groups]);\n    // \"Have we got this person already?\" — asked right after a résumé fills the\n    // form in (the first moment an email/phone exist to check), and again on\n    // submit as the authoritative gate. Config-driven; a module with no\n    // duplicate stages configured never sees any of it.\n    const duplicateConfig = useMemo(() => {\n        const groupWithConfig = extractGroups(formGroups).find((g) => g?.duplicateCheck);\n        return groupWithConfig?.duplicateCheck ?? {};\n    }, [formGroups]);\n\n    const duplicates = useDuplicateCheck({\n        form,\n        moduleName,\n        config: duplicateConfig,\n        // Choosing \"update the existing record\" hands off to that record's Edit\n        // form, carrying the file just uploaded so it is stored as another\n        // version rather than being lost with the abandoned Add form.\n        // The edit route is CONFIG, never guessed. There is no derivable rule:\n        // this app routes candidates at \"/candidate/edit/:id\" (singular) and\n        // clients at \"/clients/edit/:id\" (plural). Deriving it sent every\n        // candidate to \"/candidates/edit/:id\", which matches no route, so the\n        // catch-all redirected to the dashboard — the record the user asked to\n        // open simply vanished.\n        //\n        // With no route configured we do NOT navigate. Closing the dialog and\n        // leaving the user where they are is recoverable; throwing them at a\n        // wrong URL is not.\n        onUseExisting: useCallback((id, result, reason, carry) => {\n            if (!id) return;\n            // The backend delivers the configured route WITH the answer, so\n            // there is one source of truth; the group-level value is only an\n            // override for a project that wants a different destination.\n            const template = result?.editRoute || duplicateConfig?.editRoute;\n            if (!template) {\n                console.warn(\n                    `[duplicate-check] ${moduleName}: no editRoute configured, so the existing `\n                    + 'record was not opened. Set it in Admin → Automations → \"Check for someone '\n                    + 'already on file\" → \"Where to open the existing record\".',\n                );\n                return;\n            }\n            const target = safeNavTarget(template, id, {});\n            if (!target) return;\n            // The uploaded file travels WITH the user. They picked that résumé\n            // for that person; sending them to the existing record and quietly\n            // dropping it would make them find and attach it again — and the\n            // whole point of opening the existing record is to add this newer\n            // file to it (file versioning keeps the previous one).\n            navigate(target, {\n                state: {\n                    fromDuplicate: true,\n                    carryFiles: carry?.files ?? null,\n                },\n            });\n        }, [duplicateConfig, navigate]),\n    });\n\n    const aiActions = useAiActions({\n        form,\n        groups,\n        module: moduleName,\n        // BEFORE any parsed value reaches the form. This is the first moment an\n        // email and phone exist, so it is the first moment the question can be\n        // asked — and if we already have this person there is no point filling\n        // in a form the user is about to abandon.\n        onParsed: useCallback(async ({ field, payload }) => {\n            const key = field?.field;\n            // The file the user just picked, handed to the prompt so it can\n            // travel with them to the existing record.\n            const carry = key ? { files: { [key]: form.getFieldValue(key) } } : null;\n\n            const verdict = await duplicates.prompt({ reason: 'upload', payload, carry });\n            if (verdict === 'clear') return true;\n\n            // 'existing' — they were sent to the record we already have and the\n            // file went WITH them, so it must not also be left behind here.\n            // 'blocked' — they backed out to check; leaving the file attached to\n            // a form that was never filled in just means the next thing they do\n            // starts from a half-state they did not choose.\n            // Either way the upload is undone: nothing on this form was filled\n            // in, so nothing on it should look as though it was.\n            if (key) {\n                form.setFieldValue(key, []);\n                message.info(verdict === 'existing'\n                    ? 'Résumé moved to their record.'\n                    : 'Résumé removed — nothing on this form was filled in.');\n            }\n            return 'abort';\n        }, [duplicates, form]),\n        // AFTER the form is filled — a second, cheaper pass that also covers\n        // anything the user had typed before uploading.\n        onApplied: useCallback(async () => {\n            await duplicates.prompt({ reason: 'upload' });\n        }, [duplicates]),\n    });\n\n    // Blur on a field marked `checkDuplicateOnBlur` (the email box). Debounced\n    // through a ref rather than fired directly: tabbing quickly through a form\n    // can blur the same field twice, and two overlapping checks would open two\n    // dialogs on top of each other.\n    // ── Region gate ─────────────────────────────────────────────────────────\n    // The active region (Admin → Detail Groups → Display Defaults → Region)\n    // selects which `regionRules` block each group applies. A region is a KEY\n    // into config, never a branch in code — which is what lets a new market be\n    // added without touching this file.\n    //\n    // Today's use: a candidate may be put forward mid-course in the US and UK,\n    // but not in India, where a company only accepts a completed qualification.\n    const handleRegionBlocked = useCallback((field) => {\n        const region = getDefaults().region;\n        // Find the group this \"still ongoing\" tick-box belongs to, so its own\n        // region rules decide — not some global setting.\n        const group = groups.find((g) => (g.fields ?? []).some((f) => f.field === field.field));\n        if (!group) return false;\n\n        const effective = resolveRegionRules(group, region);\n        // Only gates the field the group nominates as its ongoing flag, so an\n        // unrelated checkbox in the same group is never caught by this.\n        const ongoingField = effective.orderBy?.inProgressField ?? 'currentStudyingHere';\n        if (field.field !== ongoingField) return false;\n        if (inProgressAllowed(effective)) return false;\n\n        // Warn vs block. A warning explains the consequence and lets the tick\n        // stand — recording a real person mid-degree is worth doing even where\n        // they could not be put forward today. A block reverses the tick, and\n        // the submit-time validator below refuses the row however it arrived.\n        const blocking = inProgressBlocks(effective);\n        openFormNotice({\n            tone: blocking ? 'duplicate' : 'overwrite',\n            title: blocking\n                ? 'This has to be completed first'\n                // States the CONSEQUENCE, not a vague heading. The user's next\n                // action depends on knowing that saving this is fine but\n                // submitting them later will not be.\n                : 'You can add this, but they cannot be submitted',\n            facts: [\n                { label: 'Region', value: region || 'Common' },\n                { label: 'Entry', value: group.label ?? group.name },\n            ],\n            body: inProgressError(effective),\n            okText: blocking ? 'Got it' : 'Keep it anyway',\n        });\n        return blocking;\n    }, [groups]);\n\n    // ── The submit-time half of the same rule ───────────────────────────────\n    // Reversing the tick-box only catches a row somebody ticked BY HAND. A\n    // submission prefills its rows from the candidate, and the candidate is\n    // allowed to hold an in-progress entry — so on a blocking region the row\n    // arrives already ticked and nobody ever touched the box. Without a rule on\n    // the field the form would happily submit it, and the restriction would\n    // apply to exactly the users who did not need stopping.\n    //\n    // Resolved here rather than inside getRules because it depends on the\n    // GROUP, which getRules never sees.\n    const inProgressRulesFor = useCallback((field, groupName) => {\n        const group = groups.find((g) => g.name === groupName);\n        if (!group) return undefined;\n        const effective = resolveRegionRules(group, getDefaults().region);\n        const ongoingField = effective.orderBy?.inProgressField ?? 'currentStudyingHere';\n        if (field.field !== ongoingField) return undefined;\n        const rule = buildInProgressValidator(effective);\n        return rule ? [rule] : undefined;\n    }, [groups]);\n\n\n    // ── Newest-first row ordering ───────────────────────────────────────────\n    // After the user changes a row's dates or ticks \"still ongoing\", check\n    // whether that row now belongs somewhere else and ASK. Nothing is ever\n    // reordered silently — a list that rearranges itself while you are typing\n    // in it is disorienting, and the user may have a reason for the order.\n    const handleRowOrder = useCallback(async (field, name) => {\n        // Only meaningful inside a repeatable group: [listName, rowIndex, key].\n        if (!Array.isArray(name) || name.length < 3 || typeof name[1] !== 'number') return;\n        const groupName = name[0];\n        const rowIndex = name[1];\n\n        const group = groups.find((g) => g.name === groupName);\n        if (!group) return;\n        // Region-resolved, so a market that reorders differently is honoured.\n        const effective = resolveRegionRules(group, getDefaults().region);\n        if (!effective.orderBy) return;\n\n        // Read AFTER the change has landed in the store, so the row being\n        // judged carries the value the user just set rather than the previous\n        // one — the whole decision turns on that value.\n        await Promise.resolve();\n        const rows = form.getFieldValue(groupName);\n        if (!Array.isArray(rows)) return;\n\n        await promptRowMove({\n            group: effective,\n            rows,\n            rowIndex,\n            move: listControlsRef.current[groupName]?.move,\n            confirm: ({ title, body, okText, cancelText, from, to }) => openFormDecision({\n                tone: 'suggestion',\n                title,\n                facts: [\n                    { label: 'This entry is at', value: `Row ${from + 1}` },\n                    { label: 'It belongs at', value: `Row ${to + 1}` },\n                ],\n                body,\n                okText,\n                cancelText,\n            }),\n        });\n    }, [groups, form]);\n\n    const duplicateBlurRef = useRef(false);\n    const handleDuplicateBlur = useCallback(async () => {\n        if (duplicateBlurRef.current) return;\n        duplicateBlurRef.current = true;\n        try {\n            await duplicates.prompt({ reason: 'blur' });\n        } finally {\n            duplicateBlurRef.current = false;\n        }\n    }, [duplicates]);\n    const [viewMode, setViewMode] = useState(\"list\");\n    const searchDisabled = isSearch && !hasSearchCriteria(searchFormValues);\n\n    // Scan raw formGroups (before normalizeGroups strips the clientScope field) to\n    // auto-detect whether this module needs a client gate and read its optional message.\n    // The Admin field config is the only source that enables this gate.\n    const { hasClientScope, clientGateMessage, clientGateResetOnChange } = useMemo(() => {\n        const gateField = extractGroups(formGroups).flatMap(g => g.fields ?? []).find(f => truthy(f.clientScope));\n        return gateField\n            ? {\n                hasClientScope: true,\n                clientGateMessage: gateField.clientGateMessage || '',\n                clientGateResetOnChange: truthy(gateField.clientGateResetOnChange),\n            }\n            : { hasClientScope: false, clientGateMessage: '', clientGateResetOnChange: false };\n    }, [formGroups]);\n\n    const handleClientGateChange = (nextClientId) => {\n        if (clientGateResetOnChange) {\n            form.resetFields();\n            // resetFields restores configured initial/default values. Explicitly\n            // clear every root key as well so changing the Client Gate truly\n            // removes nested values, files and repeatable-group rows.\n            const storedValues = form.getFieldsValue(true);\n            form.setFieldsValue(Object.fromEntries(\n                Object.keys(storedValues).map((fieldName) => [fieldName, undefined]),\n            ));\n            setSearchResults({ searched: false, rows: [], total: 0, fields: [], loading: false });\n            setSearchPagination({ current: 1, pageSize: 10 });\n        }\n        setScopeClientId(nextClientId ?? '');\n    };\n\n    const waitingForClientScope = hasClientScope && !effectiveClientId;\n\n    const loadClientOptions = useCallback(() => (\n        getAdminClients({ limit: 200 }).then(setClientOptions).catch(() => setClientOptions([]))\n    ), []);\n\n    useEffect(() => {\n        // No picker needed when the client is already known (caller-supplied or\n        // resolved from the linked job).\n        if (!hasClientScope || presetClientId || linkedClientId) return;\n        loadClientOptions();\n    }, [hasClientScope, presetClientId, linkedClientId, loadClientOptions]);\n\n    // Quick-create hook for the \"Select Client\" gate — the same \"Add More\"\n    // in-dropdown create used by ordinary lookup fields (useQuickField), so the\n    // gate can open the Clients Add form in a modal and, on save, refetch the\n    // options and select the new client. Reuses the generic clients Add flow.\n    //\n    // NOTE — this synthetic field object is HARDCODED (a pre-existing wart: the\n    // client gate is rendered by this component rather than as an ordinary\n    // configured field, so it has no admin field-config document to read).\n    // Every OTHER field gets the same behaviour purely from admin config via the\n    // generic `quickCreateNotice` key; only this one gate has to restate it in\n    // code. The gate is the actual submission/job path the requirement is about,\n    // so it must carry the notice too — leaving it out would mean the one flow\n    // the product owner described was the one flow without the warning.\n    const clientGateQuick = useQuickField({\n        field: {\n            field: 'clientId',\n            quickCreate: true,\n            quickCreateModule: 'clients',\n            quickCreateLabel: 'Add Client',\n            lookupCollection: 'clients',\n            displayField: 'clientName',\n            quickCreateNotice: {\n                enabled: true,\n                title: 'New Client Created',\n                // message omitted on purpose — the built-in default IS the\n                // product-owner-approved wording (see quickCreateNotice.js).\n                showCreator: true,\n                showRecordName: true,\n                recordLabel: 'Client name',\n                creatorLabel: 'Created by',\n            },\n        },\n        form,\n        name: 'clientId',\n        moduleName,\n        scopeValues: {},\n        ownValue: effectiveClientId,\n        onDone: (kind, newId) => {\n            loadClientOptions();\n            if (kind === 'create' && newId != null) handleClientGateChange(String(newId));\n        },\n    });\n\n    useEffect(() => {\n        if (!moduleName) return undefined;\n\n        let cancelled = false;\n\n        async function fetchFormGroups() {\n            try {\n                setApiLoading(true);\n                setApiError('');\n                const data = isSearch\n                    ? await getCustomForms(moduleName, 'search', action)\n                    : await getFormGroups({ module: moduleName, action, clientId: effectiveClientId, region: effectiveRegion });\n                if (!cancelled) {\n                    setApiFormGroups(extractGroups(isSearch ? data?.[0] : data));\n                    if (isSearch) setSearchFormLabel(data?.[0]?.label || '');\n                }\n            } catch (err) {\n                console.error(`Failed to fetch ${moduleName} form groups:`, err);\n                if (!cancelled) setApiError(err?.message || 'Failed to fetch form groups');\n            } finally {\n                if (!cancelled) setApiLoading(false);\n            }\n        }\n\n        fetchFormGroups();\n\n        return () => {\n            cancelled = true;\n        };\n    }, [moduleName, action, isSearch, effectiveClientId, effectiveRegion]);\n\n    // ── URL-driven prefill source + linkage ──\n    // Decode the route once. The submission flow arrives at\n    //   /submission-create/:jobId?candidateId=…&isFromSubmission=…[&submissionId=…]\n    //   • isFromSubmission=true + submissionId → prefill from the submissions record\n    //   • otherwise candidateId                → prefill from the candidates record\n    const urlPrefill = useMemo(() => {\n        if (!prefillFromUrl) return null;\n\n        const candidateId = searchParams.get('candidateId') || '';\n        const submissionId = searchParams.get('submissionId') || '';\n        const fromSubmission = String(searchParams.get('isFromSubmission')) === 'true';\n        const jobId = (routeParams.jobId && routeParams.jobId !== '_')\n            ? routeParams.jobId\n            : (searchParams.get('jobId') || '');\n\n        const source = (fromSubmission && submissionId)\n            ? { module: 'submissions', id: submissionId }\n            : (candidateId ? { module: 'candidates', id: candidateId } : null);\n\n        // Linkage the submission create requires (NOT form fields).\n        const linkage = {};\n        if (candidateId) linkage.applicantId = candidateId;\n        if (jobId) linkage.jobId = jobId;\n\n        return { source, linkage: Object.keys(linkage).length ? linkage : null };\n    }, [prefillFromUrl, searchParams, routeParams]);\n\n    // ── Prefill fetch: load the source record's form groups with embedded values ──\n    // The backend embeds field.value for scalar fields and group.rows for addRow\n    // groups (workExperience, educationDetails, documents). Single source of truth\n    // for BOTH the candidate and submission flows — no detail-view API call.\n    useEffect(() => {\n        const source = urlPrefill?.source;\n        if (!source) return undefined;\n\n        let cancelled = false;\n\n        async function fetchPrefill() {\n            try {\n                setPrefillLoading(true);\n                const data = await getFormGroups({ module: source.module, id: source.id });\n                if (!cancelled) setPrefillGroups(extractGroups(data));\n            } catch (err) {\n                console.error('Failed to fetch prefill data:', err);\n                if (!cancelled) setPrefillGroups([]);\n            } finally {\n                if (!cancelled) setPrefillLoading(false);\n            }\n        }\n\n        fetchPrefill();\n\n        return () => { cancelled = true; };\n    }, [urlPrefill]);\n\n    // addRow rows from the prefill source, keyed by group.payloadKey (e.g.\n    // \"workExperience\"). Submission addRow groups that share the same payloadKey\n    // receive these rows as their Form.List initialValue at mount. Works for both\n    // sources because the DB array element keys are identical (companyName,\n    // jobTitle, qualification, …).\n    const addRowPrefillsByKey = useMemo(() => {\n        if (!prefillGroups) return {};\n        return Object.fromEntries(\n            prefillGroups\n                .filter(g => g.addRow && Array.isArray(g.rows) && g.rows.length > 0)\n                .map(g => [g.payloadKey || g.name, g.rows]),\n        );\n    }, [prefillGroups]);\n\n    // Flat record extracted from the prefill source's scalar fields — prefills\n    // form fields whose field.field (or payloadKey) matches a source field.\n    const prefillFlatRecord = useMemo(\n        () => flatRecordFromGroups(prefillGroups),\n        [prefillGroups],\n    );\n\n    // ── Cross-module context prefill (field.prefillFromModule) ──────────────\n    // A field may prefill from a DIFFERENT module's record than the default\n    // prefill source — e.g. submission.mspReqId ← the current JOB's mspreqId on\n    // Quick Submit. The admin sets prefillFromModule (which module) +\n    // prefillFrom (which key); the record id comes from the same URL linkage the\n    // create payload already uses (jobId → jobs, applicantId → candidates).\n    const contextPrefillModules = useMemo(() => {\n        const wanted = new Set();\n        groups.forEach((group) => (group.fields ?? []).forEach((field) => {\n            if (field.prefillFromModule) wanted.add(normalizeModule(field.prefillFromModule));\n        }));\n        return [...wanted];\n    }, [groups]);\n\n    const [contextRecords, setContextRecords] = useState({});\n    useEffect(() => {\n        const linkage = urlPrefill?.linkage;\n        if (!linkage || contextPrefillModules.length === 0) return undefined;\n        let cancelled = false;\n        // Shared with EditFormV1 (form/contextPrefill.js) — resolves <module>Id /\n        // <singular>Id (+ known aliases like applicantId) out of the id map,\n        // which is the URL linkage here and the record's own recordMeta there.\n        contextPrefillModules.forEach(async (mod) => {\n            const id = contextRecordId(mod, linkage);\n            if (!id) return;\n            try {\n                const data = await getFormGroups({ module: mod, id });\n                const record = flatRecordFromGroups(extractGroups(data));\n                if (!cancelled && record) {\n                    setContextRecords((prev) => ({ ...prev, [mod]: record }));\n                }\n            } catch (err) {\n                console.error(`Context prefill fetch failed for ${mod}:`, err);\n            }\n        });\n        return () => { cancelled = true; };\n    }, [contextPrefillModules, urlPrefill]);\n\n    // ── prefillAsHint ───────────────────────────────────────────────────────\n    // Fields the admin marked `prefillAsHint` are NOT filled in; the previous\n    // record's value is shown underneath instead. See the effect below, which\n    // skips them, and formatPrefillHint for the wording.\n    //\n    // DERIVED, not state written from an effect: it is a pure function of the\n    // source record and the config, so a memo needs no synchronisation and\n    // cannot render once with the old hints and once with the new.\n    const prefillHints = useMemo(() => {\n        const sourceRecord = initialRecord ?? prefillFlatRecord;\n        if (!sourceRecord && Object.keys(contextRecords).length === 0) return {};\n        const hints = {};\n        groups.forEach((group) => {\n            if (group.addRow) return;\n            (group.fields ?? []).forEach((field) => {\n                if (!field.field || !truthy(field.prefillAsHint) || truthy(field.addRow)) return;\n                const fieldSource = field.prefillFromModule\n                    ? contextRecords[normalizeModule(field.prefillFromModule)]\n                    : sourceRecord;\n                if (!fieldSource) return;\n                const stored = pickPrefillValue(fieldSource, field);\n                if (stored === undefined || stored === null) return;\n                const shown = formatPrefillHint(field, stored);\n                if (shown) hints[field.field] = shown;\n            });\n        });\n        return hints;\n    }, [initialRecord, prefillFlatRecord, contextRecords, groups]);\n\n    // ── Prefill from initialRecord / prefillFlatRecord (best-effort) ──\n    // Matches each non-file scalar field by field.field → payloadKey on the\n    // source record and sets it via setFieldsValue. addRow groups are seeded via\n    // Form.List initialValue (see getAddRowInitialValue below) — setFieldsValue\n    // on a Form.List that mounted empty only keeps the last row.\n    useEffect(() => {\n        const sourceRecord = initialRecord ?? prefillFlatRecord;\n        // Runs when EITHER the default source or a cross-module context record is\n        // ready — a form with only prefillFromModule fields (no candidate source,\n        // e.g. Quick Submit straight from a job) must still prefill those.\n        if ((!sourceRecord && Object.keys(contextRecords).length === 0)\n            || loading || groups.length === 0) return;\n        const values = {};\n        groups.forEach((group) => {\n            if (group.toggleEnabled && group.toggleField && sourceRecord) {\n                const stored = pickPrefillValue(sourceRecord, { field: group.toggleField });\n                if (stored !== undefined && stored !== null) values[group.toggleField] = Boolean(stored);\n            }\n            if (group.addRow) return;\n            (group.fields ?? []).forEach((field) => {\n                if (!field.field) return;\n                // A repeatable (addRow) field prefills via its Form.List\n                // initialValue at mount — setFieldsValue on a Form.List that\n                // mounted empty only keeps the last item, so skip it here.\n                if (truthy(field.addRow)) return;\n                // prefillFromModule redirects this field's source to another\n                // module's URL-linked record (e.g. the current job).\n                const fieldSource = field.prefillFromModule\n                    ? contextRecords[normalizeModule(field.prefillFromModule)]\n                    : sourceRecord;\n                if (!fieldSource) return;\n                // prefillFrom (admin config) → field → payloadKey, dotted or nested.\n                const stored = pickPrefillValue(fieldSource, field);\n                if (stored === undefined || stored === null) return;\n                // `prefillAsHint` (admin config): do NOT fill this field —\n                // show what it was last time and leave the box empty.\n                //\n                // A rate is the case this exists for. Carrying the previous\n                // submission's rate forward LOOKS helpful and is the opposite:\n                // it is a number the recruiter must renegotiate every time, and\n                // a prefilled one gets submitted unread. Shown as a hint they\n                // have to read and retype, it informs the decision instead of\n                // making it for them.\n                if (truthy(field.prefillAsHint)) return;\n                if (field.type === 'file') {\n                    const fl = toFileListValue(stored);\n                    if (fl.length > 0) writeFormValue(values, field.field, fl);\n                } else {\n                    // writeFormValue, NOT values[field.field]: a DOTTED field key\n                    // (\"candidateBudget.candidateBudgetCurrency\") is registered as an\n                    // ARRAY name path (see `field.field.split('.')` where `name` is\n                    // built), but a flat object key containing dots is treated by\n                    // rc-field-form as one literal field name. So the old assignment\n                    // wrote a key nothing was listening on, and prefillFromModule /\n                    // prefillFrom silently did NOTHING for every nested field — the\n                    // value was fetched, mapped, and then dropped on the floor.\n                    writeFormValue(values, field.field, buildInitialValue(field, stored));\n                }\n            });\n        });\n        if (Object.keys(values).length > 0) form.setFieldsValue(values);\n    }, [initialRecord, prefillFlatRecord, contextRecords, loading, groups, form]);\n\n    // ── Relevant-skill prefill (async, never blocking) ──────────────────────\n    // Quick Submit starts the match at SUBMIT time and hands a TOKEN for the\n    // still-in-flight promise over in nav state (the promise itself cannot\n    // travel through router state — history.pushState requires\n    // structured-cloneable data, and a Promise is not, see pendingHandoff.js).\n    // The request overlaps this form's mount instead of delaying it. When it\n    // settles we fill the rows of every addRow group the admin marked with\n    // `skillMatchField` — that config key names the field inside the row that\n    // receives the skill, so no group, field or module name is hardcoded here.\n    //\n    // Form.List rows must be written with setFieldsValue, never a remount: a\n    // key change would throw away anything the recruiter has already typed.\n    // Rows the user has already filled are left alone for the same reason.\n    //\n    // REFRESH SAFETY: history.state (and therefore the token) SURVIVES a browser\n    // reload, but the in-memory map the token points into does not — the SPA\n    // runtime that held it is gone. takePendingPromise then returns nothing and\n    // the rows silently never fill, which is exactly what QA saw: \"relevant\n    // skills are not parsed after a refresh\". So the INPUTS travel too, and when\n    // the token resolves to nothing we simply re-issue the match. Inputs come\n    // from nav state when the caller supplied them, else from the URL linkage\n    // this form already derives (jobId in the path, candidateId in the query) —\n    // which is itself refresh-proof. Still non-blocking, still driven only by\n    // group.skillMatchField.\n    useEffect(() => {\n        const token = routerLocation?.state?.relevantSkillsToken;\n        const stateInputs = routerLocation?.state?.relevantSkillsInputs;\n        const jobId = stateInputs?.jobId ?? urlPrefill?.linkage?.jobId ?? '';\n        const applicantId = stateInputs?.applicantId ?? stateInputs?.candidateId\n            ?? urlPrefill?.linkage?.applicantId ?? '';\n        // Guard on token/loading/groups BEFORE taking the promise — takePendingPromise\n        // deletes on read, so calling it before we're actually ready to use the\n        // result would consume it on a run that's just going to bail out, and\n        // every later run (once loading clears / groups arrive) would find nothing.\n        //\n        // A handoff is still REQUIRED to start a match: without a token (or\n        // explicit inputs in nav state) this is an ordinary visit to the form,\n        // not a Quick Submit, and must not fire an AI call on its own.\n        const handedOff = Boolean(token) || Boolean(stateInputs);\n        if (!handedOff || loading || groups.length === 0) return undefined;\n\n        const targets = groups.filter((g) => truthy(g.addRow) && g.skillMatchField);\n        if (targets.length === 0) return undefined;\n\n        // StrictMode double-invokes effects (mount → cleanup → mount again with\n        // identical deps). Re-taking on the second mount would find the token\n        // already consumed and silently skip the fill, so a same-token remount\n        // reuses the promise already taken instead of consuming again. The same\n        // ref also stops the refresh path from firing a SECOND match request on\n        // the double-invoke.\n        const runKey = token || `inputs:${jobId}:${applicantId}`;\n        let promise;\n        if (skillMatchTokenRef.current === runKey && skillMatchPromiseRef.current) {\n            promise = skillMatchPromiseRef.current;\n        } else {\n            promise = token ? takePendingPromise(token) : undefined;\n            // Handoff lost (page reloaded, or the link was opened directly) —\n            // re-issue from the inputs. matchRelevantSkills never rejects and\n            // degrades to [], which the fill below treats as \"change nothing\".\n            if ((!promise || typeof promise.then !== 'function') && jobId && applicantId) {\n                promise = matchRelevantSkills({ jobId, applicantId }).catch(() => []);\n            }\n            skillMatchTokenRef.current = runKey;\n            skillMatchPromiseRef.current = promise;\n        }\n        if (!promise || typeof promise.then !== 'function') return undefined;\n\n        let cancelled = false;\n        promise.then((skills) => {\n            // An empty result must NOT wipe the rows. \"Nothing matched\" and\n            // \"the service was unreachable\" arrive here identically, and\n            // clearing a candidate's carried-over skills because an AI call\n            // failed would destroy real data.\n            if (cancelled || !Array.isArray(skills) || skills.length === 0) return;\n            const values = {};\n            targets.forEach((group) => {\n                const existing = form.getFieldValue(group.name);\n                const rows = Array.isArray(existing) ? existing : [];\n                // REPLACE, not append: the rows carried over from the candidate\n                // are that candidate's skills in general, not the ones this job\n                // asks for. The match is the answer to \"which apply here\", so\n                // anything it did not return is dropped.\n                //\n                // A row whose skill IS in the match is REUSED rather than\n                // rebuilt, so its Experience/Remarks survive — replacing it\n                // with a bare { skill } would silently discard values the\n                // recruiter (or the candidate record) already supplied.\n                const bySkill = new Map();\n                rows.forEach((row) => {\n                    const key = String(row?.[group.skillMatchField] ?? '').trim().toLowerCase();\n                    if (key && !bySkill.has(key)) bySkill.set(key, row);\n                });\n                values[group.name] = skills.map((skill) => (\n                    bySkill.get(String(skill).trim().toLowerCase())\n                    ?? { [group.skillMatchField]: skill }\n                ));\n            });\n            if (Object.keys(values).length > 0) form.setFieldsValue(values);\n        }).catch(() => { /* matchRelevantSkills already degrades to [] */ });\n\n        return () => { cancelled = true; };\n        // The linkage ids are listed as SCALARS: urlPrefill is a fresh memo\n        // object on every searchParams change, so depending on it would re-run\n        // (and, on the refresh path, re-request) for no reason.\n    }, [\n        routerLocation?.state?.relevantSkillsToken,\n        routerLocation?.state?.relevantSkillsInputs,\n        urlPrefill?.linkage?.jobId,\n        urlPrefill?.linkage?.applicantId,\n        loading, groups, form,\n    ]);\n\n    // Linkage merged into the create payload: URL-derived when prefillFromUrl,\n    // else the explicit extraPayload prop.\n    const scopePayload = hasClientScope && effectiveClientId ? { clientId: effectiveClientId } : {};\n    const effectiveExtraPayload = { ...scopePayload, ...(urlPrefill?.linkage ?? extraPayload ?? {}) };\n\n    // True once both the form groups and (when needed) the prefill source data are\n    // ready. The Form.List components must NOT mount until this is true so that\n    // getAddRowInitialValue below provides the correct initialValue at mount —\n    // antd ignores initialValue changes after a Form.List has already mounted.\n    const isFormReady = !waitingForClientScope && !loading && (!urlPrefill?.source || (prefillGroups !== null && !prefillLoading));\n\n    // Build the Form.List initialValue for an addRow group. When candidate prefill\n    // data is available the group's payloadKey (e.g. \"workExperience\") is looked up\n    // in addRowPrefillsByKey and the stored rows are mapped through buildInitialValue\n    // so antd controls receive the right shape. Falls back to a single empty row.\n    const getAddRowInitialValue = (group) => {\n        // prefillFrom lets an addRow group seed its rows from a DIFFERENT source\n        // group key than its own (write) key — e.g. the submission employer group\n        // (submission_current_employer) prefilling from the candidate's\n        // current_employer_details rows on Quick Submit. Falls back to the write\n        // key, so groups that already share a payloadKey are unaffected.\n        const gKey = group.prefillFrom || group.payloadKey || group.name;\n        const rows = addRowPrefillsByKey[gKey];\n        const minRows = Math.max(0, Number(group.minRows ?? 0) || 0);\n        // Admin-configured defaultValues seed every fresh row (top-level fields\n        // get theirs via Form.Item initialValue, which does not reach Form.List\n        // rows — e.g. VMS Commission 5.5 inside the Employer group).\n        const seed = rowDefaultsFor(group);\n        if (!rows || rows.length === 0) {\n            // initialRows in config controls how many empty rows to start with (default 0).\n            // minRows still controls the minimum kept after removal.\n            const startCount = group.initialRows !== undefined\n                ? Math.max(minRows, Math.max(0, Number(group.initialRows) || 0))\n                : minRows;\n            return Array.from({ length: startCount }, () => ({ ...seed }));\n        }\n        const initial = rows.map(row => {\n            const rowVals = { ...seed };\n            (group.fields ?? []).forEach(field => {\n                if (!field.field || field.type === 'file') return;\n                const val = pickPrefillValue(row, field);\n                if (val !== undefined && val !== null) {\n                    // A repeat field inside the row (nested Form.List) hydrates as\n                    // an array, each element normalised for its control; a plain\n                    // field hydrates as a single value.\n                    rowVals[field.field] = truthy(field.addRow)\n                        ? buildRepeatFieldInitial(field, val)\n                        : buildInitialValue(field, val);\n                }\n            });\n            return rowVals;\n        });\n        while (initial.length < minRows) initial.push({ ...seed });\n        return initial;\n    };\n\n    // Precomputed per-group so a linked set (group.linkGroup) can be padded to\n    // equal length BEFORE any Form.List mounts — antd ignores initialValue\n    // changes after first mount, so this has to be ready up front, not derived\n    // ad hoc per group. A no-op passthrough for every group not in a linked set.\n\n    // ── Collapsible sections (group.allowCollapse / group.defaultCollapsed) ──\n    // Collapsing is OPT-IN. A group that does not ask for it renders with no\n    // chevron and can never be collapsed — which is the behaviour every form\n    // had before this existed, so nothing already configured changes.\n    //\n    // `defaultCollapsed` only means anything for a group that allows collapsing\n    // at all: a section that starts closed but cannot be opened would be a\n    // section the user simply cannot fill in.\n    //\n    // Seeded once per group set rather than on every render, so a user who\n    // opens a default-closed section does not have it slam shut again on the\n    // next state change. `collapsedSeeded` tracks WHICH group set has been\n    // applied, so a module switch (or a config reload) re-seeds exactly once.\n    const collapsedSeedKey = useMemo(\n        () => groups.map((g) => `${g.name}:${truthy(g.allowCollapse) ? 1 : 0}${truthy(g.defaultCollapsed) ? 1 : 0}`).join('|'),\n        [groups],\n    );\n    const collapsedSeeded = useRef(null);\n    useEffect(() => {\n        if (!groups.length || collapsedSeeded.current === collapsedSeedKey) return;\n        collapsedSeeded.current = collapsedSeedKey;\n        const seeded = {};\n        groups.forEach((group, index) => {\n            const key = group.name ?? group.id ?? String(index);\n            if (truthy(group.allowCollapse) && truthy(group.defaultCollapsed)) seeded[key] = true;\n        });\n        setCollapsed(seeded);\n    }, [collapsedSeedKey, groups]);\n\n    const addRowInitials = useMemo(() => {\n        const raw = {};\n        groups.forEach((group) => {\n            if (group.addRow) raw[group.name] = getAddRowInitialValue(group);\n        });\n        return padLinkedInitialValues(linkedGroupSets, raw);\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [groups, addRowPrefillsByKey, linkedGroupSets]);\n\n    const toggle = (key) => setCollapsed((prev) => ({ ...prev, [key]: !prev[key] }));\n\n    const handleReset = () => {\n        form.resetFields();\n        // Also reset collapsed state to default (all expanded)\n        setCollapsed({});\n        setSelectedSource('internal');\n        setTabs([]);\n    };\n\n    const handleSearch = useCallback(async (values, sourceOverride, paginationOverride = {}) => {\n        if (!isSearch) return;\n        const nextPageSize = Number(paginationOverride.pageSize) > 0\n            ? Number(paginationOverride.pageSize)\n            : searchPagination.pageSize;\n        const requestedCurrent = Number(paginationOverride.current);\n        const nextCurrent = Number.isFinite(requestedCurrent) && requestedCurrent > 0\n            ? Math.floor(requestedCurrent)\n            : 1;\n\n        try {\n            setLastSearchValues(values);\n            setSearchPagination({ current: nextCurrent, pageSize: nextPageSize });\n            setSearchResults((current) => ({ ...current, loading: true, searched: true }));\n            const checkedSources = getSearchSources(values?.selectedSource);\n            const activeSource = sourceOverride\n                ? resolveSearchSource(sourceOverride, selectedSource)\n                : (checkedSources.includes('internal')\n                    ? 'internal'\n                    : resolveSearchSource(values?.selectedSource, selectedSource));\n\n            // Include selectedSource in the search parameters\n            const searchParamsWithSource = {\n                ...values,\n                selectedSource: activeSource,\n            };\n\n            console.log('[AddFormV1] Calling searchModuleData with scope:', activeSource);\n\n            const result = await searchModuleData(moduleName || 'candidates', searchParamsWithSource, {\n                limit: nextPageSize,\n                offset: (nextCurrent - 1) * nextPageSize,\n            }, {\n                scope: activeSource,\n            });\n\n            setSelectedSource(activeSource);\n            setSearchResults({\n                searched: true,\n                rows: result.rows,\n                total: result.total,\n                fields: result.fields,\n                // Admin-configured row actions/rules — searchModuleData pulls these\n                // from the same /module-data-list response the regular ListView\n                // list-endpoint returns them on, so search results get the same\n                // admin-driven actions instead of none.\n                actions: result.actions ?? [],\n                actionRules: result.actionRules ?? [],\n                loading: false,\n            });\n            setTabs((currentTabs) => buildSourceTabs({\n                sources: checkedSources,\n                activeSource,\n                activeCount: result.total,\n                responseCounts: result.counts,\n                currentTabs,\n                backendTabs: result.tabs,\n            }));\n        } catch (error) {\n            console.error('Search failed:', error);\n            message.error(error?.message || 'Failed to search records');\n            setSearchResults({ searched: true, rows: [], total: 0, fields: [], actions: [], actionRules: [], loading: false });\n        }\n    }, [isSearch, moduleName, selectedSource, searchPagination.pageSize]);\n\n    const handleSourceAction = useCallback(async (action, record) => {\n        const actionKey = getSourceActionInstanceKey(action, record);\n        setSourceActionState((current) => ({\n            ...current,\n            [actionKey]: { ...(current[actionKey] ?? {}), loading: true },\n        }));\n        try {\n            const response = await runSourceAction(action, record);\n            message.success(\n                response?.message\n                ?? response?.data?.message\n                ?? action.successMessage\n                ?? 'Action completed successfully.',\n            );\n            setSourceActionState((current) => ({\n                ...current,\n                [actionKey]: { loading: false, completed: true },\n            }));\n        } catch (error) {\n            message.error(error?.message || action.errorMessage || 'Action failed.');\n            setSourceActionState((current) => ({\n                ...current,\n                [actionKey]: { ...(current[actionKey] ?? {}), loading: false },\n            }));\n        } finally {\n            setSourceActionState((current) => ({\n                ...current,\n                [actionKey]: { ...(current[actionKey] ?? {}), loading: false },\n            }));\n        }\n    }, []);\n\n    const handleTabChange = useCallback((newSource) => {\n        const activeSource = resolveSearchSource(newSource, selectedSource);\n        setSelectedSource(activeSource);\n        setSearchPagination({ current: 1, pageSize: searchPagination.pageSize });\n\n        // Re-trigger search with new source if we have previous search values\n        if (Object.keys(lastSearchValues).length > 0) {\n            handleSearch(lastSearchValues, activeSource, { current: 1, pageSize: searchPagination.pageSize });\n        }\n    }, [searchPagination.pageSize, lastSearchValues, handleSearch, selectedSource]);\n\n    const handleSearchPageChange = useCallback((current, pageSize) => {\n        const nextPageSize = Number(pageSize) > 0 ? Number(pageSize) : searchPagination.pageSize;\n        const nextCurrent = Number(current) > 0 ? Number(current) : 1;\n        if (Object.keys(lastSearchValues).length === 0) {\n            setSearchPagination({ current: nextCurrent, pageSize: nextPageSize });\n            return;\n        }\n        handleSearch(lastSearchValues, selectedSource, { current: nextCurrent, pageSize: nextPageSize });\n    }, [handleSearch, lastSearchValues, searchPagination.pageSize, selectedSource]);\n\n    const handleSearchPageSizeChange = useCallback((pageSize) => {\n        const nextPageSize = Number(pageSize) > 0 ? Number(pageSize) : searchPagination.pageSize;\n        if (Object.keys(lastSearchValues).length === 0) {\n            setSearchPagination({ current: 1, pageSize: nextPageSize });\n            return;\n        }\n        handleSearch(lastSearchValues, selectedSource, { current: 1, pageSize: nextPageSize });\n    }, [handleSearch, lastSearchValues, searchPagination.pageSize, selectedSource]);\n\n    // Submit-time duplicate (\"already present\") coming back from the\n    // authoritative server-side check. The record was NOT created, so the form\n    // must behave exactly like a failed client-side validation: values kept,\n    // form open, collapsed sections expanded, error shown under the offending\n    // field, and that field scrolled to + focused (shared\n    // utils/scrollToFirstFormError, same as onFinishFailed).\n    //\n    // The name used is the one the SERVER returned — the frontend field key,\n    // which is not necessarily the stored field it maps to.\n    const applyDuplicateFieldErrors = (source) => {\n        const duplicates = extractDuplicateFieldErrors(source, { uniqueRules: uniqueRuleIndex });\n        if (duplicates.length === 0) return false;\n\n        // item.name is the FULL antd path: a plain key for an ordinary field, and\n        // [group, rowIndex, key] for a field inside a repeatable (addRow) group,\n        // so the error lands on the row the user actually typed into.\n        form.setFields(duplicates.map((item) => ({ name: item.name ?? item.field, errors: [item.message] })));\n        setCollapsed({});\n        scrollToFirstFormError({\n            errorFields: duplicates.map((item) => {\n                const name = item.name ?? item.field;\n                return { name: Array.isArray(name) ? name : [name], errors: [item.message] };\n            }),\n        }, form);\n        return true;\n    };\n\n\n    // confirmLevelRule — the submit-time half of group.levelRule.\n    //\n    // The rule, its levels and its wording are all admin config; nothing here\n    // names a qualification. Region-resolved, so a market that requires a\n    // different rung is honoured.\n    //\n    // Returns TRUE to continue. A failure to evaluate also returns true: a\n    // hierarchy check must never be the reason a submit cannot happen at all.\n    const confirmLevelRule = useCallback(async (values) => {\n        try {\n            const region = getDefaults().region;\n            const resolved = groups.map((group) => resolveRegionRules(group, region));\n            const verdict = levelRuleVerdict(resolved, values);\n            if (verdict.severity === 'allow') return true;\n\n            if (verdict.severity === 'block') {\n                openFormNotice({\n                    tone: 'duplicate',\n                    title: 'This qualification history is incomplete',\n                    body: verdict.message,\n                    okText: 'Go back',\n                });\n                return false;\n            }\n            // openFormDecision resolves TRUE for its OK button and FALSE for\n            // Cancel — but here OK (\"Add it now\") means \"stop, let me go add\n            // the row myself\" (continue = false) and Cancel (\"Submit anyway\")\n            // means proceed (continue = true). That is the OPPOSITE of the\n            // dialog's own resolve value, so it must be inverted here; passing\n            // it straight through made \"Add it now\" silently submit anyway and\n            // \"Submit anyway\" silently do nothing.\n            const addItNow = await openFormDecision({\n                tone: 'suggestion',\n                title: 'Add the earlier qualification too?',\n                body: verdict.message,\n                okText: 'Add it now',\n                cancelText: 'Submit anyway',\n            });\n            return !addItNow;\n        } catch (err) {\n            console.warn('[levelRule] check skipped:', err);\n            return true;\n        }\n    }, [groups]);\n\n    const submit = async (values) => {\n        if (isSearch) {\n            await handleSearch(values);\n            return;\n        }\n\n        // The authoritative duplicate gate. The upload-time check is a courtesy\n        // — it fires before the form is complete and only when a file was read\n        // — so the decision is taken again here, against the finished values,\n        // where it can actually stop a second copy being created.\n        // 'clear' and 'existing' both continue: 'existing' means the user has\n        // already been sent to the record we have, so this submit is moot.\n        if (!embedded) {\n            const verdict = await duplicates.prompt({ reason: 'submit' });\n            if (verdict !== 'clear') return;\n        }\n\n        // Qualification hierarchy (admin config: group.levelRule). A Master's\n        // with no Bachelor's beneath it is usually an incomplete record — but\n        // not always, and the recruiter looking at the CV knows better than a\n        // config does. So ASK by default and let them proceed; only a rule\n        // explicitly marked severity:\"block\" refuses.\n        if (!(await confirmLevelRule(values))) return;\n\n        // A host page can own the confirm step (e.g. Quick Submit's Pontoon\n        // attestation / preview modal) and POST the record itself. It still gets\n        // the CONFIG-DRIVEN payload here — identical to what the native submit\n        // below would send — so payloadMode (\"skip\"), payloadKey remapping,\n        // dataType coercion and the showIf payload gating all still apply.\n        // Passing only `values` (raw antd form state, as before) meant a page\n        // with a custom onSubmit silently bypassed the entire Form Groups\n        // config. `values` is still the first argument for callers that need the\n        // raw state for display (preview cards, file lists).\n        if (onSubmit) {\n            await onSubmit(values, {\n                moduleName,\n                groups,\n                // A host that POSTs the record itself (Quick Submit, Resubmit)\n                // was silently skipping the shared document registry, because\n                // this branch returns before the registration below ever runs.\n                // The uploaded résumé therefore existed on the submission\n                // record but nowhere in `documents`, so nothing could link it\n                // to the candidate. Handing the host the SAME registration the\n                // native path uses closes that gap without it having to know\n                // how files are collected.\n                registerDocuments: async (recordId, opts = {}) => {\n                    const parts = collectFileParts(values, groups, { module: opts.module ?? moduleName });\n                    if (!parts.length || !recordId) return [];\n                    return uploadModuleDocuments(opts.module ?? moduleName, recordId, parts);\n                },\n                extraPayload: effectiveExtraPayload ?? {},\n                payload: {\n                    ...(effectiveExtraPayload ?? {}),\n                    ...buildPayload(values, groups, { module: moduleName }),\n                },\n            });\n            return;\n        }\n\n        if (!moduleName) {\n            console.log('Form values:', values);\n            return;\n        }\n\n        try {\n            setSubmitLoading(true);\n            const response = await createModuleRecord(moduleName, buildDynamicFormData(values, groups, effectiveExtraPayload ?? {}, moduleName));\n            const success = response?.status !== false;\n\n            if (!success) {\n                // A duplicate reported in a 200 envelope ({status:false}) is the\n                // same failure as a 409 — handle it the same way.\n                if (applyDuplicateFieldErrors(response)) return;\n                message.error(submitErrorMessage(groups, moduleName, 'add',\n                    response?.error || response?.message || response?.data));\n                return;\n            }\n\n            // Repeatable (addRow) document files are attached in a follow-up update\n            // through the reliable indexed path (documents[0], documents[1], …). The\n            // rows themselves were created on insert (metadata is in the create JSON),\n            // so this only uploads each file to its row by index. Runs only when the\n            // form actually carried addRow file uploads, so plain records and jobs\n            // stay single-request.\n            const addRowFileParts = collectFileParts(values, groups, { scope: 'addRow', indexed: true, module: moduleName });\n            const newRecordId = response?.id ?? response?.data?.id ?? response?.data?._id ?? response?._id;\n            if (addRowFileParts.length > 0 && newRecordId) {\n                try {\n                    await updateRecord(moduleName, newRecordId, { ...(effectiveExtraPayload ?? {}), ...buildPayload(values, groups, { module: moduleName }) }, addRowFileParts);\n                } catch (uploadErr) {\n                    console.error('Document file attach (post-create update) failed:', uploadErr);\n                    message.warning('Record created, but attaching document files failed. Edit the record to re-upload.');\n                }\n            }\n\n            // Common document registry — the module record is created FIRST (the\n            // Create API above generated its reference id), then every uploaded\n            // file (single or multiple, flat or addRow) is registered in the\n            // shared \"documents\" collection against that id, keyed by module name\n            // + the form field it was uploaded under (resume, jobDescription, …).\n            // Best-effort: the record already exists, so a registry failure only\n            // warns and never rolls back the create.\n            const allFileParts = collectFileParts(values, groups, { module: moduleName });\n            if (allFileParts.length > 0 && newRecordId) {\n                try {\n                    await uploadModuleDocuments(moduleName, newRecordId, allFileParts);\n                } catch (docErr) {\n                    console.error('Document registry upload failed:', docErr);\n                    message.warning('Record created, but saving its document records failed.');\n                }\n            }\n\n            // Admin-configurable success toast (group.submitMessages); defaults to\n            // \"<Module> has added successfully\" for every module, new ones included.\n            const successText = submitSuccessMessage(groups, moduleName, 'add');\n            if (successText) message.success(successText);\n            form.resetFields();\n\n            // Embedded (quick \"Add More\" modal): hand the new id back to the caller\n            // so it can refetch its option list and select the new record — never\n            // navigate away from the host form.\n            if (embedded && onSuccess) {\n                onSuccess(newRecordId, values);\n                return;\n            }\n\n            // A clicked extra button (formActions) overrides the group's default\n            // afterSubmit for this submit; the plain Create button leaves the ref\n            // null and keeps the existing behavior.\n            const afterSubmit = pendingAfterSubmitRef.current ?? resolveAfterSubmit(groups);\n            if (!afterSubmit) {\n                // No admin-configured behavior: return to wherever this form was\n                // opened FROM, falling back to cancelPath on a cold deep-link.\n                //\n                // This replaced a hardcoded module→route map (jobs→/jobs,\n                // candidates→/candidates, …) — four module names living in a\n                // component that is otherwise entirely config-driven, and which\n                // silently did nothing at all for every other module.\n                goBackOrTo(navigate, { cancelPath });\n            } else if (afterSubmit.mode === 'back') {\n                goBackOrTo(navigate, { cancelPath });\n            } else if (afterSubmit.mode === 'route' || afterSubmit.mode === 'detail') {\n                const target = safeNavTarget(afterSubmit.target, newRecordId, values);\n                if (target) navigate(target);\n            }\n            // afterSubmit.mode === 'stay' (or an unresolvable target): no navigation.\n        } catch (err) {\n            console.error(`Failed to create ${moduleName}:`, err);\n            // Authoritative server-side uniqueness check: keep every value the\n            // user entered, keep the form open, mark the field and take them to\n            // it. No success toast, no navigation.\n            if (applyDuplicateFieldErrors(err)) return;\n            message.error(submitErrorMessage(groups, moduleName, 'add',\n                err?.data?.error || err?.data?.message || err?.message));\n        } finally {\n            setSubmitLoading(false);\n            pendingAfterSubmitRef.current = null;\n        }\n    };\n\n    const getFieldDependencies = (field, currentName, prefixFor) => {\n        const rules = field.validations ?? field.validation ?? field.rules ?? [];\n        // maxFromField is listed separately because its referenced field may live\n        // OUTSIDE this row: the dependency path has to be built with the same\n        // scoping the rule itself uses, not the sibling assumption below.\n        const scoped = rules\n            .filter((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'maxFromField')\n            .map((rule) => maxFromFieldDependency(rule, currentName, prefixFor))\n            .filter(Boolean);\n        return [...scoped, ...rules\n            .filter((rule) => {\n                const type = typeof rule === 'string' ? rule : rule?.type;\n                return ['dateAfterField', 'greaterThanField', 'strictGreaterThanField',\n                    'strictLessThanField', 'lessThanOrEqualField', 'maxFieldWithFallback',\n                    'dateBeforeField', 'timeAfterField', 'timeBeforeField'].includes(type);\n            })\n            .map((rule) => {\n                const compareFields = String(rule.value ?? rule.compareField ?? rule.field ?? '')\n                    .split(',').map((item) => item.trim()).filter(Boolean);\n                return compareFields.map((compareField) => getSiblingFieldName(currentName, compareField));\n            })\n            .flat()\n            .filter(Boolean)];\n    };\n\n    // Evaluate a Show Condition. `prefixFor` resolves the sibling path prefix for\n    // a referenced field key (row-first for a group's own field, else top-level);\n    // it may also be a precomputed prefix array/null for legacy single-condition\n    // callers. A showIf can be a single leaf ({field,operator,value}) OR carry a\n    // `conditions` array combined by `logic` (\"and\" default | \"or\") — the\n    // multi-condition \"add more\" form — and a leaf + conditions combine too.\n    const resolvePrefix = (prefixFor, key) => (typeof prefixFor === 'function' ? prefixFor(key) : prefixFor);\n    const evalShowIfLeaf = (cond, getFieldValue, prefixFor) => {\n        if (!cond?.field) return true;\n        const prefix = resolvePrefix(prefixFor, cond.field);\n        const path = prefix != null\n            ? [...(Array.isArray(prefix) ? prefix : [prefix]), cond.field]\n            : [cond.field];\n        const val = getFieldValue(path);\n        switch (cond.operator) {\n            case 'eq': return String(val ?? '') === String(cond.value ?? '');\n            case 'neq': return String(val ?? '') !== String(cond.value ?? '');\n            case 'truthy': return val !== undefined && val !== null && val !== '' && val !== false;\n            case 'falsy': return val === undefined || val === null || val === '' || val === false;\n            // notEmpty targets an addRow GROUP's own Form.List name (cond.field is\n            // that group's name, e.g. \"submission_referral_details\") — true once the\n            // group has at least one row. Lets a flat field elsewhere in the form\n            // (e.g. \"referral rate\") only appear/require once a referral row exists.\n            case 'notEmpty': return Array.isArray(val) ? val.length > 0 : Boolean(val);\n            // in/notIn: cond.value is a comma-separated list (e.g. \"W2-Fulltime,W2-Contract\").\n            case 'in': return String(cond.value ?? '').split(',').map((v) => v.trim()).includes(String(val ?? ''));\n            case 'notIn': return !String(cond.value ?? '').split(',').map((v) => v.trim()).includes(String(val ?? ''));\n            default: return true;\n        }\n    };\n    const evaluateShowIf = (showIf, getFieldValue, prefixFor) => {\n        if (!showIf) return true;\n        const conditions = Array.isArray(showIf.conditions) ? showIf.conditions.filter((c) => c?.field) : [];\n        if (conditions.length) {\n            const results = conditions.map((c) => evalShowIfLeaf(c, getFieldValue, prefixFor));\n            const orLogic = String(showIf.logic ?? 'and').toLowerCase() === 'or';\n            let combined = orLogic ? results.some(Boolean) : results.every(Boolean);\n            // A top-level leaf alongside conditions is folded in with the same logic.\n            if (showIf.field) {\n                const leaf = evalShowIfLeaf(showIf, getFieldValue, prefixFor);\n                combined = orLogic ? (combined || leaf) : (combined && leaf);\n            }\n            return combined;\n        }\n        return evalShowIfLeaf(showIf, getFieldValue, prefixFor);\n    };\n    // True when a field carries any Show Condition (single leaf or multi-condition).\n    const hasShowIf = (showIf) => Boolean(showIf?.field || showIf?.conditions?.some?.((c) => c?.field));\n\n    const [combineToggles, setCombineToggles] = useState({});\n\n    const fieldKey = (field) => String(field?.field ?? '');\n\n    // Who is filling this form — drives admin-configured field autoValueRules\n    // (display only; the gateway enforces the same rules server-side).\n    const actingIdentity = useMemo(() => getActingIdentity(), []);\n\n    const renderField = (field, namePrefix, listName, opts = {}) => {\n        // Split dotted keys into array form so AntD Form nests values correctly:\n        // \"passport.passportNumber\" → ['passport','passportNumber']\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : null;\n        const parsedField = fieldParts ?? field.field;\n        const name = namePrefix !== undefined\n            ? [namePrefix, ...(fieldParts ?? [field.field])]\n            : parsedField;\n        // Inside a Form.List the relative name [rowIndex, fieldName] is correct for\n        // Form.Item registration, but form.getFieldValue / cross-field validators need\n        // the absolute path [listName, rowIndex, fieldName] to find the value in the\n        // form store. Build that here so validators and validateFields use the right path.\n        // listName is normally a single Form.List name (string), but a DOUBLY-nested\n        // list (a repeat field's subFields rendered inside an addRow group row) passes\n        // the full absolute path array of its own list — spread it instead of wrapping.\n        const absoluteName = (listName !== undefined && namePrefix !== undefined)\n            ? [...(Array.isArray(listName) ? listName : [listName]), ...(Array.isArray(name) ? name : [name])]\n            : name;\n        // Checkbox.Group (when options are configured) uses value=[]; single boolean checkbox uses checked=bool.\n        const isCheckboxGroup = field.type === 'checkbox' && (\n            (field.options && field.options.length > 0) ||\n            (field.dataSource && field.dataSource !== 'static')\n        );\n        const valuePropName = (!isCheckboxGroup && field.type === 'checkbox') ? 'checked' : 'value';\n        // Inline (combined) fields show no per-box label — the combined card prints a\n        // single label and the boxes sit side by side (e.g. From / To / Currency).\n        // hideLabel: the group renders one shared header row above all addRow rows\n        // instead of repeating each field's label on every row (e.g. Languages Known).\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        // Sibling path prefix for evaluateShowIf/labelWhen: [listName, rowIndex]\n        // in a Form.List, null for ordinary top-level fields.\n        const showIfPrefix = (listName !== undefined && namePrefix !== undefined)\n            ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix]\n            : null;\n        // A condition may reference a sibling IN this row, or any top-level\n        // field (e.g. contractType). Row prefix only applies when the referenced\n        // key is one of this group's own fields; unknown membership (no\n        // rowFieldKeys passed) keeps the historical row-first behavior.\n        const prefixFor = (conditionKey) => (\n            showIfPrefix && (!opts.rowFieldKeys || opts.rowFieldKeys.has(conditionKey))\n                ? showIfPrefix\n                : null\n        );\n        // An admin-configured override checkbox rides the LABEL, so \"this value\n        // may exceed its limit\" reads as a qualifier on the field's name rather\n        // than as another input. See form/validationOverride.js.\n        const overrideCfg = overrideConfig(field);\n        const overrideFlag = overrideCfg ? overrideFlagPath(field, absoluteName, prefixFor) : null;\n        const baseFieldLabel = (opts.inline || opts.hideLabel)\n            ? ''\n            : (!isCheckboxGroup && field.type === 'checkbox')\n                ? ''\n                : <ConfiguredFieldLabel form={form} field={field} siblingPrefix={field.labelWhen?.field ? prefixFor(field.labelWhen.field) : showIfPrefix} locked={permissionLocked} />;\n        // A label-less presentation (inline/combined box, shared header row) has\n        // nowhere to hang it; the combined block prints it once instead — see\n        // renderCombinedPack.\n        const fieldLabel = (overrideCfg && baseFieldLabel) ? (\n            <span className=\"v1-label-with-override\">\n                {baseFieldLabel}\n                <ValidationOverrideCheckbox\n                    form={form}\n                    field={field}\n                    flagPath={overrideFlag}\n                    fieldPath={absoluteName}\n                    disabled={permissionLocked}\n                />\n            </span>\n        ) : baseFieldLabel;\n        const dependencies = getFieldDependencies(field, absoluteName, prefixFor);\n        // Admin-set help text (field.tooltip, or the older infoEnabled/infoText\n        // pair). It rides the label when there is one; a label-less field\n        // (inline/combined box, or a group printing one shared header row) gets\n        // it on the control instead — see fieldItem below — so EVERY control\n        // type can carry a tooltip.\n        const tooltipText = fieldTooltipText(field);\n        const mdSpan = opts.inline ? 24 : ((field.type === 'file' && truthy(field.multiple)) || field.type === 'text-editor' ? 24 : (field.col ?? 12));\n\n        // Config-driven default for the Add form: a top-level field (not inside a\n        // Form.List) with a configured defaultValue mounts pre-selected. Any prefill\n        // (initialRecord / quick-submit) runs through setFieldsValue, which overrides\n        // initialValue — so this only affects a fresh Add with no incoming value.\n        //\n        // An autoValueRule for the acting user (e.g. Submit Source → \"External\"\n        // for an employer-type user) outranks defaultValue: the field mounts\n        // showing the value the gateway will enforce anyway. Display only — the\n        // backend re-evaluates the same rules and has the final say.\n        const autoValue = autoValueFor(field, actingIdentity);\n        const initialValue = (namePrefix === undefined && field.type !== 'file'\n            && autoValue.matched && autoValue.value !== undefined && autoValue.value !== '')\n            ? autoValue.value\n            : ((namePrefix === undefined && field.type !== 'file'\n                && field.defaultValue !== undefined && field.defaultValue !== '')\n                ? field.defaultValue : undefined);\n\n        // AI Actions: admin-configured buttons (Generate/Parse-style) attached to\n        // this field. \"click\" actions render as buttons beside the field; an\n        // \"upload\" action (on a file field) fires automatically when a new file\n        // is accepted, via the onAiUpload callback passed into FieldControl.\n        const clickAiActions = (field.aiActions || []).filter((a) => a.trigger === 'click');\n        const uploadAiAction = (field.aiActions || []).find((a) => a.trigger === 'upload');\n\n        const fieldItem = (\n            <Form.Item\n                label={fieldLabel}\n                name={name}\n                extra={renderFieldHelp(field, prefillHints[field.field])}\n                rules={getRules(field, form, absoluteName, isSearch, prefixFor, uniqueContext,\n                    inProgressRulesFor(field, opts.groupNameForActions))}\n                required={isFieldRequired(field, form, absoluteName)}\n                dependencies={dependencies}\n                valuePropName={valuePropName}\n                initialValue={initialValue}\n                getValueFromEvent={field.type === 'file' ? (event) => (Array.isArray(event) ? event : event?.fileList) : undefined}\n                validateTrigger={['onBlur', 'onChange']}\n            >\n                <FieldControl\n                    key={field.refreshToken != null ? `${field.field}-refresh-${field.refreshToken}` : undefined}\n                    field={field}\n                    form={form}\n                    name={absoluteName}\n                    rowFieldKeys={opts.rowFieldKeys}\n                    moduleName={moduleName}\n                    scopeValues={{ clientId: effectiveClientId }}\n                    onAiUpload={uploadAiAction\n                        ? (file) => aiActions.runAction(opts.groupNameForActions, field, uploadAiAction, file)\n                        : undefined}\n                    onDuplicateBlur={handleDuplicateBlur}\n                    onRegionBlocked={handleRegionBlocked}\n                    onRowOrderChange={handleRowOrder}\n                    formDisabled={aiActions.busy}\n                />\n            </Form.Item>\n        );\n\n        // A label-less field (inline/combined box, or a group that prints one\n        // shared header row) has nowhere to hang the label's info icon, so the\n        // whole item becomes the tooltip target. The wrapping <span> is what\n        // Tooltip attaches to — passing the Form.Item straight in would make\n        // antd clone it for the ref, and Form.Item's clone is reserved for\n        // injecting value/onChange into its control.\n        const tooltippedItem = (tooltipText && !fieldLabel)\n            ? <Tooltip title={tooltipText}><span className=\"v1-field-tooltip-wrap\">{fieldItem}</span></Tooltip>\n            : fieldItem;\n\n        const fieldItemWithActions = clickAiActions.length > 0 ? (() => {\n            const positioned = groupActionsByPosition(clickAiActions);\n            const group = (position) => (\n                <AiActionButtonGroup\n                    key={position}\n                    position={position}\n                    actions={positioned[position]}\n                    aiActions={aiActions}\n                    groupName={opts.groupNameForActions}\n                    field={field}\n                />\n            );\n            return (\n                <div className=\"v1-ai-action-wrap\">\n                    {group('top-left')}\n                    {group('top-center')}\n                    {group('top-right')}\n                    {tooltippedItem}\n                    {group('bottom-left')}\n                    {group('bottom-center')}\n                    {group('bottom-right')}\n                </div>\n            );\n        })() : tooltippedItem;\n\n        // The verify carrier fields (verifyResultField \"isValid\" / verifyTimestampField\n        // \"validatedAt\") are show:0, so they are NOT rendered as Form.Items above —\n        // which means the value VerifyFieldButton sets via setFieldValue lives on an\n        // UNREGISTERED path and antd's onFinish drops it, so \"verified\" was never\n        // persisted (and so an edit form had nothing to prefill). Registering them as\n        // hidden Form.Items — under the SAME relative name (row-indexed inside an\n        // addRow Form.List) — makes the set value survive submit AND lets an edit\n        // prefill populate it, so VerifyFieldButton shows \"Verified\" for an already-\n        // verified email. omitEmpty on the field config keeps an unverified row from\n        // writing a null/false carrier.\n        const carrierName = (key) => (namePrefix !== undefined ? [namePrefix, key] : key);\n        const verifyCarriers = field.verifyAction ? (\n            <>\n                {field.verifyResultField && (\n                    <Form.Item name={carrierName(field.verifyResultField)} hidden noStyle>\n                        <Input />\n                    </Form.Item>\n                )}\n                {field.verifyTimestampField && (\n                    <Form.Item name={carrierName(field.verifyTimestampField)} hidden noStyle>\n                        <Input />\n                    </Form.Item>\n                )}\n            </>\n        ) : null;\n\n        const fieldItemWithVerify = field.verifyAction ? (\n            <div className=\"v1-verify-field-row\">\n                {fieldItemWithActions}\n                <VerifyFieldButton form={form} field={field} absoluteName={absoluteName} />\n                {verifyCarriers}\n            </div>\n        ) : fieldItemWithActions;\n\n        // The override flag lives on a path nothing else registers, so — exactly\n        // like the verify carriers above — it needs a hidden Form.Item or antd's\n        // onFinish drops it and an edit has nothing to prefill from.\n        const fieldItemWithOverride = overrideCfg ? (\n            <>\n                {fieldItemWithVerify}\n                <Form.Item\n                    name={namePrefix !== undefined\n                        ? [namePrefix, overrideFlag[overrideFlag.length - 1]]\n                        : overrideFlag[overrideFlag.length - 1]}\n                    valuePropName=\"checked\"\n                    hidden\n                    noStyle\n                >\n                    <Checkbox />\n                </Form.Item>\n            </>\n        ) : fieldItemWithVerify;\n\n        // Inside a combined block, each box's width follows its combineWidth weight\n        // (flex-grow), so the pack can be sized by ratio (e.g. 2:1, 1:2:3). Unset → 1.\n        const inlineStyle = opts.inline\n            ? { flex: `${Number(field.combineWidth) > 0 ? Number(field.combineWidth) : 1} 1 0`, maxWidth: 'none' }\n            : undefined;\n\n\n        const autoFillWatcher = field.autoFillFromApi ? (\n            <AutoFillFromApiWatcher\n                key={`${field.field}-autoFillFromApi`}\n                form={form}\n                config={field.autoFillFromApi}\n                watchPath={absoluteName}\n            />\n        ) : null;\n\n        const prefillWatcher = field.prefillWhen?.length ? (\n            <PrefillWhenWatcher\n                key={`${field.field}-prefillWhen`}\n                form={form}\n                rules={field.prefillWhen}\n                watchPaths={prefillWhenWatchPaths(field.prefillWhen, absoluteName, resolveScopedFieldPath, prefixFor)}\n                targetPath={absoluteName}\n                resetOnNoMatch={field.prefillWhenReset !== false}\n            />\n        ) : null;\n\n        // A show:0 field only reaches here because it has prefillWhen (see\n        // the visibleFields filter above) — it exists purely to derive and\n        // hold a value via the watcher, never to be seen or directly edited.\n        if (field.show === 0) {\n            return (\n                <Fragment key={field.field}>\n                    {prefillWatcher}\n                    {autoFillWatcher}\n                    <Form.Item name={name} hidden noStyle>\n                        <input type=\"hidden\" />\n                    </Form.Item>\n                </Fragment>\n            );\n        }\n\n        // colWhen: live grid width, so a field can shrink when a condition\n        // reveals a sibling next to it. Inline (combined) cells are flex-sized\n        // by combineWidth, so they keep their fixed span.\n        const hasColWhen = !opts.inline && colWhenRules(field).length > 0;\n        const spanFor = (getFieldValue) => (hasColWhen\n            ? resolveColSpan(field, mdSpan, (rule) => getFieldValue(conditionFieldPath(rule, prefixFor(rule.field))))\n            : mdSpan);\n\n        if (hasShowIf(field.showIf) || hasColWhen) {\n            return (\n                <Fragment key={field.field}>\n                    {prefillWatcher}\n                    {autoFillWatcher}\n                    <Form.Item shouldUpdate noStyle>\n                        {({ getFieldValue }) =>\n                            (!hasShowIf(field.showIf) || evaluateShowIf(field.showIf, getFieldValue, prefixFor))\n                                ? <Col xs={24} md={spanFor(getFieldValue)} style={inlineStyle} className={opts.inline ? 'v1-combine-cell' : undefined}>{fieldItemWithOverride}</Col>\n                                : null\n                        }\n                    </Form.Item>\n                </Fragment>\n            );\n        }\n        return (\n            <Fragment key={field.field}>\n                {prefillWatcher}\n                {autoFillWatcher}\n                <Col xs={24} md={mdSpan} style={inlineStyle} className={opts.inline ? 'v1-combine-cell' : undefined}>{fieldItemWithOverride}</Col>\n            </Fragment>\n        );\n    };\n\n    // renderAddRowField — field-level \"addRow\": repeats a SINGLE field's control\n    // with the same add/remove + min/initial/max config the group-level addRow\n    // uses (Form.List), but each list item IS the field's value directly (no\n    // sub-key row object). Config keys mirror the group ones: field.minRows /\n    // field.initialRows / field.maxRows / field.addLabel.\n    //   • minRows    — delete is disabled once the list reaches this count.\n    //   • initialRows— empty inputs shown on a fresh Add (falls back to minRows).\n    //   • maxRows    — the \"Add\" button hides once the list reaches this count.\n    // Required (field.req) is enforced at the LIST level (>=1 non-empty entry) —\n    // per-item rules skip \"required\" so an empty-but-present item never blocks.\n    // Each item renders through singleFieldOf(field) so a repeatable select/\n    // multi field shows a SINGLE control per item, not a multi-select.\n    // Only used for a top-level field (namePrefix === undefined) — a field with\n    // addRow=true inside an addRow GROUP renders as a normal single-value field\n    // (no nested repeats).\n    const renderAddRowField = (field) => {\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : [field.field];\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        const fieldLabel = <FieldLabel field={field} label={field.label} locked={permissionLocked} />;\n        const itemField = singleFieldOf(field);\n        // subFields → repeat a GROUP of fields per row (each row is an object of\n        // the sub-fields, e.g. question + answer) instead of a single scalar.\n        // Rows render through the same renderFields the group-level addRow uses.\n        const hasSubFields = Array.isArray(field.subFields) && field.subFields.length > 0;\n        // Sub-fields are always shown + editable (the admin exposes no show/edit\n        // toggle for them). Force both so a sub-field never renders disabled: the\n        // Go FormGroupField serializes show/edit as 0 when unset (no omitempty),\n        // which editable() would otherwise read as \"not editable\".\n        const subFieldsToRender = hasSubFields\n            ? field.subFields.map((sf) => ({ ...sf, show: 1, edit: 1 }))\n            : null;\n        const minRows = Math.max(0, Number(field.minRows ?? 0) || 0);\n        const maxRows = field.maxRows !== undefined && field.maxRows !== '' && Number(field.maxRows) > 0\n            ? Number(field.maxRows) : 0;\n        // Prefill source (quick-submit / initialRecord) — the Form.List mounts\n        // only once the form is ready, so this initialValue is correct at mount.\n        const prefillSource = pickPrefillValue(initialRecord ?? prefillFlatRecord ?? {}, field);\n        const initialValue = buildRepeatFieldInitial(field, prefillSource);\n\n        return (\n            <Col key={field.field} xs={24} md={24}>\n                <Form.Item label={fieldLabel} required={isFieldRequired(field)} colon={false} className=\"v1-combine-field\">\n                    <Form.List\n                        name={fieldParts}\n                        initialValue={initialValue}\n                        rules={[{\n                            validator: async (_, items = []) => {\n                                if (isFieldRequired(field)) {\n                                    const filled = hasSubFields\n                                        ? items.some((v) => hasMeaningfulValue(v))\n                                        : items.some((v) => v !== undefined && v !== null && v !== '' && !(Array.isArray(v) && v.length === 0));\n                                    if (!filled) throw new Error('Mandatory Field');\n                                }\n                                if (minRows > 0 && items.length < minRows) {\n                                    throw new Error(`Keep at least ${minRows} ${hasSubFields ? 'row' : 'value'}${minRows > 1 ? 's' : ''}.`);\n                                }\n                            },\n                        }]}\n                    >\n                        {(items, { add, remove }, { errors }) => (\n                            <div className=\"v1-addrow-wrapper\">\n                                {items.map(({ key: itemKey, name: itemName }) => (\n                                    <div key={itemKey} className=\"v1-addrow-item\">\n                                        <Button\n                                            type=\"text\" danger icon={<DeleteOutlined />}\n                                            onClick={() => remove(itemName)}\n                                            disabled={items.length <= minRows}\n                                            className=\"v1-addrow-delete-btn\"\n                                        />\n                                        <div className=\"v1-addrow-fields\">\n                                            {hasSubFields ? (\n                                                <Row gutter={[24, 0]} align=\"top\">\n                                                    {renderFields(subFieldsToRender, itemName, fieldParts[0], false, field.field)}\n                                                </Row>\n                                            ) : (\n                                                <Form.Item\n                                                    name={[itemName]}\n                                                    noStyle\n                                                    valuePropName={field.type === 'checkbox' && !(field.options?.length) ? 'checked' : 'value'}\n                                                    getValueFromEvent={field.type === 'file' ? (event) => (Array.isArray(event) ? event : event?.fileList) : undefined}\n                                                    rules={getRules(itemField, form, [...fieldParts, itemName], isSearch)}\n                                                >\n                                                    <FieldControl\n                                                        field={itemField}\n                                                        form={form}\n                                                        name={[...fieldParts, itemName]}\n                                                        moduleName={moduleName}\n                                                        scopeValues={{ clientId: effectiveClientId }}\n                                                        formDisabled={aiActions.busy}\n                                                    />\n                                                </Form.Item>\n                                            )}\n                                        </div>\n                                    </div>\n                                ))}\n                                {(!maxRows || items.length < maxRows) && (\n                                    <Button type=\"link\" icon={<PlusOutlined />} onClick={() => add()} className=\"v1-addrow-add-btn\">\n                                        {field.addLabel ?? `Add ${field.label ?? 'Value'}`}\n                                    </Button>\n                                )}\n                                <Form.ErrorList errors={errors} />\n                            </div>\n                        )}\n                    </Form.List>\n                </Form.Item>\n            </Col>\n        );\n    };\n\n    // renderNestedRepeatField — a repeat field (field.addRow) that lives INSIDE\n    // an addRow group row. It nests its own Form.List under the current row so\n    // every row owns an independent set of repeat values (the payload shape\n    // group[rowIndex].repeatField[repeatIndex], e.g. educationDetails[0].subjects).\n    // Also handles the field.subFields case (repeat a GROUP of sub-fields\n    // together per row, e.g. question + answer) nested the same way — each item\n    // renders the sub-fields through the same renderFields the top-level\n    // subFields branch (renderAddRowField) uses, so a select/lookup sub-field\n    // gets the exact same config-driven dropdown loading as any other field.\n    // namePrefix is the outer row's index (from the group Form.List), listName\n    // is the group's Form.List name (string) or, for a doubly-nested case, its\n    // absolute path array. The nested list's `name` is relative to that list\n    // context ([rowIndex, ...fieldParts]); item controls use the absolute path\n    // for validators/FieldControl.\n    const renderNestedRepeatField = (field, namePrefix, listName) => {\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : [field.field];\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        const fieldLabel = <FieldLabel field={field} label={field.label} locked={permissionLocked} />;\n        const itemField = singleFieldOf(field);\n        const hasSubFields = Array.isArray(field.subFields) && field.subFields.length > 0;\n        const subFieldsToRender = hasSubFields\n            ? field.subFields.map((sf) => ({ ...sf, show: 1, edit: 1 }))\n            : null;\n        const minRows = Math.max(0, Number(field.minRows ?? 0) || 0);\n        const maxRows = field.maxRows !== undefined && field.maxRows !== '' && Number(field.maxRows) > 0\n            ? Number(field.maxRows) : 0;\n        // Relative name (group-list context prefixes the group name); the parent\n        // row's initialValue already carries any stored values for this key, so a\n        // fresh row falls back to config-driven empty inputs while an edited row\n        // inherits its stored values (antd ignores this initialValue when the\n        // store already holds a value at this path).\n        const listNameRel = [namePrefix, ...fieldParts];\n        const nestedAbsoluteListName = [...(Array.isArray(listName) ? listName : [listName]), namePrefix, ...fieldParts];\n        const initialValue = buildRepeatFieldInitial(field, undefined);\n        return (\n            <Col key={`${listName}-${namePrefix}-${field.field}`} xs={24} md={hasSubFields ? 24 : (field.col ?? 24)}>\n                <Form.Item label={fieldLabel} required={isFieldRequired(field)} colon={false} className=\"v1-combine-field\">\n                    <Form.List\n                        name={listNameRel}\n                        initialValue={initialValue}\n                        rules={hasSubFields ? [{\n                            validator: async (_, items = []) => {\n                                if (isFieldRequired(field)) {\n                                    const filled = items.some((v) => hasMeaningfulValue(v));\n                                    if (!filled) throw new Error('Mandatory Field');\n                                }\n                                if (minRows > 0 && items.length < minRows) {\n                                    throw new Error(`Keep at least ${minRows} row${minRows > 1 ? 's' : ''}.`);\n                                }\n                            },\n                        }] : []}\n                    >\n                        {(items, { add, remove }, { errors }) => (\n                            <div className=\"v1-addrow-wrapper\">\n                                {items.map(({ key: itemKey, name: itemName }) => {\n                                    const absoluteName = [...nestedAbsoluteListName, itemName];\n                                    return (\n                                        <div key={itemKey} className=\"v1-addrow-item\">\n                                            <Button\n                                                type=\"text\" danger icon={<DeleteOutlined />}\n                                                onClick={() => remove(itemName)}\n                                                disabled={items.length <= minRows}\n                                                className=\"v1-addrow-delete-btn\"\n                                            />\n                                            <div className=\"v1-addrow-fields\">\n                                                {hasSubFields ? (\n                                                    <Row gutter={[24, 0]} align=\"top\">\n                                                        {renderFields(subFieldsToRender, itemName, nestedAbsoluteListName, false, field.field)}\n                                                    </Row>\n                                                ) : (\n                                                    <Form.Item\n                                                        name={[itemName]}\n                                                        noStyle\n                                                        valuePropName={field.type === 'checkbox' && !(field.options?.length) ? 'checked' : 'value'}\n                                                        getValueFromEvent={field.type === 'file' ? (event) => (Array.isArray(event) ? event : event?.fileList) : undefined}\n                                                        rules={getRules(itemField, form, absoluteName, isSearch)}\n                                                    >\n                                                        <FieldControl\n                                                            field={itemField}\n                                                            form={form}\n                                                            name={absoluteName}\n                                                            moduleName={moduleName}\n                                                            scopeValues={{ clientId: effectiveClientId }}\n                                                            formDisabled={aiActions.busy}\n                                                        />\n                                                    </Form.Item>\n                                                )}\n                                            </div>\n                                        </div>\n                                    );\n                                })}\n                                {(!maxRows || items.length < maxRows) && (\n                                    <Button type=\"link\" icon={<PlusOutlined />} onClick={() => add()} className=\"v1-addrow-add-btn\">\n                                        {field.addLabel ?? `Add ${field.label ?? 'Value'}`}\n                                    </Button>\n                                )}\n                                <Form.ErrorList errors={errors} />\n                            </div>\n                        )}\n                    </Form.List>\n                </Form.Item>\n            </Col>\n        );\n    };\n\n\n// registerHiddenFields — a show:0 field still needs a Form.Item.\n//\n// A hidden field is not decoration: it is a CARRIER. The engine deliberately\n// keeps show:0 fields in the group (see normalizeGroups) precisely so their\n// values participate — the job's client rate rides onto a submission that way\n// (jobClientRate.*, filled by prefillFromModule), and a verify result rides on\n// isValid/validatedAt.\n//\n// But a value set with setFieldsValue on a path NOTHING has registered is not\n// reliably part of the form: onFinish drops it, and a cross-field rule reading\n// it through getFieldValue can come back empty. That is why the verify carriers\n// were already registered by hand at their own call site. Doing it here covers\n// EVERY config-declared hidden field instead of the two someone remembered,\n// which is what makes a rule like \"rate may not exceed the job's client rate\"\n// actually fire — before this it silently found no ceiling and passed anything.\n//\n// Rendered `hidden` (never visible), unstyled, and outside the layout grid, so\n// nothing about the form's appearance changes.\nconst renderHiddenCarriers = (fields, namePrefix) => fields\n    .filter((f) => f.field && f.show !== undefined && !truthy(f.show))\n    .map((f) => {\n        const parts = String(f.field).includes('.') ? String(f.field).split('.') : f.field;\n        const name = namePrefix !== undefined\n            ? [namePrefix, ...(Array.isArray(parts) ? parts : [parts])]\n            : parts;\n        return (\n            <Form.Item key={`hidden-${f.field}`} name={name} hidden noStyle>\n                <Input />\n            </Form.Item>\n        );\n    });\n\n    const renderFields = (fields, namePrefix, listName, hideLabel = false, groupNameForActions) => {\n        const used = new Set();\n        const out = [];\n        // Keys of THIS group's own fields — conditions (showIf/labelWhen/\n        // prefillWhen) referencing a field OUTSIDE the group (e.g. the top-level\n        // contractType from inside the addRow employer group) must resolve\n        // against the top-level form, not the row.\n        const rowFieldKeys = new Set(fields.map((f) => f.field).filter(Boolean));\n        // Hidden (show:0) fields stay in `fields` so buildPayload can see them\n        // (see normalizeGroups) — they just never get a Form.Item here.\n        const visibleFields = fields.filter((f) => (\n            f.show === undefined || truthy(f.show) || (f.show === 0 && Boolean(f.prefillWhen?.length))\n        ));\n        out.push(...renderHiddenCarriers(fields, namePrefix));\n        visibleFields.forEach((field) => {\n            if (truthy(field.addRow) && namePrefix === undefined) {\n                out.push(renderAddRowField(field));\n                return;\n            }\n            // A repeat field INSIDE an addRow group row (namePrefix defined) gets\n            // its own nested Form.List so each row keeps independent repeat values\n            // (educationDetails[rowIndex].subjects[]) — including a subFields\n            // repeat-GROUP (e.g. question+answer pairs per education row).\n            if (truthy(field.addRow) && namePrefix !== undefined) {\n                out.push(renderNestedRepeatField(field, namePrefix, listName));\n                return;\n            }\n            const combineKey = field.combineKey?.trim?.();\n            if (!combineKey) {\n                out.push(renderField(field, namePrefix, listName, { hideLabel, groupNameForActions, rowFieldKeys }));\n                return;\n            }\n            const packKey = `${listName ?? 'root'}:${namePrefix ?? 'root'}:${combineKey}`;\n            if (used.has(packKey)) return;\n            const pack = visibleFields.filter((f) => f.combineKey === combineKey);\n            pack.forEach((f) => used.add(`${listName ?? 'root'}:${namePrefix ?? 'root'}:${f.combineKey}`));\n\n            const labelField = pack.find((f) => f.combineLabel) ?? field;\n            const siblingPrefix = (listName !== undefined && namePrefix !== undefined)\n                ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix]\n                : null;\n            // A combined pack prints ONE shared label, so an override checkbox\n            // configured on ANY member belongs beside that shared label — the\n            // per-field path in renderField cannot fire here (inline members are\n            // label-less by design). First member that declares one wins.\n            const packOverrideField = pack.find((f) => overrideConfig(f)) ?? null;\n            const packPrefixForOverride = (conditionKey) => (\n                siblingPrefix && (!rowFieldKeys || rowFieldKeys.has(conditionKey)) ? siblingPrefix : null\n            );\n            const packOverrideAbsName = packOverrideField\n                ? ((listName !== undefined && namePrefix !== undefined)\n                    ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix,\n                        ...(String(packOverrideField.field).includes('.')\n                            ? String(packOverrideField.field).split('.')\n                            : [packOverrideField.field])]\n                    : (String(packOverrideField.field).includes('.')\n                        ? String(packOverrideField.field).split('.')\n                        : packOverrideField.field))\n                : null;\n            const baseCombinedLabel = <ConfiguredFieldLabel form={form} field={labelField} siblingPrefix={siblingPrefix} combined />;\n            const label = packOverrideField ? (\n                <span className=\"v1-label-with-override\">\n                    {baseCombinedLabel}\n                    <ValidationOverrideCheckbox\n                        form={form}\n                        field={packOverrideField}\n                        flagPath={overrideFlagPath(packOverrideField, packOverrideAbsName, packPrefixForOverride)}\n                        fieldPath={packOverrideAbsName}\n                    />\n                </span>\n            ) : baseCombinedLabel;\n            const toggleTarget = pack.find((f) => f.combineToggleTarget)?.combineToggleTarget;\n            const toggleLabel = pack.find((f) => f.combineToggleLabel)?.combineToggleLabel ?? 'Show range';\n            const toggleStateKey = packKey;\n            const wrapPack = pack.some((f) => truthy(f.combineWrap));\n            const configuredSpan = Number(pack.find((f) => [12, 24].includes(Number(f.combineSpan)))?.combineSpan);\n            const targetField = toggleTarget ? pack.find((f) => fieldKey(f) === toggleTarget) : null;\n            const targetParts = targetField?.field?.includes?.('.') ? targetField.field.split('.') : [targetField?.field].filter(Boolean);\n            const targetName = targetField\n                ? ((listName !== undefined && namePrefix !== undefined)\n                    ? [listName, namePrefix, ...targetParts]\n                    : (targetParts.length > 1 ? targetParts : targetField.field))\n                : null;\n\n            // Layout mirrors the legacy combined field: one label, the boxes inline on\n            // a single row, and the range toggle BELOW. Toggle off → only the primary\n            // (target hidden); toggle on → the target box appears alongside. The wider\n            // packs (with currency/unit) take a full row; a simple From/To pair is half.\n            const primaryReq = pack.some((f) => isFieldRequired(f));\n            const comboSpan = [12, 24].includes(configuredSpan)\n                ? configuredSpan\n                : (pack.length >= 3 ? 24 : 12);\n            // A combined pack prints ONE shared label above its boxes, and that\n            // label lives outside the per-field showIf gates. When every member\n            // is hidden by its condition the boxes disappear but the labelled\n            // shell stayed — e.g. an empty \"Contact Number\" on a W2 employer.\n            // Gate the whole pack on \"is any member still visible\".\n            const packPrefixFor = (conditionKey) => (\n                siblingPrefix && (!rowFieldKeys || rowFieldKeys.has(conditionKey)) ? siblingPrefix : null\n            );\n            const packHasShowIf = pack.some((f) => hasShowIf(f.showIf));\n            const anyPackMemberVisible = (getFieldValue) => pack.some(\n                (f) => !hasShowIf(f.showIf) || evaluateShowIf(f.showIf, getFieldValue, packPrefixFor),\n            );\n            const packCol = (\n                <Col key={packKey} xs={24} md={comboSpan}>\n                    <Form.Item label={label} required={primaryReq} colon={false} className=\"v1-combine-field\">\n                        <Form.Item noStyle shouldUpdate>\n                            {({ getFieldValue }) => {\n                                const hasTargetValue = targetName ? !empty(getFieldValue(targetName)) : false;\n                                const checked = combineToggles[toggleStateKey] ?? hasTargetValue;\n                                const visiblePack = toggleTarget && !checked\n                                    ? pack.filter((f) => fieldKey(f) !== toggleTarget)\n                                    : pack;\n                                return (\n                                    <>\n                                        <Row\n                                            gutter={[8, 0]}\n                                            align=\"top\"\n                                            wrap={wrapPack}\n                                            className={`v1-combine-row${wrapPack ? ' v1-combine-row-wrap' : ''}`}\n                                        >\n                                            {/* Combined-field mandatory cascade: if ANY field in a\n                                                combined pack is required, every VISIBLE field in the\n                                                pack is required too (e.g. Notice Period requires its\n                                                Unit). Applied to visiblePack so a hidden range \"To\"\n                                                stays optional until its toggle is on. */}\n                                            {visiblePack.map((f) => renderField(primaryReq ? { ...f, req: 1 } : f, namePrefix, listName, { inline: true }))}\n                                        </Row>\n                                        {toggleTarget && (\n                                            <div className=\"v1-combine-range\">\n                                                <Switch\n                                                    size=\"small\"\n                                                    checked={checked}\n                                                    onChange={(next) => {\n                                                        if (!next && targetName) {\n                                                            form.setFieldValue(targetName, undefined);\n                                                            form.validateFields([targetName]).catch(() => { });\n                                                        }\n                                                        setCombineToggles((prev) => ({ ...prev, [toggleStateKey]: next }));\n                                                    }}\n                                                />\n                                                <Text type=\"secondary\" className=\"v1-combine-toggle-label\">{toggleLabel}</Text>\n                                            </div>\n                                        )}\n                                    </>\n                                );\n                            }}\n                        </Form.Item>\n                    </Form.Item>\n                </Col>\n            );\n            out.push(packHasShowIf ? (\n                <Form.Item key={packKey} shouldUpdate noStyle>\n                    {({ getFieldValue }) => (anyPackMemberVisible(getFieldValue) ? packCol : null)}\n                </Form.Item>\n            ) : packCol);\n        });\n        return out;\n    };\n\n    // Derive fields from search results for ListView (same logic as JobsListPage)\n    const searchFields = useMemo(() => {\n        if (searchResults.fields?.length) return searchResults.fields;\n        const firstRow = searchResults.rows[0];\n        if (!firstRow) return [];\n\n        return Object.keys(firstRow)\n            .filter((key) => !key.startsWith('_') && typeof firstRow[key] !== 'object')\n            .map((key) => ({\n                value: key,\n                field: key,\n                label: key.replace(/([A-Z])/g, ' $1').replace(/^./, (char) => char.toUpperCase()),\n                isVisible: true,\n            }));\n    }, [searchResults.fields, searchResults.rows]);\n\n    // Determine view mode based on source type: show list view for external sources,\n    // card view for internal sources\n    const getViewModeFromRecords = (records) => {\n        if (!Array.isArray(records) || records.length === 0) return 'card';\n\n        const hasExternalSource = records.some((record) => {\n            const sourceFields = [\n                record?.sourceType,\n                record?.profileSource,\n                record?.selectedSource,\n                record?.customFields?.sourceType,\n                record?.customFields?.profileSource,\n            ];\n\n            return sourceFields.some((value) => {\n                if (value === null || value === undefined) return false;\n                const normalized = String(value).trim().toLowerCase();\n                if (!normalized) return false;\n                return !['all', 'internal'].includes(normalized);\n            });\n        });\n\n        return hasExternalSource ? 'list' : 'card';\n    };\n\n    const defaultViewMode = useMemo(() => {\n        return getViewModeFromRecords(searchResults.rows);\n    }, [searchResults.rows]);\n\n    const searchFieldsWithActions = useMemo(() => {\n        const sourceActions = getAvailableSourceActions({\n            rows: searchResults.rows,\n            selectedSource,\n        });\n        if (!sourceActions.length) return searchFields;\n\n        const actionFields = new Set(sourceActions.map((action) => action.field));\n        const fieldsWithoutActions = searchFields.filter(\n            (field) => field.cardRole !== 'action' && !actionFields.has(field.value),\n        );\n        return [\n            ...fieldsWithoutActions,\n            ...sourceActions.map((action) => ({\n                value: action.field,\n                field: action.field,\n                label: action.label ?? 'Action',\n                cardRole: 'action',\n                isVisible: true,\n                tableHidden: true,\n                sorter: false,\n                render: (_value, record) => {\n                    if (!sourceActionAppliesToRecord(action, record, selectedSource)) return null;\n                    const actionKey = getSourceActionInstanceKey(action, record);\n                    const state = sourceActionState[actionKey] ?? {};\n                    const missingActionId = !actionKey;\n                    const disabled = missingActionId || state.completed;\n\n                    return (\n                        <Button\n                            type=\"primary\"\n                            size=\"small\"\n                            loading={state.loading}\n                            disabled={disabled}\n                            onClick={() => handleSourceAction(action, record)}\n                        >\n                            {state.completed ? action.completedLabel : action.buttonLabel}\n                        </Button>\n                    );\n                },\n            })),\n        ];\n    }, [handleSourceAction, searchFields, searchResults.rows, selectedSource, sourceActionState]);\n\n    // Merge page-level context (e.g. { jobId }) into every search-result row\n    // action's popupState, so a popup it opens (via ListView's action.route\n    // handling) receives that context too — see the searchActionContext prop.\n    const searchResultActions = useMemo(() => {\n        if (!searchActionContext) return searchResults.actions;\n        const mergeContext = (action) => ({\n            ...action,\n            popupState: { ...searchActionContext, ...action.popupState },\n            ...(action.children ? { children: action.children.map(mergeContext) } : {}),\n        });\n        return (searchResults.actions ?? []).map(mergeContext);\n    }, [searchResults.actions, searchActionContext]);\n\n    // renderGroupBody builds a group's inner controls (the addRow Form.List or\n    // the flat field Row) WITHOUT its Card chrome, so a group flagged\n    // `mergeInto: \"<hostGroupName>\"` can render inside another group's card\n    // (e.g. Rate Details inside Employer) while keeping its own payload,\n    // appendHistory and showIf semantics completely unchanged — the merge is\n    // presentation only.\n    const renderGroupBody = (group) => {\n        const groupName = group.name ?? group.id ?? '';\n        // group.linkGroup: when this group is linked to others, the LEADER owns\n        // the Add button + minRows/requireOne validator for the whole set; every\n        // member (leader + followers) still gets its own Form.List/Card/rows, and\n        // add/remove always go through every member via listControlsRef so row\n        // counts stay equal by construction. Unlinked groups (linkedSet === null,\n        // i.e. every group that predates this feature) fall through leaderGroup\n        // === group, so minRows/rules/initialValue below compute exactly as before.\n        const linkedSet = findLinkedSet(linkedGroupSets, groupName);\n        const isFollower = Boolean(linkedSet) && linkedSet.leaderName !== groupName;\n        const leaderGroup = linkedSet\n            ? (groups.find((g) => g.name === linkedSet.leaderName) ?? group)\n            : group;\n        const minRows = Math.max(0, Number(leaderGroup.minRows ?? 0) || 0);\n        const maxRows = Math.max(0, Number(leaderGroup.maxRows ?? 0) || 0);\n        const linkedMemberNames = linkedSet ? linkedSet.memberNames : [groupName];\n        const addLinkedRow = () => {\n            // New rows start from the group's admin-configured defaults (same\n            // seed the initial rows get), not empty.\n            linkedMemberNames.forEach((name) => {\n                const member = groups.find((g) => g.name === name) ?? group;\n                listControlsRef.current[name]?.add(rowDefaultsFor(member));\n            });\n        };\n        const removeLinkedRow = (rowName) => {\n            linkedMemberNames.forEach((name) => listControlsRef.current[name]?.remove(rowName));\n        };\n        const body = group.addRow ? (\n            <Form.List\n                name={groupName}\n                initialValue={addRowInitials[groupName] ?? []}\n                rules={isFollower ? [] : [\n                    {\n                        validator: async (_, rows = []) => {\n                            // A group switched OFF via its own toggle (e.g. \"Fresher\" hiding\n                            // Work Experience) is not rendered at all — don't force rows on it.\n                            const switchedOn = truthy(group.toggleEnabled) && group.toggleField\n                                && Boolean(form.getFieldValue(group.toggleField));\n                            if (switchedOn) return;\n                            if (minRows > 0 && rows.length < minRows) {\n                                throw new Error(`Keep at least ${minRows} row${minRows > 1 ? 's' : ''}.`);\n                            }\n                            if (truthy(group.requireOne)) {\n                                const invalid = rows.some((row) => !hasMeaningfulValue(row));\n                                if (invalid) throw new Error('Fill at least one field in each added row.');\n                            }\n                        },\n                    },\n                ]}\n            >\n                {(rows, { add, remove, move }, { errors }) => {\n                    // `move` joins the registry so the newest-first prompt can\n                    // reorder a row the user just marked as ongoing. Form.List's\n                    // own move preserves every row's values; rebuilding the\n                    // array by hand would not.\n                    listControlsRef.current[groupName] = { add, remove, move };\n                    return (\n                        <div className=\"v1-addrow-wrapper\">\n                            <div className=\"v1-addrow-topbar\">\n                                {!isFollower ? (\n                                    (!maxRows || rows.length < maxRows) && (\n                                        <Button\n                                            type=\"link\"\n                                            icon={<PlusOutlined />}\n                                            onClick={addLinkedRow}\n                                            className=\"v1-addrow-add-btn\"\n                                        >\n                                            {group.addLabel ?? `Add ${group.label ?? 'Row'}`}\n                                        </Button>\n                                    )\n                                ) : (\n                                    <Text type=\"secondary\" className=\"v1-addrow-linked-hint\">\n                                        Rows added via {leaderGroup.label ?? leaderGroup.name}\n                                    </Text>\n                                )}\n                            </div>\n\n                            {truthy(group.sharedRowLabels) && rows.length > 0 && (\n                                <Row gutter={[24, 0]} className=\"v1-addrow-header\">\n                                    {group.fields.filter((f) => f.show === undefined || truthy(f.show)).map((field) => (\n                                        <Col key={fieldKey(field)} md={field.col ?? 12} className=\"v1-addrow-header-label\">\n                                            {field.label}\n                                        </Col>\n                                    ))}\n                                </Row>\n                            )}\n\n                            {rows.map(({ key: rowKey, name }) => (\n                                <div key={rowKey} className=\"v1-addrow-item\">\n                                    <Button\n                                        type=\"text\"\n                                        danger\n                                        icon={<DeleteOutlined />}\n                                        onClick={() => removeLinkedRow(name)}\n                                        disabled={rows.length <= minRows}\n                                        className=\"v1-addrow-delete-btn\"\n                                    />\n\n                                    <div className=\"v1-addrow-fields\">\n                                        <Row gutter={[24, 0]} align=\"top\">\n                                            {renderFields(group.fields, name, groupName, truthy(group.sharedRowLabels), groupName)}\n                                        </Row>\n                                    </div>\n                                </div>\n                            ))}\n                            <Form.ErrorList errors={errors} />\n                        </div>\n                    );\n                }}\n            </Form.List>\n        ) : (\n            <Row gutter={[24, 0]}>{renderFields(group.fields, undefined, undefined, false, groupName)}</Row>\n        );\n\n        return body;\n    };\n\n    // Groups rendered INSIDE another group's card (group.mergeInto). A child\n    // keeps its own showIf gate and gets a light section title; everything else\n    // (payload, validation, Form.List names) is untouched.\n    const mergedChildrenOf = (group) => groups.filter(\n        (g) => g !== group && g.mergeInto && String(g.mergeInto) === String(group.name),\n    );\n    const isMergedChild = (group) => Boolean(\n        group.mergeInto && groups.some((g) => g !== group && String(g.name) === String(group.mergeInto)),\n    );\n\n    // A merged child renders BEFORE the host's own fields when it declares\n    // `mergePosition: \"top\"`. Needed whenever the child holds the field the\n    // host's fields are conditioned on — Contract Type gates every Employer\n    // field, so rendering it underneath them reads backwards and invites the\n    // user to fill a disabled card first.\n    const mergedAt = (group, position) => mergedChildrenOf(group).filter(\n        (child) => (String(child.mergePosition ?? 'bottom') === position),\n    );\n\n\n    const renderGroup = (group, index) => {\n        const key = group.name ?? group.id ?? String(index);\n        const body = renderGroupBody(group);\n        const mergedTop = mergedAt(group, 'top');\n        const mergedChildren = mergedAt(group, 'bottom');\n\n        // One renderer for both slots, so a merged child behaves identically\n        // whichever side of the host body it sits on.\n        const renderMergedChild = (child) => {\n            const section = (\n                <div key={child.name} className=\"v1-merged-group\">\n                    <div className=\"v1-merged-group-title\">{child.label ?? child.name}</div>\n                    {renderGroupBody(child)}\n                </div>\n            );\n            const gated = child.showIf?.field\n                ? <GroupShowIfGate key={child.name} form={form} showIf={child.showIf} render={() => section} />\n                : section;\n            // Its OWN disabled state, not the host's — see GroupDisabledProvider.\n            return (\n                <GroupDisabledProvider key={child.name} form={form} group={child} inheritParent={false}>\n                    {gated}\n                </GroupDisabledProvider>\n            );\n        };\n\n        return (\n            <Card\n                key={key}\n                className=\"v1-card v1-edit-card\"\n                title={<SectionTitle icon={sectionIcons[index % sectionIcons.length]} title={isSearch ? (searchFormLabel || group.label) : (group.label ?? group.name ?? 'Details')} />}\n                extra={(\n                    <Space size={8} align=\"center\" className=\"v1-group-actions\">\n                        <GroupInfoMessage group={group} />\n                        <GroupToggleControl group={group} />\n                        {/* Opt-in only (group.allowCollapse). Without it there is\n                            no chevron and the section cannot be collapsed — the\n                            behaviour every form had before this was configurable. */}\n                        {truthy(group.allowCollapse) && (\n                            <Button\n                                type=\"text\"\n                                size=\"small\"\n                                aria-expanded={!collapsed[key]}\n                                aria-label={collapsed[key] ? 'Expand section' : 'Collapse section'}\n                                icon={collapsed[key] ? <DownOutlined /> : <UpOutlined />}\n                                onClick={(event) => {\n                                    event.stopPropagation();\n                                    toggle(key);\n                                }}\n                            />\n                        )}\n                    </Space>\n                )}\n            >\n                <Form.Item noStyle shouldUpdate>\n                    {({ getFieldValue }) => {\n                        const switchedOn = truthy(group.toggleEnabled) && group.toggleField && Boolean(getFieldValue(group.toggleField));\n                        return (\n                            <div style={{ display: collapsed[key] || switchedOn ? 'none' : 'block' }}>\n                                {mergedTop.map(renderMergedChild)}\n                                {body}\n                                {mergedChildren.map(renderMergedChild)}\n                            </div>\n                        );\n                    }}\n                </Form.Item>\n            </Card>\n        );\n    };\n\n    return (\n        <main>\n            {breadcrumbItems.length > 0 && <AppBreadcrumb items={breadcrumbItems} />}\n            <div className=\"v1-edit-page\">\n                {hasClientScope && !presetClientId && !linkedClientId && (\n                    <Card className=\"v1-card v1-edit-card v1-client-gate-card\">\n                        <Space direction=\"vertical\" size={12} style={{ width: '100%' }}>\n                            <SectionTitle icon={<UserOutlined />} title=\"Select Client\" />\n                            {clientGateMessage && <Text type=\"secondary\">{clientGateMessage}</Text>}\n                            <Row gutter={[16, 0]}>\n                                <Col xs={24} md={14}>\n                                    <Select\n                                        showSearch\n                                        allowClear\n                                        placeholder=\"Select client\"\n                                        style={{ width: '100%' }}\n                                        value={effectiveClientId || undefined}\n                                        optionFilterProp=\"label\"\n                                        options={clientOptions.map((c) => ({\n                                            value: c._id ?? c.id,\n                                            label: c.clientName ?? c.name ?? c.clientRefrenceId ?? c._id,\n                                        })).filter((c) => c.value)}\n                                        onChange={handleClientGateChange}\n                                        dropdownRender={clientGateQuick.footer\n                                            ? (menu) => (<>{menu}{clientGateQuick.footer}</>)\n                                            : undefined}\n                                    />\n                                    {clientGateQuick.modal}\n                                </Col>\n                            </Row>\n                        </Space>\n                    </Card>\n                )}\n                <div className=\"v1-page-inner\">\n                    {/* Async work gets its OWN viewport-centred overlay.\n                        The wrapping Spin below centres its indicator inside the\n                        element it wraps — on a form this long that lands\n                        somewhere in the middle of the page, which after any\n                        scrolling is off screen entirely. Reading a résumé takes\n                        seconds, so the user is left looking at a frozen form\n                        with no visible sign that anything is happening.\n                        `fullscreen` pins it to the centre of the VIEWPORT with\n                        a scrim, so it is where the user is looking whatever\n                        they have scrolled to. */}\n                    <Spin\n                        fullscreen\n                        spinning={aiActions.busy || duplicates.checking}\n                        size=\"large\"\n                        tip={\n                            aiActions.busy\n                                ? (aiActions.loadingText || 'Reading the file…')\n                                : 'Checking whether we already have this person…'\n                        }\n                    />\n                    <Spin\n                        spinning={!isFormReady && !waitingForClientScope}\n                        description=\"Loading form fields…\"\n                    >\n                        <Form\n                            form={form}\n                            layout=\"vertical\"\n                            colon={false}\n                            className=\"v1-form\"\n                            // Disabled during the duplicate check too — it can\n                            // end by navigating away, and letting someone keep\n                            // typing into a form that is about to be abandoned\n                            // loses whatever they add in those seconds.\n                            disabled={aiActions.busy || duplicates.checking}\n                            requiredMark={(label, { required }) => (\n                                <>\n                                    {label}\n                                    {required && <span className=\"v1-required-mark\"> *</span>}\n                                </>\n                            )}\n                            onFinish={submit}\n                            onFinishFailed={(info) => {\n                                // Expand collapsed sections first — a hidden error\n                                // field can't be scrolled to or focused.\n                                setCollapsed({});\n                                scrollToFirstFormError(info, form);\n                            }}\n                        >\n                            {isFormReady && groups.filter((g) => !isMergedChild(g)).map((group, index) => (\n                                <GroupDisabledProvider key={group.name ?? `grp-${index}`} form={form} group={group}>\n                                    {group.showIf?.field\n                                        ? <GroupShowIfGate form={form} showIf={group.showIf} render={() => renderGroup(group, index)} />\n                                        : renderGroup(group, index)}\n                                </GroupDisabledProvider>\n                            ))}\n                            {isFormReady && !error && groups.length === 0 && (\n                                <Alert type=\"info\" showIcon message={isSearch ? \"No search configuration found.\" : \"No form fields are configured.\"} />\n                            )}\n                            {isFormReady && isSearch && (\n                                <div className=\"v1-search-form-actions\">\n                                    <Space size={12}>\n                                        <Button onClick={handleReset} disabled={!groups.length}>\n                                            Reset\n                                        </Button>\n                                        <Button onClick={() => goBackOrTo(navigate, { cancelPath })}>\n                                            Back\n                                        </Button>\n                                        <Button\n                                            type=\"primary\"\n                                            htmlType=\"submit\"\n                                            disabled={submitLoading || !groups.length || searchDisabled}\n                                            loading={submitLoading}\n                                        >\n                                            {submitText}\n                                        </Button>\n                                    </Space>\n                                </div>\n                            )}\n                        </Form>\n                    </Spin>\n                </div>\n\n                {!isSearch && (\n                    <div className={embedded ? 'v1-footer v1-footer--embedded' : 'v1-footer'}>\n                        <Text type=\"secondary\">All Unsaved Changes will be lost if you cancel and reload.</Text>\n                        <Space size={12}>\n                            <Button onClick={() => (embedded && onCancel\n                                ? onCancel()\n                                : goBackOrTo(navigate, { cancelPath }))}>Cancel</Button>\n                            {formActions.map((action, index) => (\n                                <FormActionButton\n                                    key={`${action.label ?? 'action'}-${index}`}\n                                    form={form}\n                                    groups={groups}\n                                    action={action}\n                                    disabled={!isFormReady || submitLoading || uniquePending > 0 || !groups.length}\n                                    loading={submitLoading}\n                                    onFire={() => {\n                                        pendingAfterSubmitRef.current = action.afterSubmit ?? { mode: 'stay' };\n                                        // Opt-in only — an action can force specific field\n                                        // values right before submitting (e.g. a distinct\n                                        // \"Schedule\" button implying scheduleForLater=true\n                                        // without requiring the checkbox to be checked).\n                                        if (action.setValuesBeforeSubmit) {\n                                            form.setFieldsValue(action.setValuesBeforeSubmit);\n                                        }\n                                        form.submit();\n                                    }}\n                                />\n                            ))}\n                            <ValidationGatedSubmitButton\n                                form={form}\n                                groups={groups}\n                                onClick={() => { pendingAfterSubmitRef.current = null; form.submit(); }}\n                                // A pending uniqueness check must resolve before\n                                // the record can be created.\n                                disabled={!isFormReady || submitLoading || uniquePending > 0 || !groups.length}\n                                loading={submitLoading}\n                            >\n                                {submitText}\n                            </ValidationGatedSubmitButton>\n                        </Space>\n                    </div>\n                )}\n\n                {/* Search results ListView — rendered inside AddFormV1 when in search mode */}\n                {isSearch && searchResults.searched && (\n                    <ListView\n                        moduleName={moduleName}\n                        breadcrumbItems={[]}\n                        dataSource={searchResults.rows}\n                        fields={searchFieldsWithActions}\n                        total={searchResults.total}\n                        loading={searchResults.loading}\n                        current={searchPagination.current}\n                        pageSize={searchPagination.pageSize}\n                        showViewToggle\n                        activeView={viewMode}\n                        onViewChange={setViewMode}\n                        onPageChange={handleSearchPageChange}\n                        onPageSizeChange={handleSearchPageSizeChange}\n                        showSearch={false}\n                        tabs={tabs}\n                        selectedSource={selectedSource}\n                        onTabChange={handleTabChange}\n                        actions={searchResultActions}\n                        actionRules={searchResults.actionRules}\n                    />\n                )}\n            </div>\n        </main>\n    );\n});\n","import { Alert } from 'antd';\nimport '../styles/AppAlert.css';\n\nexport default function AppAlert({\n  className = '',\n  variant = 'default',\n  showIcon = true,\n  ...rest\n}) {\n  return (\n    <Alert\n      className={`app-alert app-alert--${variant} ${className}`.trim()}\n      showIcon={showIcon}\n      {...rest}\n    />\n  );\n}\n","import { formatApp, formatAppDateTime, appNow, toApp } from '../../services/timezone';\nimport { getDefaults } from '../../services/detailDefaults';\n/* Relative day label for a group header: Today / 1 Day ago / N Days ago.\n *\n * Measured in the TENANT's day, not the browser's. Mixing the two is how a note\n * written at 11pm IST ends up filed under \"1 Day ago\" for a colleague reading\n * it from London — the row already prints its time in the tenant zone, so the\n * header has to agree with it. */\nexport function relativeDay(date) {\n  const today = appNow().startOf('day');\n  const diffDays = today.diff(toApp(date).startOf('day'), 'day');\n\n  if (diffDays <= 0) return 'Today';\n  if (diffDays === 1) return '1 Day ago';\n  return `${diffDays} Days ago`;\n}\n\n/* Group timeline rows by calendar day, newest day first.\n *\n * The day boundary is the TENANT's midnight. Grouping by the browser's while\n * each row prints the tenant's time put rows under a day their own timestamp\n * contradicted — the mismatch was visible on screen. */\nexport function groupByDay(rows = [], getTime) {\n  const groups = new Map();\n\n  rows.forEach((row) => {\n    const value = getTime(row);\n    const local = toApp(value);\n    if (!local.isValid()) return;\n    const key = local.format('YYYY-MM-DD');\n    if (!groups.has(key)) {\n      // `date` is kept as a real Date for the header label and the sort; it is\n      // the same instant, only the DAY it is filed under is tenant-scoped.\n      groups.set(key, { date: new Date(local.valueOf()), items: [] });\n    }\n    groups.get(key).items.push(row);\n  });\n\n  return [...groups.values()].sort((a, b) => b.date - a.date);\n}\n\n/* dateOnlyFormat — the DATE half of the tenant's configured date-time format.\n *\n * Derived rather than hardcoded so a day header and a full timestamp cannot\n * disagree about how a date is written. With the default\n * \"MMM DD, YYYY | hh:mm A\" this yields \"MMM DD, YYYY\", so a group header reads\n * \"Aug 06, 2026\" and the row beneath it \"Aug 06, 2026 | 10:07 AM IST\" — the\n * same date, spelled the same way.\n *\n * The separator is the pipe the format already uses to divide the two halves.\n * A format with no pipe is used whole: it is presumably date-only already, and\n * inventing a split would be a guess. */\nfunction dateOnlyFormat(defaults) {\n  const full = defaults?.dateTimeFormat || 'MMM DD, YYYY | hh:mm A';\n  const [datePart] = full.split('|');\n  return (datePart ?? full).trim() || full;\n}\n\n/* Full date-only label, tenant zone. Used for the tooltip and anywhere a day\n * is named on its own. */\nexport function formatDate(value) {\n  const defaults = getDefaults();\n  return formatApp(value, dateOnlyFormat(defaults), defaults);\n}\n\n/* The day a group of rows is filed under. Same spelling as the date half of\n * every timestamp below it. */\nexport function formatShortDate(value) {\n  return formatDate(value);\n}\n\n/* The timestamp on an activity or note row.\n *\n * ONE value in the tenant's standard format — \"Aug 06, 2026 | 10:07 AM IST\" —\n * not a time and a date rendered separately, in the opposite order, with a\n * different date spelling from every other timestamp in the app. That is what\n * this was: \"10:07 AM EST/EDT\" and \"Aug 6, 2026\" as two spans, reading\n * time-then-date, while the record header two inches above read\n * \"Aug 06, 2026 | 07:03 PM\".\n *\n * It goes through formatAppDateTime like every other timestamp, so it follows\n * the admin's date format, the admin's time zone, and the admin's choice about\n * whether the zone label is shown. */\nexport function formatTimestamp(value) {\n  return formatAppDateTime(value, getDefaults());\n}\n","import { Collapse, Empty } from 'antd';\nimport { groupByDay, relativeDay, formatShortDate, formatTimestamp } from './timelineUtils';\n\n// One row: dot + connector rail, then the body and a single muted meta line\n// (author · time · date). Shared by both the grouped (Collapse-of-days) and\n// flat rendering below, so a row looks identical either way.\nfunction TimelineRow({ row, last, getTime, getAuthor, getMeta, renderBody }) {\n  const time = getTime(row);\n  const author = getAuthor?.(row);\n  const meta = getMeta?.(row);\n\n  return (\n    <div className=\"znx-an-item\">\n      <div className=\"znx-an-rail\">\n        {meta ? (\n          <span\n            className={`znx-an-icon-dot znx-an-icon-dot--${meta.tone}`}\n            title={meta.label}\n          >\n            {meta.icon}\n          </span>\n        ) : (\n          <span className=\"znx-an-dot\" />\n        )}\n        {!last && <span className=\"znx-an-line\" />}\n      </div>\n      <div className=\"znx-an-content\">\n        {renderBody(row)}\n        <div className=\"znx-an-meta\">\n          {author && (\n            <>\n              <span className=\"znx-an-author\">{author}</span>\n              <span className=\"znx-an-sep\" aria-hidden=\"true\" />\n            </>\n          )}\n          {/* One timestamp, in the tenant's standard format, reading date then\n              time — the same as every other timestamp in the app. It used to be\n              two spans in the opposite order with a different date spelling. */}\n          <span className=\"znx-an-stamp\">{formatTimestamp(time)}</span>\n        </div>\n      </div>\n    </div>\n  );\n}\n\n/*\n * Renders timeline rows either grouped into a Collapse of calendar days\n * (default) or, with `grouped={false}`, as one flat list — same row markup\n * either way, just without the day-header/collapse chrome. `getTime` reads\n * the row's timestamp, `renderBody` renders the row-specific content (note\n * text / activity html) and the optional `getAuthor` supplies a name for the\n * meta line.\n *\n * Reading order inside a row is message first, then a single muted meta line\n * (author · time · date). The message is what the user came for; the timestamp\n * is a reference they only reach for once the message has landed.\n */\nexport default function TimelineGroups({\n  rows = [],\n  getTime,\n  getKey,\n  getAuthor,\n  getMeta,\n  renderBody,\n  emptyText = 'Nothing here yet.',\n  grouped = true,\n}) {\n  if (!grouped) {\n    if (!rows.length) {\n      return (\n        <div className=\"znx-an-empty\">\n          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={emptyText} />\n        </div>\n      );\n    }\n    return (\n      <div className=\"znx-an-flat\">\n        {rows.map((row, rowIndex) => (\n          <TimelineRow\n            key={getKey(row, rowIndex)}\n            row={row}\n            last={rowIndex === rows.length - 1}\n            getTime={getTime}\n            getAuthor={getAuthor}\n            getMeta={getMeta}\n            renderBody={renderBody}\n          />\n        ))}\n      </div>\n    );\n  }\n\n  const groups = groupByDay(rows, getTime);\n\n  if (!groups.length) {\n    return (\n      <div className=\"znx-an-empty\">\n        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={emptyText} />\n      </div>\n    );\n  }\n\n  const items = groups.map((group, groupIndex) => ({\n    key: String(groupIndex),\n    // The full day lives here, once per group, instead of being repeated on\n    // every row underneath it.\n    label: (\n      <span className=\"znx-an-group\">\n        <span className=\"znx-an-group-day\">{relativeDay(group.date)}</span>\n        <span className=\"znx-an-group-date\">{formatShortDate(group.date)}</span>\n        <span className=\"znx-an-group-count\">{group.items.length}</span>\n      </span>\n    ),\n    children: group.items.map((row, rowIndex) => (\n      <TimelineRow\n        key={getKey(row, rowIndex)}\n        row={row}\n        last={rowIndex === group.items.length - 1}\n        getTime={getTime}\n        getAuthor={getAuthor}\n        getMeta={getMeta}\n        renderBody={renderBody}\n      />\n    )),\n  }));\n\n  return (\n    <Collapse\n      className=\"znx-an-collapse\"\n      defaultActiveKey={['0']}\n      ghost\n      items={items}\n    />\n  );\n}\n","import {\n  PlusOutlined,\n  EditOutlined,\n  MessageOutlined,\n  UserSwitchOutlined,\n  SendOutlined,\n  RedoOutlined,\n  CheckOutlined,\n  CloseOutlined,\n  UndoOutlined,\n  DeleteOutlined,\n  SwapOutlined,\n  PaperClipOutlined,\n  ClockCircleOutlined,\n  HistoryOutlined,\n} from '@ant-design/icons';\n\n/*\n * Maps an activity/history row to a small, meaningful icon + accent color\n * instead of one repeated dot for every event. Keyed by the backend's loose\n * `activityType` (case-insensitive, values are inconsistent across services —\n * \"add\" | \"Assignment\" | \"Submitted\" | \"reject_days\" | ... — so this is an\n * alias table, not an enum) with a keyword fallback over the comment text for\n * older rows that never got a type.\n *\n * Shared by the generic Activity tab (jobs/candidates/submissions/onboarding/\n * assignment/client) and Timesheet's review history, so \"approved\" looks the\n * same shade of green everywhere in the app.\n */\nconst TYPE_ALIASES = {\n  add: 'created',\n  create: 'created',\n  created: 'created',\n\n  update: 'updated',\n  updated: 'updated',\n  edit: 'updated',\n  edited: 'updated',\n  // Timesheet-specific: a day's hours/logs edited, or the proof screenshot\n  // replaced, during the rejected/reopened correction window before a\n  // resubmit — see ReviewHistoryCard in the ZINNEXT-V2 Timesheet pages.\n  update_log: 'updated',\n  update_proof: 'updated',\n\n  notes: 'note',\n  note: 'note',\n  comment: 'note',\n\n  assign: 'assigned',\n  assigned: 'assigned',\n  assignment: 'assigned',\n  reassign: 'assigned',\n  reassigned: 'assigned',\n\n  submit: 'submitted',\n  submitted: 'submitted',\n  submission: 'submitted',\n  'internal submission': 'submitted',\n  send_for_approval: 'sendForApproval',\n  'send for approval': 'sendForApproval',\n  sendforapproval: 'sendForApproval',\n\n  resubmit: 'resubmitted',\n  resubmitted: 'resubmitted',\n  // A manager's Re-Approve \"Send For Approval\" (rate corrected after a CFO\n  // rejection, resent to the CFO) — distinct from a fresh \"approved\" so the\n  // timeline doesn't show two approvals for one request.\n  resent_for_approval: 'resent',\n\n  reject: 'rejected',\n  rejected: 'rejected',\n  reject_days: 'rejected',\n  declined: 'rejected',\n  decline: 'rejected',\n\n  approve: 'approved',\n  approved: 'approved',\n  approve_days: 'approved',\n\n  reopen: 'reopened',\n  reopened: 'reopened',\n\n  delete: 'deleted',\n  deleted: 'deleted',\n  remove: 'deleted',\n  removed: 'deleted',\n\n  status: 'status',\n  'status change': 'status',\n  statuschange: 'status',\n\n  document: 'document',\n  documents: 'document',\n  upload: 'document',\n  uploaded: 'document',\n  attachment: 'document',\n};\n\nconst ACTION_META = {\n  created:      { tone: 'success', icon: <PlusOutlined />,       label: 'Created' },\n  updated:      { tone: 'info',    icon: <EditOutlined />,       label: 'Updated' },\n  note:         { tone: 'neutral', icon: <MessageOutlined />,    label: 'Note' },\n  assigned:     { tone: 'purple',  icon: <UserSwitchOutlined />, label: 'Assigned' },\n  submitted:    { tone: 'info',    icon: <SendOutlined />,       label: 'Submitted' },\n  sendForApproval: { tone: 'info', icon: <SendOutlined />,       label: 'Send for Approval' },\n  resubmitted:  { tone: 'purple',  icon: <RedoOutlined />,       label: 'Re-submitted' },\n  resent:       { tone: 'purple',  icon: <RedoOutlined />,       label: 'Resend for Approval' },\n  approved:     { tone: 'success', icon: <CheckOutlined />,      label: 'Approved' },\n  rejected:     { tone: 'danger',  icon: <CloseOutlined />,      label: 'Rejected' },\n  reopened:     { tone: 'neutral', icon: <UndoOutlined />,       label: 'Reopened' },\n  deleted:      { tone: 'danger',  icon: <DeleteOutlined />,     label: 'Deleted' },\n  status:       { tone: 'warning', icon: <SwapOutlined />,       label: 'Status changed' },\n  document:     { tone: 'info',    icon: <PaperClipOutlined />,  label: 'Document' },\n  scheduled:    { tone: 'warning', icon: <ClockCircleOutlined />, label: 'Scheduled' },\n  default:      { tone: 'neutral', icon: <HistoryOutlined />,    label: 'Activity' },\n};\n\n// Fallback keyword sniff for rows with no (or an unrecognized) activityType —\n// mostly older free-text activityComments like \"Job created and assigned...\".\nconst KEYWORD_ACTIONS = [\n  // Must be checked before the generic `approv` rule. These descriptions\n  // contain the word \"approval\", but represent a request sent to the CFO,\n  // not an approval completed by the CFO.\n  [/\\b(?:submitted|sent|send)\\b[\\s\\S]*\\b(?:cfo|finance)\\b[\\s\\S]*\\bfor approval\\b/i, 'sendForApproval'],\n  [/\\bsend(?:ing)?\\s+for\\s+approval\\b/i, 'sendForApproval'],\n  [/\\breject/i, 'rejected'],\n  // Checked BEFORE the broad \\bapprov match: a resend sentence naturally\n  // contains \"...for CFO approval\" (matches \\bapprov too), so resend/resubmit\n  // must win first or every resend keyword-falls-back to \"Approved\".\n  [/\\bresent\\b/i, 'resent'],\n  [/\\bresubmit/i, 'resubmitted'],\n  [/\\bapprov/i, 'approved'],\n  [/\\bsubmit/i, 'submitted'],\n  [/\\breassign|\\bassign/i, 'assigned'],\n  [/\\bdelete|\\bremov/i, 'deleted'],\n  [/\\breopen/i, 'reopened'],\n  [/\\bstatus/i, 'status'],\n  [/\\bdocument|\\battach|\\bupload/i, 'document'],\n  [/\\bnote/i, 'note'],\n  [/\\bupdat|\\bchang|\\bedit/i, 'updated'],\n  [/\\bcreat|\\badded\\b/i, 'created'],\n];\n\nfunction resolveAction(activityType, text) {\n  const typeKey = String(activityType || '').trim().toLowerCase();\n  if (typeKey && TYPE_ALIASES[typeKey]) return TYPE_ALIASES[typeKey];\n\n  const plain = String(text || '');\n  for (const [pattern, action] of KEYWORD_ACTIONS) {\n    if (pattern.test(plain)) return action;\n  }\n  return 'default';\n}\n\n/* row: activity/history entry — reads activityType/action + a text fallback. */\nexport function resolveActivityMeta(row = {}, plainText = '') {\n  const activityType =\n    row.activityType ??\n    row.activity_type ??\n    row.type ??\n    row.action;\n  const action = resolveAction(activityType, plainText || row.activityComments);\n  return ACTION_META[action] ?? ACTION_META.default;\n}\n\n","import { useMemo } from 'react';\nimport TimelineGroups from './timeline';\nimport { resolveActivityMeta } from './activityMeta';\n\n/* Strip any HTML tags so activity comments render as clean plain text. */\nfunction toPlainText(html = '') {\n  if (typeof document === 'undefined') return String(html);\n  const holder = document.createElement('div');\n  holder.innerHTML = html;\n  return holder.textContent || holder.innerText || '';\n}\n\nconst sampleActivity = [\n  {\n    id: 'a1',\n    activityTime: new Date().toISOString(),\n    activityComments: 'Job <b>created</b> and assigned to the recruitment team.',\n  },\n  {\n    id: 'a2',\n    activityTime: new Date(Date.now() - 2 * 86400000).toISOString(),\n    activityComments: 'Status changed to <b>Active</b>.',\n  },\n];\n\nexport default function ActivityTab({ activity, grouped = true }) {\n  const rows = useMemo(() => {\n    const source = Array.isArray(activity) ? activity : sampleActivity;\n    return [...source].sort((left, right) => {\n      const leftTime = new Date(\n        left?.activityTime ?? left?.activityDateTime ?? left?.performedAt ?? left?.createdAt ?? left?.updatedAt ?? 0,\n      ).getTime();\n      const rightTime = new Date(\n        right?.activityTime ?? right?.activityDateTime ?? right?.performedAt ?? right?.createdAt ?? right?.updatedAt ?? 0,\n      ).getTime();\n      return (Number.isNaN(rightTime) ? 0 : rightTime) - (Number.isNaN(leftTime) ? 0 : leftTime);\n    });\n  }, [activity]);\n\n  return (\n    <div className=\"znx-an-body\">\n      <div className=\"znx-an-scroll\">\n        <TimelineGroups\n          rows={rows}\n          grouped={grouped}\n          getTime={(row) => row.activityTime ?? row.createdAt}\n          getKey={(row, index) => row.id ?? row._id ?? index}\n          emptyText=\"No activity here.\"\n          getMeta={(row) => resolveActivityMeta(row, row.activityComments)}\n          renderBody={(row) => {\n            const meta = resolveActivityMeta(row, row.activityComments);\n            return (\n              <div className=\"znx-an-comment\">\n                <span className={`znx-an-tag znx-an-tag--${meta.tone}`}>{meta.label}</span>\n                {toPlainText(row.activityComments)}\n              </div>\n            );\n          }}\n        />\n      </div>\n    </div>\n  );\n}\n","import { useMemo, useRef, useState } from 'react';\nimport { Button, Form, Mentions, message } from 'antd';\nimport TimelineGroups from './timeline';\nimport { getMentionUsers } from '../../services/dropdownApi';\n\n/* Turn one API user record into a { value, label } mention option.\n * value is the inserted token (kept space-free so the @mention renders as a\n * single tag); label is the friendlier name shown in the dropdown. */\nfunction normalizeMentionUser(item) {\n  const userName = item?.user_name ?? item?.userName ?? item?.username;\n  const first = item?.first_name ?? item?.firstName ?? '';\n  const last = item?.last_name ?? item?.lastName ?? '';\n  const fullName = `${first} ${last}`.trim();\n  const email = item?.email ?? '';\n  const value = userName ?? fullName.replace(/\\s+/g, '') ?? email\n    ?? String(item?.user_id ?? item?.id ?? '');\n  const label = [userName, fullName, email].filter(Boolean).join(' - ') || String(value);\n  return { value: String(value), label };\n}\n\nconst sampleNotes = [\n  {\n    id: 'n1',\n    createdAt: new Date().toISOString(),\n    author: 'You',\n    notes: 'Shortlisted 3 candidates, sharing profiles with @Hiring Manager today.',\n  },\n];\n\n/* Render note text, turning @mentions into inline brand-tinted chips. A borderless\n * inline chip sits on the text baseline; an antd Tag carries its own margins and\n * border and breaks the line rhythm of a sentence it is embedded in. */\nfunction renderNoteText(text = '') {\n  return text.split(/(\\s+)/).map((chunk, index) => {\n    if (chunk.startsWith('@') && chunk.length > 1) {\n      return (\n        <span className=\"znx-an-mention\" key={index}>\n          {chunk}\n        </span>\n      );\n    }\n    return <span key={index}>{chunk}</span>;\n  });\n}\n\n// `allowAddNote={false}` renders the tab read-only — the timeline without the\n// composer. For a host whose notes are authored somewhere else entirely (the\n// timesheet pages have their own Notes / Comments field on a different store),\n// the composer here is a second, unrelated place to write about the same\n// record; hiding it keeps the history readable without inviting a split.\nexport default function NotesTab({ notes, users = [], onAddNote, allowAddNote = true }) {\n  const [form] = Form.useForm();\n  const [localNotes, setLocalNotes] = useState(() =>\n    Array.isArray(notes) ? notes : sampleNotes,\n  );\n  const [posting, setPosting] = useState(false);\n  // Live mention users fetched from the API when the user types after '@'.\n  // null = not searched yet → fall back to any users passed in via props.\n  const [mentionUsers, setMentionUsers] = useState(null);\n  const [mentionLoading, setMentionLoading] = useState(false);\n  const searchTimer = useRef(null);\n\n  const rows = Array.isArray(notes) ? notes : localNotes;\n\n  const fallbackOptions = useMemo(\n    () => users.map((user) => ({ value: user.display ?? user.value, label: user.display ?? user.label })),\n    [users],\n  );\n  const mentionOptions = mentionUsers ?? fallbackOptions;\n\n  // Debounced @-mention search → calls the shared getMentionUsers API and\n  // lists matching users in the Mentions dropdown.\n  const handleMentionSearch = (search) => {\n    clearTimeout(searchTimer.current);\n    setMentionLoading(true);\n    searchTimer.current = setTimeout(() => {\n      getMentionUsers(search)\n        .then((data) => {\n          const raw = Array.isArray(data) ? data : (data?.items ?? data?.list ?? data?.data ?? []);\n          setMentionUsers(raw.map(normalizeMentionUser));\n        })\n        .catch(() => setMentionUsers([]))\n        .finally(() => setMentionLoading(false));\n    }, 300);\n  };\n\n  const handlePost = async ({ note }) => {\n    const text = (note ?? '').trim();\n    if (!text) return;\n\n    setPosting(true);\n    try {\n      if (onAddNote) {\n        await onAddNote(text);\n      } else {\n        setLocalNotes((prev) => [\n          { id: `local-${Date.now()}`, createdAt: new Date().toISOString(), author: 'You', notes: text },\n          ...prev,\n        ]);\n      }\n      form.resetFields();\n      message.success('Notes added successfully');\n    } catch {\n      message.error('Something went wrong, please try again.');\n    } finally {\n      setPosting(false);\n    }\n  };\n\n  return (\n    <div className=\"znx-an-body\">\n      {allowAddNote && (\n        <Form form={form} onFinish={handlePost} className=\"znx-an-composer\">\n          <Form.Item\n            name=\"note\"\n            rules={[{ required: true, message: 'Notes is required' }]}\n            style={{ marginBottom: 0 }}\n          >\n            <Mentions\n              rows={3}\n              prefix=\"@\"\n              options={mentionOptions}\n              loading={mentionLoading}\n              filterOption={false}\n              onSearch={handleMentionSearch}\n              placeholder=\"Add your notes on the job, use '@' to mention\"\n            />\n          </Form.Item>\n          <div className=\"znx-an-composer-actions\">\n            <Button type=\"primary\" size=\"small\" htmlType=\"submit\" loading={posting}>\n              Post\n            </Button>\n          </div>\n        </Form>\n      )}\n\n      {/* getAuthor: createdByName is the field persisted on the note document;\n          `author` is the wire-only alias the API also stamps. `||` not `??` —\n          the backend sends \"\" (not undefined) when a name cannot be resolved,\n          and timeline.jsx renders no attribution at all for a falsy value,\n          which is the right outcome: blank beats \"User #12\". */}\n      <div className=\"znx-an-scroll\">\n        <TimelineGroups\n          rows={rows}\n          getTime={(row) => row.createdAt ?? row.activityTime}\n          getKey={(row, index) => row.id ?? row._id ?? index}\n          getAuthor={(row) => row.createdByName || row.author || ''}\n          emptyText=\"No notes here.\"\n          renderBody={(row) => (\n            <div className=\"znx-an-comment\">{renderNoteText(row.notes)}</div>\n          )}\n        />\n      </div>\n    </div>\n  );\n}\n","import PropTypes from 'prop-types';\nimport { useCallback, useEffect, useState } from 'react';\nimport { Card } from 'antd';\nimport { createNote, getActivity, getNotes } from '../../services/detailedViewApi';\nimport DynamicTabs from '../DynamicTabs';\nimport ActivityTab from './ActivityTab';\nimport NotesTab from './NotesTab';\nimport '../../styles/activity-notes.css';\n\n/*\n * Self-contained \"Activity & Notes\" card used on the right rail of a detail\n * view. Holds two tabs — Activity (read-only timeline) and Notes (composer +\n * timeline).\n *\n * Given `moduleName` + `id` it fetches its own Activity & Notes and posts new\n * notes back to the API. DetailViewPage just passes moduleName + id; when those\n * are absent each tab falls back to its own sample data so the card still\n * renders standalone.\n */\nexport default function ActivityNotesCard({\n  moduleName,\n  id,\n  users = [],\n  showActivity = true,\n  showNotes = true,\n  allowAddNote = true,\n  defaultActiveKey = 'activity',\n  refreshKey = 0,\n  className = '',\n}) {\n  const [activity, setActivity] = useState(null);\n  const [notes, setNotes] = useState(null);\n\n  // Load the Activity & Notes for the current record.\n  useEffect(() => {\n    if (!moduleName || !id) return undefined;\n\n    let cancelled = false;\n\n    async function fetchActivityAndNotes() {\n      const [activityData, notesData] = await Promise.all([\n        showActivity ? getActivity(moduleName, id).catch(() => []) : Promise.resolve(null),\n        showNotes ? getNotes(id).catch(() => []) : Promise.resolve(null),\n      ]);\n      if (!cancelled) {\n        setActivity(activityData);\n        setNotes(notesData);\n      }\n    }\n\n    fetchActivityAndNotes();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [moduleName, id, showActivity, showNotes, refreshKey]);\n\n  const handleAddNote = useCallback(\n    async (text) => {\n      if (!id) return;\n      // Pass the module so the backend tags the note and logs the activity.\n      await createNote({ relatedId: id, notes: text, notesFor: moduleName });\n      // A new note also creates an activity entry, so refresh both timelines.\n      const [notesData, activityData] = await Promise.all([\n        getNotes(id).catch(() => []),\n        showActivity ? getActivity(moduleName, id).catch(() => []) : Promise.resolve(activity),\n      ]);\n      setNotes(notesData);\n      if (showActivity) setActivity(activityData);\n    },\n    [id, moduleName, showActivity, activity],\n  );\n\n  // Only render the tabs that are enabled for this page.\n  const tabs = [\n    showActivity && {\n      key: 'activity',\n      title: 'Activity',\n      count: Array.isArray(activity) ? activity.length : undefined,\n      children: <ActivityTab activity={activity} />,\n    },\n    showNotes && {\n      key: 'notes',\n      title: 'Notes',\n      count: Array.isArray(notes) ? notes.length : undefined,\n      children: (\n        <NotesTab\n          notes={notes}\n          users={users}\n          allowAddNote={allowAddNote}\n          onAddNote={id ? handleAddNote : undefined}\n        />\n      ),\n    },\n  ].filter(Boolean);\n\n  // Fall back to the first available tab if the default one is hidden.\n  const initialKey = tabs.some((tab) => tab.key === defaultActiveKey)\n    ? defaultActiveKey\n    : tabs[0]?.key;\n  const [activeKey, setActiveKey] = useState(initialKey);\n\n  return (\n    <Card className={['znx-an-card', className].filter(Boolean).join(' ')} styles={{ body: { padding: 0 } }}>\n      <DynamicTabs\n        className=\"znx-an-tabs\"\n        tabs={tabs}\n        activeKey={activeKey}\n        onChange={setActiveKey}\n      />\n    </Card>\n  );\n}\n\nActivityNotesCard.propTypes = {\n  moduleName: PropTypes.string,\n  id: PropTypes.string,\n  users: PropTypes.array,\n  showActivity: PropTypes.bool,\n  showNotes: PropTypes.bool,\n  // Set false to render the Notes tab read-only: the timeline stays, the\n  // composer goes. For hosts that author notes elsewhere (Timesheet keeps its\n  // own Notes / Comments field, on a different store) — the tab would\n  // otherwise be a second, unconnected place to write about the same record.\n  allowAddNote: PropTypes.bool,\n  defaultActiveKey: PropTypes.string,\n  refreshKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n  // Extra class(es) on the outer Card — e.g. a host page's own sizing hooks\n  // (flex-fill sidebar, height caps) layered on top of the base znx-an-card\n  // look, without the host having to reimplement the card shell.\n  className: PropTypes.string,\n};\n","import { Avatar, Tooltip } from 'antd';\n\nexport default function AssigneeAvatars({ assignees, extraAssignees }) {\n  return (\n    <Avatar.Group maxCount={3} size=\"small\">\n      {assignees.map((a, i) => (\n        <Tooltip title={a.initials} key={i}>\n          <Avatar\n            size=\"small\"\n            style={{ backgroundColor: a.color, fontSize: 10, fontWeight: 600, cursor: 'default' }}\n          >\n            {a.initials}\n          </Avatar>\n        </Tooltip>\n      ))}\n      {extraAssignees > 0 && (\n        <Avatar size=\"small\" style={{ backgroundColor: '#d9d9d9', color: '#555', fontSize: 10 }}>\n          +{extraAssignees}\n        </Avatar>\n      )}\n    </Avatar.Group>\n  );\n}\n","// ───────────────────────────────────────────────────────────────────────────\n// Client-side gate for BulkUploadPanel.\n//\n// A drag-and-drop bypasses the OS file dialog's `accept` filter entirely, so\n// the extension / MIME / size rules here are what actually stop a .pdf or a\n// .jpeg from reaching the importer. Kept in its own module (not in the panel)\n// so it can be unit-tested and reused without pulling in React.\n// ───────────────────────────────────────────────────────────────────────────\n\nexport const DEFAULT_ACCEPT = ['.xlsx', '.xls', '.csv'];\nexport const DEFAULT_MAX_SIZE_MB = 10;\n\n// Extension → the MIME types a browser reports for it. Also fed to the file\n// input's `accept` so the OS dialog greys out everything else up front.\nexport const MIME_BY_EXTENSION = {\n  '.xlsx': ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],\n  '.xls': ['application/vnd.ms-excel'],\n  '.csv': ['text/csv', 'application/csv', 'text/plain'],\n};\n\n// Friendlier rejection copy for the types people actually try by mistake —\n// a saved-as-PDF invoice, or a phone photo of a printed sheet.\nconst REJECTION_HINTS = [\n  { test: (ext, type) => ext === '.pdf' || type === 'application/pdf', label: 'PDF' },\n  {\n    test: (ext, type) =>\n      type.startsWith('image/') ||\n      ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.heic', '.bmp', '.svg'].includes(ext),\n    label: 'Image',\n  },\n  { test: (ext) => ['.doc', '.docx'].includes(ext), label: 'Word document' },\n  { test: (ext) => ['.zip', '.rar', '.7z'].includes(ext), label: 'Archive' },\n  { test: (ext) => ['.txt', '.json', '.xml'].includes(ext), label: 'Plain text' },\n];\n\nexport function getFileExtension(name = '') {\n  const dot = name.lastIndexOf('.');\n  return dot === -1 ? '' : name.slice(dot).toLowerCase();\n}\n\nexport function formatFileSize(bytes = 0) {\n  if (bytes < 1024) return `${bytes} B`;\n  if (bytes < 1024 * 1024) return `${Math.ceil(bytes / 1024)} KB`;\n  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// buildAcceptAttr returns the value for <input accept=\"…\">: extensions AND\n// their MIME types, because Safari and Firefox each honour only one of them.\nexport function buildAcceptAttr(accept = DEFAULT_ACCEPT) {\n  const extensions = accept.map((item) => item.toLowerCase());\n  return extensions.concat(extensions.flatMap((ext) => MIME_BY_EXTENSION[ext] ?? [])).join(',');\n}\n\n// validateBulkFile returns null when the file may be uploaded, or a\n// user-facing reason string when it may not.\nexport function validateBulkFile(file, { accept = DEFAULT_ACCEPT, maxSizeMB = DEFAULT_MAX_SIZE_MB } = {}) {\n  if (!file) return 'No file selected.';\n\n  const extension = getFileExtension(file.name);\n  const mimeType = (file.type || '').toLowerCase();\n  const allowed = accept.map((item) => item.toLowerCase());\n  const allowedLabel = allowed.join(', ');\n\n  if (!extension) {\n    return `\"${file.name}\" has no file extension. Only ${allowedLabel} files are allowed.`;\n  }\n  if (!allowed.includes(extension)) {\n    const hint = REJECTION_HINTS.find((rule) => rule.test(extension, mimeType));\n    return hint\n      ? `${hint.label} files are not supported. Only ${allowedLabel} files are allowed.`\n      : `\"${extension}\" files are not supported. Only ${allowedLabel} files are allowed.`;\n  }\n  // An extension can be faked by renaming report.pdf to report.xlsx, so\n  // cross-check the MIME type the browser sniffed. An empty type is normal\n  // (some OSes report nothing for .csv), so only a positively-wrong type is\n  // rejected here.\n  const expectedMimes = MIME_BY_EXTENSION[extension];\n  if (mimeType && expectedMimes && !expectedMimes.includes(mimeType)) {\n    return `\"${file.name}\" is not a real ${extension} file (detected ${mimeType}). Re-save it from Excel and try again.`;\n  }\n  if (file.size === 0) {\n    return `\"${file.name}\" is empty. Fill in at least one row before uploading.`;\n  }\n  if (file.size > maxSizeMB * 1024 * 1024) {\n    return `File is ${formatFileSize(file.size)}. The limit is ${maxSizeMB} MB.`;\n  }\n  return null;\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { Alert, Button, Progress, Tag, Tooltip, message } from 'antd';\nimport {\n  ArrowLeftOutlined,\n  CheckCircleFilled,\n  CloseCircleFilled,\n  DeleteOutlined,\n  DownloadOutlined,\n  FileExcelOutlined,\n  ReloadOutlined,\n} from '@ant-design/icons';\nimport AppBreadcrumb from '../Breadcrumb';\nimport {\n  DEFAULT_ACCEPT,\n  DEFAULT_MAX_SIZE_MB,\n  buildAcceptAttr,\n  formatFileSize,\n  validateBulkFile,\n} from './bulkUploadValidation';\nimport '../../styles/bulk-upload-panel.css';\n\n// ───────────────────────────────────────────────────────────────────────────\n// BulkUploadPanel — the shared \"download the template, drop the filled sheet\n// back in\" screen. Any module that imports rows from a spreadsheet (billing\n// actuals, test steps, candidates, …) renders this and supplies only its two\n// async calls plus a result renderer, so every bulk-upload screen in the suite\n// looks and validates identically.\n//\n// The upload target is a drop area rather than a button: a file can be dragged\n// onto it or clicked to browse. Both paths funnel through the one validator in\n// bulkUploadValidation.js, so a .pdf or .jpeg never reaches onUpload.\n//\n// Props\n//   title / description        page heading\n//   breadcrumbItems            [{ label, href }] — passed to core Breadcrumb\n//   backTo / backLabel         optional back link in the header\n//   templateTitle / …Hint      right-rail sample-template card copy\n//   templateLabel              download button label\n//   instructions               string[] rendered as the \"Before you upload\" list\n//   accept                     allowed extensions, default .xlsx/.xls/.csv\n//   maxSizeMB                  size ceiling, default 10\n//   onDownloadTemplate()       async; triggers the browser download\n//   onUpload(file)             async; resolves with the import summary\n//   renderResult(summary, {reset})   module-specific summary UI\n//   extraSidebar               extra nodes appended to the right rail\n// ───────────────────────────────────────────────────────────────────────────\n\n// The drop-area artwork: a spreadsheet with an upload badge. Inline SVG rather\n// than a PNG so it stays crisp at any DPI, follows the drop state's colors,\n// and adds no asset the host app has to serve.\nfunction UploadArtwork() {\n  return (\n    <svg className=\"bulk-upload-art\" viewBox=\"0 0 72 72\" focusable=\"false\" aria-hidden=\"true\">\n      <rect x=\"12\" y=\"6\" width=\"36\" height=\"48\" rx=\"5\" className=\"bulk-upload-art__sheet\" />\n      <path d=\"M20 20h20M20 28h20M20 36h12\" className=\"bulk-upload-art__lines\" />\n      <circle cx=\"50\" cy=\"48\" r=\"15\" className=\"bulk-upload-art__badge\" />\n      <path d=\"M50 55V41m0 0-6 6m6-6 6 6\" className=\"bulk-upload-art__arrow\" />\n    </svg>\n  );\n}\n\nexport default function BulkUploadPanel({\n  title,\n  description,\n  breadcrumbItems,\n  backTo,\n  backLabel = 'Back',\n  templateLabel = 'Download Sample Template',\n  templateTitle = 'Sample template',\n  templateHint = 'Pre-filled with the exact column names the importer expects. Do not rename or reorder the columns.',\n  instructions = [],\n  accept = DEFAULT_ACCEPT,\n  maxSizeMB = DEFAULT_MAX_SIZE_MB,\n  onDownloadTemplate,\n  onUpload,\n  renderResult,\n  extraSidebar,\n}) {\n  const inputRef = useRef(null);\n  const [dragging, setDragging] = useState(false);\n  const [downloading, setDownloading] = useState(false);\n  const [uploading, setUploading] = useState(false);\n  const [file, setFile] = useState(null);\n  const [error, setError] = useState(null);\n  const [result, setResult] = useState(null);\n  // Bumped after every attempt so the <input> remounts empty — picking the\n  // SAME file twice in a row still fires onChange.\n  const [inputKey, setInputKey] = useState(0);\n\n  const acceptList = useMemo(() => accept.map((item) => item.toLowerCase()), [accept]);\n  const acceptAttr = useMemo(() => buildAcceptAttr(acceptList), [acceptList]);\n\n  const reset = useCallback(() => {\n    setFile(null);\n    setError(null);\n    setResult(null);\n    setDragging(false);\n    setInputKey((key) => key + 1);\n  }, []);\n\n  const handleDownload = useCallback(async () => {\n    if (!onDownloadTemplate) return;\n    setDownloading(true);\n    try {\n      await onDownloadTemplate();\n      message.success('Sample template downloaded.');\n    } catch (err) {\n      message.error(err?.message || 'Could not download the template.');\n    } finally {\n      setDownloading(false);\n    }\n  }, [onDownloadTemplate]);\n\n  // Single entry point for both the browse dialog and drag-and-drop, so the\n  // two paths can never diverge on what they let through.\n  const acceptFile = useCallback(\n    async (picked) => {\n      if (!picked || uploading) return;\n      setInputKey((key) => key + 1);\n\n      const reason = validateBulkFile(picked, { accept: acceptList, maxSizeMB });\n      if (reason) {\n        setFile(null);\n        setResult(null);\n        setError(reason);\n        return;\n      }\n\n      setError(null);\n      setResult(null);\n      setFile({ name: picked.name, size: picked.size });\n      setUploading(true);\n      try {\n        const summary = await onUpload(picked);\n        setResult(summary);\n      } catch (err) {\n        setError(err?.message || 'Upload failed. Please try again.');\n      } finally {\n        setUploading(false);\n      }\n    },\n    [acceptList, maxSizeMB, onUpload, uploading],\n  );\n\n  const openFileDialog = () => {\n    if (!uploading) inputRef.current?.click();\n  };\n\n  const dropzoneClass = [\n    'bulk-upload-dropzone',\n    dragging ? 'is-dragging' : '',\n    uploading ? 'is-busy' : '',\n    error ? 'is-error' : '',\n    result && !error ? 'is-done' : '',\n  ]\n    .filter(Boolean)\n    .join(' ');\n\n  return (\n    <div className=\"bulk-upload-panel\">\n      {breadcrumbItems?.length ? (\n        <div className=\"bulk-upload-breadcrumb\">\n          <AppBreadcrumb items={breadcrumbItems} />\n        </div>\n      ) : null}\n\n      {/* One bordered frame around the whole working area, matching the outer\n          panel the Billing / Payroll list pages sit in (.finance-page). */}\n      <div className=\"bulk-upload-frame\">\n        <header className=\"bulk-upload-header\">\n          <div className=\"bulk-upload-header__icon\" aria-hidden=\"true\">\n            <FileExcelOutlined />\n          </div>\n          <div className=\"bulk-upload-header__text\">\n            <h1 className=\"bulk-upload-header__title\">{title}</h1>\n            {description ? <p className=\"bulk-upload-header__desc\">{description}</p> : null}\n          </div>\n          {backTo ? (\n            <RouterLink className=\"bulk-upload-header__back\" to={backTo}>\n              <Button type=\"text\" icon={<ArrowLeftOutlined />}>{backLabel}</Button>\n            </RouterLink>\n          ) : null}\n        </header>\n\n        <div className=\"bulk-upload-grid\">\n          <section className=\"bulk-upload-card bulk-upload-card--drop\">\n            <div className=\"bulk-upload-card__head\">\n              <span className=\"bulk-upload-step\">Step 2</span>\n              <h2 className=\"bulk-upload-card__title\">Upload the filled file</h2>\n            </div>\n\n            <div\n              role=\"button\"\n              tabIndex={uploading ? -1 : 0}\n              aria-disabled={uploading}\n              aria-label=\"Upload the filled file — click to browse, or drop a file here\"\n              className={dropzoneClass}\n              onClick={openFileDialog}\n              onKeyDown={(event) => {\n                if (event.key === 'Enter' || event.key === ' ') {\n                  event.preventDefault();\n                  openFileDialog();\n                }\n              }}\n              onDragOver={(event) => {\n                event.preventDefault();\n                if (!uploading) setDragging(true);\n              }}\n              onDragLeave={() => setDragging(false)}\n              onDrop={(event) => {\n                event.preventDefault();\n                setDragging(false);\n                acceptFile(event.dataTransfer.files?.[0]);\n              }}\n            >\n              <UploadArtwork />\n              <p className=\"bulk-upload-dropzone__title\">\n                {dragging ? 'Drop the file to start uploading' : 'Drag & drop your file here'}\n              </p>\n              <p className=\"bulk-upload-dropzone__sub\">\n                or <span className=\"bulk-upload-dropzone__link\">browse from your computer</span>\n              </p>\n              <div className=\"bulk-upload-chips\">\n                {acceptList.map((ext) => (\n                  <Tag key={ext} className=\"bulk-upload-chip bulk-upload-chip--ok\">{ext}</Tag>\n                ))}\n                <Tooltip title=\"These file types are rejected before upload\">\n                  <Tag className=\"bulk-upload-chip bulk-upload-chip--no\">.pdf .jpg .png not allowed</Tag>\n                </Tooltip>\n              </div>\n              <p className=\"bulk-upload-dropzone__limit\">Maximum size {maxSizeMB} MB</p>\n            </div>\n\n            <input\n              key={inputKey}\n              ref={inputRef}\n              hidden\n              type=\"file\"\n              accept={acceptAttr}\n              onChange={(event) => acceptFile(event.target.files?.[0])}\n            />\n\n            {file ? (\n              <div className={`bulk-upload-file ${error ? 'is-error' : ''}`}>\n                <span className=\"bulk-upload-file__icon\">\n                  {uploading ? <FileExcelOutlined /> : error ? <CloseCircleFilled /> : <CheckCircleFilled />}\n                </span>\n                <span className=\"bulk-upload-file__meta\">\n                  <span className=\"bulk-upload-file__name\" title={file.name}>{file.name}</span>\n                  <span className=\"bulk-upload-file__size\">\n                    {formatFileSize(file.size)}\n                    {uploading ? ' · uploading…' : error ? ' · failed' : ' · processed'}\n                  </span>\n                </span>\n                {uploading ? null : (\n                  <Button\n                    type=\"text\"\n                    size=\"small\"\n                    icon={result ? <ReloadOutlined /> : <DeleteOutlined />}\n                    onClick={reset}\n                  >\n                    {result ? 'Upload another' : 'Remove'}\n                  </Button>\n                )}\n              </div>\n            ) : null}\n\n            {uploading ? (\n              <Progress percent={99} status=\"active\" showInfo={false} size=\"small\" className=\"bulk-upload-progress\" />\n            ) : null}\n\n            {error ? (\n              <Alert\n                type=\"error\"\n                showIcon\n                className=\"bulk-upload-alert\"\n                title=\"File not accepted\"\n                description={error}\n              />\n            ) : null}\n          </section>\n\n          <aside className=\"bulk-upload-side\">\n            <section className=\"bulk-upload-card bulk-upload-card--template\">\n              <div className=\"bulk-upload-card__head\">\n                <span className=\"bulk-upload-step\">Step 1</span>\n                <h2 className=\"bulk-upload-card__title\">{templateTitle}</h2>\n              </div>\n              <p className=\"bulk-upload-side__hint\">{templateHint}</p>\n              <Button\n                block\n                icon={<DownloadOutlined />}\n                loading={downloading}\n                onClick={handleDownload}\n                className=\"bulk-upload-template-btn\"\n              >\n                {templateLabel}\n              </Button>\n            </section>\n\n            {instructions.length ? (\n              <section className=\"bulk-upload-card bulk-upload-card--rules\">\n                <h2 className=\"bulk-upload-card__title\">Before you upload</h2>\n                <ul className=\"bulk-upload-rules\">\n                  {instructions.map((line) => (\n                    <li key={line}>{line}</li>\n                  ))}\n                </ul>\n              </section>\n            ) : null}\n\n            {extraSidebar}\n          </aside>\n        </div>\n\n        {result && renderResult ? (\n          <div className=\"bulk-upload-result\">{renderResult(result, { reset })}</div>\n        ) : null}\n      </div>\n    </div>\n  );\n}\n","import { ensureToken, fetchJsonWithAuth, getStoredToken } from './authApi';\nimport { AUTH_URL, JOBS_URL } from './apiConfig';\n\n// ── Jobs via jobsapi/v1 (user auth) ──────────────────────────────────────────\n\nexport async function getJobs({\n  jobStatus = 'active',\n  jobRecruitmentStatus = 'unread',\n  limit = 50,\n  offset = 0,\n  userId = 1,\n  sortBy = 'id',\n} = {}) {\n  const token = await ensureToken();\n  const params = new URLSearchParams({\n    jobStatus, jobRecruitmentStatus,\n    limit: String(limit), offset: String(offset),\n    userId: String(userId), sortBy,\n  });\n  const res = await fetch(`${JOBS_URL}/jobs?${params}`, {\n    method: 'GET',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n  });\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  const json = await res.json();\n  return json.data ?? json;\n}\n\nexport async function getJobDetailView(id) {\n  const token = await ensureToken();\n  const params = new URLSearchParams({ jobId: String(id) });\n  const res = await fetch(`${JOBS_URL}/jobs?${params}`, {\n    method: 'GET',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n  });\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  const json = await res.json();\n  return json.data ?? json;\n}\n\nexport async function uploadJobAttachment(recordId, file) {\n  const token = await ensureToken();\n  const formData = new FormData();\n  formData.append('file', file);\n  formData.append('jobId', recordId);\n  const res = await fetch(`${JOBS_URL}/jobs/${recordId}/attachment`, {\n    method: 'POST',\n    headers: { Authorization: `Bearer ${token}` },\n    body: formData,\n  });\n  if (!res.ok) {\n    const errorText = await res.text();\n    throw new Error(errorText || `API ${res.status}: ${res.statusText}`);\n  }\n  const json = await res.json();\n  return json.data ?? json;\n}\n\n// ── Jobs via authapi/v1 (service auth — auto-refreshes with stored token) ────\n// Used by DescriptionBlock for the job description edit flow.\n\nconst SERVICE_CREDENTIALS = {\n  email: 'zinnext@realtekconsulting.net',\n  user_pwd: 'Admin@123*',\n};\n\nlet serviceLoginPromise = null;\n\nasync function serviceLogin() {\n  if (serviceLoginPromise) return serviceLoginPromise;\n  serviceLoginPromise = fetch(`${AUTH_URL}/login`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify(SERVICE_CREDENTIALS),\n  })\n    .then(async (res) => {\n      if (!res.ok) throw new Error(`Login failed: ${res.status}`);\n      const json = await res.json();\n      const token = json.token ?? json.access_token ?? json.data?.token ?? json.data?.access_token;\n      if (!token) throw new Error('No token in login response');\n      localStorage.setItem('authToken', token);\n      return token;\n    })\n    .finally(() => { serviceLoginPromise = null; });\n  return serviceLoginPromise;\n}\n\nasync function getServiceToken() {\n  const token = getStoredToken() ?? localStorage.getItem('authToken');\n  if (token) return token;\n  return serviceLogin();\n}\n\nasync function authApiGet(path) {\n  let token = await getServiceToken();\n  let res = await fetch(`${AUTH_URL}${path}`, {\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n  });\n  if (res.status === 401) {\n    localStorage.removeItem('authToken');\n    token = await serviceLogin();\n    res = await fetch(`${AUTH_URL}${path}`, {\n      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n    });\n  }\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  const json = await res.json();\n  return json.data ?? json;\n}\n\nasync function authApiPut(path, body) {\n  let token = await getServiceToken();\n  let res = await fetch(`${AUTH_URL}${path}`, {\n    method: 'PUT',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n    body: JSON.stringify(body),\n  });\n  if (res.status === 401) {\n    localStorage.removeItem('authToken');\n    token = await serviceLogin();\n    res = await fetch(`${AUTH_URL}${path}`, {\n      method: 'PUT',\n      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n      body: JSON.stringify(body),\n    });\n  }\n  if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n  return res.json();\n}\n\nexport async function getAllJobs() {\n  return authApiGet('/jobs');\n}\n\nexport async function getJobById(id) {\n  return authApiGet(`/jobs/${id}`);\n}\n\nexport async function updateJobDescription(id, rawDescription) {\n  return authApiPut(`/jobs/${id}`, { rawDescription });\n}\n\nexport async function getJobDetailedView(module, id) {\n  const token = await getServiceToken();\n  const res = await fetch(`${AUTH_URL}/detailedView?module=${module}&id=${id}`, {\n    method: 'GET',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n  });\n  if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);\n  return res.json();\n}\n\nexport async function getSourceCandidates(jobId, options = {}) {\n  const token = await ensureToken();\n\n  const {\n    offset = 0,\n    limit = 10,\n    booleanQuery = '',\n    skills = [],\n    location = '',\n    jobTitle = '',\n    minExperience = '',\n    maxExperience = '',\n    hiringStage = '',\n    hiringStageType = '',\n    sortBy = 'relevance',\n    sortType = 'asc',\n    searchFilter = {},\n    diceFilter = {},\n    searchQuery = '',\n    sourceType = 'internal',\n    selectedSource = ['internal'],\n    userId = 0,\n  } = options;\n\n  const tenantId = localStorage.getItem('tenantId') || '';\n  const businessId = localStorage.getItem('businessId') || '';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '';\n\n  const payload = {\n    tenantId,\n    businessId,\n    businessUnitId,\n    jobId,\n    filter: {\n      skills,\n      location: location ? [location] : [],\n      jobTitle: jobTitle ? [jobTitle] : [],\n      experienceFrom: minExperience?.toString() || '',\n      experienceTo: maxExperience?.toString() || '',\n    },\n    hiringStage,\n    hiringStageType,\n    sortBy,\n    sortType,\n    booleanQuery,\n    searchFilter,\n    diceFilter,\n    searchQuery,\n    sourceType,\n    selectedSource,\n    userId,\n    offset,\n    limit,\n  };\n\n  const response = await fetch(\n    `${JOBS_URL}/source/hiring-candidate-list?offset=${offset}&limit=${limit}`,\n    {\n      method: 'POST',\n      headers: {\n        Authorization: `Bearer ${token}`,\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify(payload),\n    }\n  );\n\n  if (!response.ok) {\n    throw new Error(`API ${response.status}: ${response.statusText}`);\n  }\n\n  return await response.json();\n}\n\nexport async function getJobDescription(jobId) {\n  const token = await ensureToken();\n\n  const response = await fetch(\n    `${JOBS_URL}/jobs?jobId=${jobId}`,\n    {\n      method: 'GET',\n      headers: {\n        Authorization: `Bearer ${token}`,\n        'Content-Type': 'application/json',\n      },\n    }\n  );\n\n  if (!response.ok) {\n    throw new Error(`API ${response.status}: ${response.statusText}`);\n  }\n\n  return await response.json();\n}\n","import { useState } from 'react';\nimport { Button, Input, message, Space, Tag, Typography } from 'antd';\nimport { EditOutlined } from '@ant-design/icons';\nimport { getJobById, updateJobDescription } from '../services/jobsApi';\nimport '../styles/DescriptionBlock.css';\n\nconst { Text } = Typography;\nconst PREVIEW = 2;\n\nexport default function DescriptionBlock({ jobId, sections = [], meta = [], rawDescription = '', onSaved }) {\n  const [expanded, setExpanded]   = useState(false);\n  const [editing, setEditing]     = useState(false);\n  const [rawDesc, setRawDesc]     = useState('');\n  const [saving, setSaving]       = useState(false);\n\n  const sorted  = [...sections].sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0));\n  const visible  = expanded ? sorted : sorted.slice(0, PREVIEW);\n  const hasMore  = sorted.length > PREVIEW;\n\n  function startEdit() {\n    setRawDesc(rawDescription);\n    setEditing(true);\n  }\n\n  function cancelEdit() {\n    setEditing(false);\n    setRawDesc('');\n  }\n\n  async function handleSave() {\n    if (!rawDesc.trim()) {\n      message.warning('Please enter a job description');\n      return;\n    }\n    setSaving(true);\n    try {\n      await updateJobDescription(jobId, rawDesc.trim());\n      const updated = await getJobById(jobId);\n      onSaved?.(updated);\n      setEditing(false);\n      setRawDesc('');\n      message.success('Description updated successfully');\n    } catch {\n      message.error('Failed to update description');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  if (editing) {\n    return (\n      <Space direction=\"vertical\" style={{ width: '100%' }} size={8}>\n        <Input.TextArea\n          rows={10}\n          value={rawDesc}\n          onChange={(e) => setRawDesc(e.target.value)}\n          placeholder=\"Paste raw job description here...\"\n        />\n        <Space>\n          <Button type=\"primary\" loading={saving} onClick={handleSave}>\n            Save & Parse\n          </Button>\n          <Button onClick={cancelEdit}>Cancel</Button>\n        </Space>\n      </Space>\n    );\n  }\n\n  return (\n    <div className=\"desc-block\">\n      <div className=\"desc-block-toolbar\">\n        <EditOutlined className=\"desc-edit-icon\" onClick={startEdit} />\n      </div>\n\n      {!sections.length && !meta.length ? (\n        <Text type=\"secondary\">No description available.</Text>\n      ) : (\n        <div className=\"jdv-ats-desc\">\n          {meta.length > 0 && (\n            <div className=\"jdv-ats-meta-grid\">\n              {meta.map(({ fieldKey, fieldLabel, value }) => (\n                <div key={fieldKey} className=\"jdv-ats-meta-row\">\n                  <span className=\"jdv-ats-meta-key\">{fieldLabel}</span>\n                  <span className=\"jdv-ats-meta-val\">{value}</span>\n                </div>\n              ))}\n            </div>\n          )}\n\n          <div className=\"jdv-ats-sections\">\n            {visible.map(({ sectionKey, sectionTitle, renderType, content = [] }) =>\n              renderType === 'education' ? (\n                /* ── Education: green accent card at the bottom ── */\n                <div key={sectionKey} className=\"education-block\">\n                  <div className=\"education-header\">\n                    <span>🎓</span>\n                    <span>{sectionTitle}</span>\n                  </div>\n                  <ul className=\"education-list\">\n                    {content.map((item, i) => (\n                      <li key={i} className=\"education-list-item\">{item}</li>\n                    ))}\n                  </ul>\n                </div>\n              ) : (\n                /* ── Regular section ── */\n                <div key={sectionKey} className=\"jdv-ats-section\">\n                  <div className=\"jdv-ats-section-hd\"><span>{sectionTitle}</span></div>\n                  {renderType === 'chips' ? (\n                    <Space size={[6, 6]} wrap style={{ marginTop: 8 }}>\n                      {content.map((item, i) => (\n                        <Tag key={i} className=\"jdv-skill-tag\">{item}</Tag>\n                      ))}\n                    </Space>\n                  ) : (\n                    <ul className=\"jdv-ats-bullets\">\n                      {content.map((item, i) => (\n                        <li key={i} className=\"jdv-ats-bullet-item\">{item}</li>\n                      ))}\n                    </ul>\n                  )}\n                </div>\n              )\n            )}\n          </div>\n\n          {hasMore && (\n            <span className=\"jdv-desc-toggle\" onClick={() => setExpanded((p) => !p)}>\n              {expanded ? 'Show less' : `Show more (${sections.length - PREVIEW} more sections)`}\n            </span>\n          )}\n        </div>\n      )}\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\n\n// The signed-in user's numeric id, as stored by authApi on login. Used as the\n// default identity passed to a tab's visibility predicate (e.g. \"is this record\n// assigned to me\").\nfunction currentUserId() {\n  return Number(localStorage.getItem('userId')) || 0;\n}\n\n/*\n * Generic detail-tab visibility gate.\n *\n * A module's tab entry (jobConfig.tabs, candidateConfig.tabs, …) may declare an\n * optional `visibleWhen(ctx)` predicate — a sync boolean or a Promise<boolean>.\n * A tab with no predicate is always shown, so this is purely additive and every\n * existing tab keeps rendering unchanged.\n *\n *   ctx = { id, moduleName, record, currentUserId }\n *\n * `record` is the detail record when the caller has it (the header flattens it\n * from form-groups); it may be undefined for callers that don't (a predicate\n * that needs more should fetch it itself, keyed by id). A gated tab stays HIDDEN\n * until its predicate resolves truthy, so a restricted tab never flashes on\n * screen before disappearing. On predicate error it fails OPEN (tab shown).\n */\nexport function useVisibleTabs(tabs, { id, moduleName, record } = {}) {\n  const list = useMemo(() => (Array.isArray(tabs) ? tabs : []), [tabs]);\n  const gated = useMemo(\n    () => list.filter((tab) => typeof tab?.visibleWhen === 'function'),\n    [list],\n  );\n\n  // \"<id>:<tabKey>\" → boolean once resolved. Keyed by id so a previous record's\n  // result never leaks into another, and a key absent from the map means the\n  // predicate for this record is still pending. Only the async callbacks write\n  // to it (never synchronously inside the effect body).\n  const [resolved, setResolved] = useState({});\n\n  useEffect(() => {\n    if (!gated.length) return undefined;\n    let cancelled = false;\n    const ctx = { id, moduleName, record, currentUserId: currentUserId() };\n    gated.forEach((tab) => {\n      const cacheKey = `${id}:${tab.key}`;\n      Promise.resolve()\n        .then(() => tab.visibleWhen(ctx))\n        .then((visible) => {\n          if (!cancelled) setResolved((prev) => ({ ...prev, [cacheKey]: visible !== false }));\n        })\n        .catch(() => {\n          if (!cancelled) setResolved((prev) => ({ ...prev, [cacheKey]: true }));\n        });\n    });\n    return () => { cancelled = true; };\n  }, [gated, id, moduleName, record]);\n\n  return useMemo(\n    () => list.filter((tab) => (\n      typeof tab?.visibleWhen !== 'function' ? true : resolved[`${id}:${tab.key}`] === true\n    )),\n    [list, resolved, id],\n  );\n}\n\nexport default useVisibleTabs;\n","/*\n * Shared header spec for the built-in Billing and Payroll module configs\n * (./modules/billingConfig.js, ./modules/payrollConfig.js). Both render through\n * DetailHeaderCard's `variant: 'finance'` branch, which renders the finance\n * header design inline (avatar / icon chips / engagement badge / state-gated\n * buttons / workflow stepper). Field keys are the stored financeRecords dot-paths.\n *\n * This lives in the parent detailConfig folder (not ./modules) so the module\n * glob in headerConfig.js does not try to register it as a module. `icon` values\n * are string keys resolved by DetailHeaderCard's ICONS map.\n */\n\n// Engagement chip row shared by billing and payroll — BA id, client, employer\n// (engagement type as a badge), project, then the payment rule and the period.\n//\n// The old `paymentCycle` chip is gone. It read a legacy free-text field that\n// usually just said \"Weekly\" — a cadence label that never answered the only\n// question this header should: when is this person actually due to be paid.\n// In its place are the payment TERM, the DEADLINE it produces, and the BATCH\n// the payment run is grouped by.\n//\n// paymentTermsLabel / paymentDeadlineLabel are stored preformatted on the\n// record precisely because chip values resolve against the stored document,\n// so a raw date here would render as an ISO timestamp.\n// (engagement type as a badge), project, then the payment rule and the period.\n//\n// The old `paymentCycle` chip is gone. It read a legacy free-text field that\n// usually just said \"Weekly\" — a cadence label that never answered the only\n// question this header should: when is this person actually due to be paid.\n// In its place are the payment TERM, the DEADLINE it produces, and the BATCH\n// the payment run is grouped by.\n//\n// paymentTermsLabel / paymentDeadlineLabel are stored preformatted on the\n// record precisely because chip values resolve against the stored document,\n// so a raw date here would render as an ISO timestamp.\nexport const financeChips = [\n  { field: 'baId', label: 'BA', icon: 'idcard' },\n  { field: 'clientName', icon: 'bank', tooltip: 'Client' },\n  { field: 'employerName', icon: 'team', badgeField: 'engagementType', tooltip: 'Employer' },\n  { field: 'projectName', icon: 'project', tooltip: 'Project' },\n  // Work priority from the candidate's batchCandidates row — P1 is most urgent.\n  // Renders as a dash for anyone with no batchCandidates row, none set, or a\n  // timesheet submitted before this existed (MetaChip falls back to '—' rather\n  // than hiding an empty chip — same as every other chip in this row).\n  { field: 'batchPriority', icon: 'idcard', tooltip: 'Priority' },\n  { field: 'paymentTermsLabel', icon: 'cycle', tooltip: 'Payment Terms' },\n  { field: 'paymentDeadlineLabel', icon: 'period', tooltip: 'Payment Deadline' },\n  { field: 'batchName', icon: 'project', tooltip: 'Payment Batch' },\n  // The WORK month (Jun 2026) — distinct from the processing month the payment\n  // falls in (Aug 2026 on NET 30), which is shown in the Payment Terms card.\n  { field: 'period.label', icon: 'period', tooltip: 'Period' },\n];\n\nexport default financeChips;\n","import { financeChips } from '../financeHeaderCommon';\n\n/*\n * Billing detail config (built-in). Auto-registered by headerConfig.js's\n * ./modules/*.js glob under module key \"billing\". `header.variant: 'finance'`\n * makes DetailHeaderCard render the finance header design (avatar / icon chips /\n * C2C badge / state-gated buttons / workflow stepper) instead of the default card.\n *\n * Header values are fetched from\n * GET /admin/form-groups?module=billing&id=<timesheetId>&view=detail, resolved\n * against the financeRecords collection (recordKey:\"timesheetId\"). Buttons come\n * from the seeded Row Actions, gated by the seeded Module Action Rules.\n */\nexport const billingConfig = {\n  module: 'billing',\n  tabs: [],\n  header: {\n    variant: 'finance',\n    title: 'candidateName',\n    eyebrow: 'designation',\n    statusField: 'billing.status',\n    chips: financeChips,\n  },\n};\n\nexport default billingConfig;\n","import { formatAppDateTime } from '../../../services/timezone';\n/*\n * Shared helpers used by every per-module detail config. Kept JSX-free so the\n * config files stay pure data + small functions.\n */\n\nexport const CURRENCY_SYMBOL = { USD: '$', INR: '₹', EUR: '€', GBP: '£', AUD: '$', CAD: '$' };\n\nexport const isEmpty = (value) =>\n  value === undefined ||\n  value === null ||\n  value === '' ||\n  (Array.isArray(value) && value.length === 0);\n\nexport const has = (value) => !isEmpty(value);\n\nexport function capitalize(text) {\n  const str = asText(text);\n  return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nexport function lookupId(value) {\n  if (value && typeof value === 'object' && !Array.isArray(value)\n    && 'id' in value && 'value' in value) {\n    return value.id ?? value.value;\n  }\n  return value;\n}\n\nexport function asText(value) {\n  if (Array.isArray(value)) {\n    return value\n      .filter((item) => !isEmpty(item))\n      .map((item) => asText(item))\n      .filter(Boolean)\n      .join(', ');\n  }\n  if (value && typeof value === 'object' && 'id' in value && 'value' in value) {\n    return String(value.value ?? value.id ?? '');\n  }\n  return String(value ?? '');\n}\n\nexport function symbol(currency) {\n  if (isEmpty(currency)) return '';\n  return CURRENCY_SYMBOL[String(currency).toUpperCase()] ?? String(currency);\n}\n\n// \"Jun 17, 2026 | 07:31PM\" — used by the header \"Created on\" line.\n/**\n * formatDateTime — an instant, as the tenant has configured it.\n *\n * This used to build the string by hand with toLocaleDateString /\n * toLocaleTimeString, which meant two things it should not have meant:\n *\n *   • the format (\"Aug 06, 2026 | 07:03PM\") was hardcoded here, so changing it\n *     anywhere meant changing it in code;\n *   • it rendered in the BROWSER's zone. Two colleagues in different countries\n *     opening the same record saw different times, with nothing on screen to\n *     say which was which.\n *\n * Both are now config: Admin → Display Defaults sets the format and the zone,\n * and the zone's short name is appended so a timestamp says which clock it is\n * on. Because this is render-time, EXISTING records pick it up immediately —\n * nothing in the database changes.\n */\nexport function formatDateTime(value) {\n  if (isEmpty(value)) return '';\n  return formatAppDateTime(value);\n}\n\n// Formats a rate/budget into a compact string e.g. \"₹34 - 55/Monthly\" or \"$80/Hour\".\n// Returns '' when there's no usable start value so callers can `has()`-guard it.\nexport function formatRate({ start, end, sym = '', unit } = {}) {\n  if (isEmpty(start) || Number(start) <= 0) return '';\n  const range = !isEmpty(end) && Number(end) > 0 ? `${start} - ${end}` : `${start}`;\n  return `${sym}${range}${isEmpty(unit) ? '' : `/${unit}`}`;\n}\n\n// Light colour mapping for the status pill.\nexport function statusColor(value) {\n  const key = asText(value).toLowerCase();\n  if (['active', 'open', 'hired', 'approved', 'fulfilled', 'submitted'].includes(key)) return 'success';\n  if (['inactive', 'closed', 'rejected', 'high'].includes(key)) return 'error';\n  if (['hold', 'on hold', 'pending', 'unread', 'medium'].includes(key)) return 'warning';\n  return 'default';\n}\n","import { capitalize, statusColor, symbol, formatRate } from '../configUtils';\n\n/*\n * Candidate detail header — fill-in-the-blanks config.\n *\n *   title    : fields joined together to form the heading\n *   eyebrow  : small line shown above the title\n *   status   : the coloured status pill\n *   ids      : id chips shown under the title  → { label, field }\n *   meta     : the icon + text row             → { icon, field }\n *   timestamp: the date line under the header\n *\n * A `field` is the API field name. Use a list like ['a', 'b'] to mean\n * \"use a, or b if a is empty\". Reorder / relabel freely — that's all it takes.\n */\nexport const candidateConfig = {\n  module: 'candidate',\n  tabs: [\n    { key: 'details', label: 'Details' },\n    { key: 'jobs', label: 'Jobs' },\n    { key: 'emails', label: 'Emails' },\n    { key: 'attachments', label: 'Attachments' },\n  ],\n  header: {\n    title: ['firstName', 'middleName', 'lastName'],\n    eyebrow: 'source',\n\n    // Use the candidate's status; if there's none but they're placed, say so.\n    status: ({ val, has }) => {\n      if (has(val('status'))) return { label: capitalize(val('status')), color: statusColor(val('status')) };\n      if (val('applicantPlacedStatus') === true) return { label: 'Placed', color: 'success' };\n      return null;\n    },\n\n    ids: [\n      { label: 'Candidate ID', field: ['applicantRefrenceId', 'applicantReferenceId', 'candidateReferenceId'] },\n    ],\n\n    meta: [\n      { icon: 'designation', field: 'designation' },\n      { icon: 'location',    field: ['currentLocation', 'preferredLocation'] },\n      { icon: 'experience',  compute: candidateExperience },\n      { icon: 'employment',  field: 'workAuthorisation' },\n      { icon: 'rate',        prefix: 'Expected: ', compute: expectedRate },\n    ],\n\n    timestamp: { label: 'Created Date', field: ['createdAt', 'createdDate'] },\n  },\n};\n\n// Years of experience, with months appended when present (\"5 yrs 6 mo\").\nfunction candidateExperience({ val, has }) {\n  const years = has(val('yearOfExperience')) ? val('yearOfExperience') : val('experience');\n  if (!has(years)) return '';\n  const months = val('monthOfExperience');\n  const tail = has(months) && Number(months) > 0 ? ` ${months} mo` : '';\n  return `${years} yrs${tail}`;\n}\n\n// Expected pay, formatted like \"₹80/Hour\".\nfunction expectedRate({ val }) {\n  const pay = val('expectedPayDetails') ?? {};\n  return formatRate({\n    start: pay.expectedPay ?? val('expectedPay'),\n    sym: pay.expectedPayCurrencySymbol ?? symbol(pay.expectedPayCurrency),\n    unit: pay.expectedPayUnit,\n  });\n}\n\nexport default candidateConfig;\n","import { capitalize, statusColor } from '../configUtils';\n\n/*\n * Employer detail header — fill-in-the-blanks config.\n *\n * Employer records key their fields as empCompanyName/empWebsite/… (not the\n * generic name/title/companyName the header falls back to), so without this\n * config the header showed a blank title ('-') for every employer. See\n * headerConfig.js's genericBuildData for the fallback this overrides.\n *\n *   title    : fields joined together to form the heading\n *   eyebrow  : small line shown above the title\n *   status   : the coloured status pill\n *   ids      : id chips shown under the title  → { label, field }\n *   meta     : the icon + text row             → { icon, field }\n *   timestamp: the date line under the header\n */\nexport const employerConfig = {\n  module: 'employer',\n  header: {\n    title: 'empCompanyName',\n    eyebrow: 'empWebsite',\n\n    status: ({ val, has }) => (\n      has(val('status'))\n        ? { label: capitalize(val('status')), color: statusColor(val('status')) }\n        : null\n    ),\n\n    ids: [\n      { label: 'Federal Tax ID', field: 'empFederalTaxId' },\n      { label: 'State of Incorporation', field: 'empStateOfIncorporation' },\n    ],\n\n    meta: [\n      { icon: 'location', field: 'empCompanyLocation' },\n    ],\n\n    timestamp: { label: 'Created Date', field: ['createdAt', 'createdDate'] },\n  },\n};\n\nexport default employerConfig;\n","// ─────────────────────────────────────────────────────────────────────────\n// detailEmptiness — \"is there actually anything to show here?\".\n//\n// Written for a combined (\"combineKey\") block, where the question is subtler\n// than `value == null`. A Passport pack combines a number, an expiry date and\n// the uploaded copy under one label. When nothing was ever uploaded the record\n// still holds the CONTAINER ({ passportNumber, passportExpiryDate }) — and\n// extractDocuments happily turns any object into one nameless \"Document\" entry,\n// so the block printed a file chip for a file that does not exist.\n//\n// So a file part counts only documents that RESOLVE to something openable (a\n// storage location or a URL), and any field may opt into `hideWhenEmpty` from\n// Detail Groups to drop out of its block — or drop the block entirely — when it\n// has no value. Both rules are generic: no field or module is named here.\n//\n// ZERO is deliberately NOT empty here: a rate of 0, a count of 0 and a\n// percentage of 0 all mean something, and a global \"0 is blank\" rule would eat\n// them. But the END of a range is different — a start/end pair whose end was\n// never filled stores 0, and printing it gives \"92 · 0\" (or a dangling\n// separator) for what is really just \"92\". That is a per-FIELD judgement, not a\n// global one, so it is a per-field admin flag: `hideWhenZero` says \"for THIS\n// field, treat zero as nothing to show\". Nothing here knows which field or\n// module that is.\n// ─────────────────────────────────────────────────────────────────────────\n\nimport { extractDocuments } from './renderConfig';\n\nconst truthy = (value) => value === true || value === 1 || value === '1';\n\nexport function isEmptyValue(value) {\n  if (value === undefined || value === null || value === '') return true;\n  if (Array.isArray(value)) return value.length === 0;\n  if (typeof value === 'object') {\n    // A container whose every leaf is empty is empty — the shape exists because\n    // the module's update handler always writes the sub-document, not because\n    // the user entered anything.\n    return Object.values(value).every((v) => isEmptyValue(v));\n  }\n  return false;\n}\n\n/**\n * resolvedDocuments — the documents in a value that can actually be opened.\n * Filtering on location/url is what separates a real upload from the phantom\n * entry extractDocuments derives from a plain scalar container.\n */\nexport function resolvedDocuments(value) {\n  return extractDocuments(value).filter((doc) => doc?.location || doc?.url);\n}\n\nexport function hasResolvedDocuments(value) {\n  return resolvedDocuments(value).length > 0;\n}\n\n/**\n * hidesWhenEmpty — the admin flag (Detail Groups → field → \"Hide when empty\").\n * Accepts the detail-only variant too, so a field can stay visible in the form\n * while disappearing from the detail view when unset.\n */\nexport function hidesWhenEmpty(field) {\n  // Same two homes as hidesWhenZero below: the admin authors this on the\n  // detail-config field, but the detail view reads its flags off the FORM field\n  // in the getFormGroups response, so the backend forwards it inside\n  // renderOptions. Reading both is what actually made this switch work — the key\n  // was honoured by the frontend but existed nowhere in Go, so it was discarded\n  // on save and never reached the client. The control looked functional and did\n  // nothing.\n  return truthy(field?.hideWhenEmpty)\n    || truthy(field?.hideWhenEmptyInDetail)\n    || truthy(field?.renderOptions?.hideWhenEmpty)\n    || truthy(field?.renderOptions?.hideWhenEmptyInDetail);\n}\n\n/**\n * hidesWhenZero — the admin flag (Detail Groups → field → \"…also when it is 0\").\n * Independent of `hideWhenEmpty` rather than an extension of it: a field flagged\n * this way hides on 0 AND on blank, so an admin only ever has to reach for one\n * switch to get \"show it only when it says something\". It stands alone on\n * purpose — a field that opts in must not need a second flag set correctly\n * elsewhere for the range to stop printing its dangling \"- 0\".\n */\nexport function hidesWhenZero(field) {\n  // Two homes, one meaning. The admin authors `hideWhenZero` on the detail-config\n  // field, but the detail view reads its flags off the FORM field in the\n  // getFormGroups response — and that struct has no key of its own for this, so\n  // the backend forwards it inside renderOptions (the bag that exists so a new\n  // display rule needs no schema change). Reading both means the flag works\n  // whichever way it arrives, today and if it is ever promoted to a first-class\n  // field key.\n  return truthy(field?.hideWhenZero) || truthy(field?.renderOptions?.hideWhenZero);\n}\n\n/**\n * isZeroValue — a numeric zero, however it was stored. Mongo returns the number\n * 0, a form post returns the string \"0\", and both mean the same \"never filled\n * in\" for a flagged field. SCALARS ONLY: a container is judged leaf-by-leaf by\n * isEmptyValue, and calling a whole object \"zero\" because one leaf is 0 would\n * hide packs that still have something to say.\n */\nexport function isZeroValue(value) {\n  if (typeof value === 'number') return value === 0;\n  if (typeof value === 'string') {\n    const s = value.trim();\n    return s !== '' && Number.isFinite(Number(s)) && Number(s) === 0;\n  }\n  return false;\n}\n\n/**\n * skipEmptyCell — should this cell be omitted entirely?\n * Only ever true when the admin asked for it: an unflagged empty field keeps\n * rendering the configured empty placeholder — and an unflagged ZERO keeps\n * rendering as \"0\" — exactly as before.\n */\nexport function skipEmptyCell(field, value) {\n  const zeroIsEmpty = hidesWhenZero(field);\n  if (!hidesWhenEmpty(field) && !zeroIsEmpty) return false;\n  const isFile = field?.type === 'file' || field?.type === 'document' || field?.renderType === 'document';\n  if (isFile) return !hasResolvedDocuments(value);\n  return isEmptyValue(value) || (zeroIsEmpty && isZeroValue(value));\n}\n","import { showIfConditions, evaluateShowIfWith, conditionMatches } from '../form/conditionalFieldLabel';\n\nconst truthy = (value) => value === true || value === 1 || value === '1';\n\n/**\n * recordValues — flatten every field's saved value across ALL groups into one\n * lookup, so a Show Condition can reference any field on the record rather than\n * only one in its own group (e.g. Rate Details keys off contractType, which\n * lives in its own group). Reference values arrive as { id, value }; the\n * readable `value` is what conditions compare against. A field's payloadKey is\n * registered too, so a condition may name either the form key or the DB key.\n */\nexport function recordValues(formGroups = []) {\n  const values = {};\n  for (const group of formGroups ?? []) {\n    for (const field of group?.fields ?? []) {\n      if (!field?.field || field.value === undefined) continue;\n      const raw = field.value;\n      const flat = (raw && typeof raw === 'object' && !Array.isArray(raw) && 'value' in raw)\n        ? raw.value\n        : raw;\n      values[field.field] = flat;\n      if (field.payloadKey && values[field.payloadKey] === undefined) {\n        values[field.payloadKey] = flat;\n      }\n    }\n  }\n  return values;\n}\n\n/**\n * visibleInDetail — the detail view honours the same admin-configured Show\n * Condition the add/edit forms do, so a value that no longer applies to the\n * record is hidden instead of shown as stale (e.g. Candidate Rate on a C2C\n * candidate, where the rate belongs to the employer).\n *\n * FAIL OPEN: when any referenced field is absent from the record the condition\n * cannot be judged, so the content is shown. Hiding only ever happens on a\n * positive evaluation — an unresolvable condition must never silently swallow\n * data. `ignoreShowIfInDetail` is the admin escape hatch to always show it.\n */\nexport function visibleInDetail(config, values) {\n  const conditions = showIfConditions(config?.showIf);\n  if (!conditions.length || truthy(config?.ignoreShowIfInDetail)) return true;\n  const evaluable = conditions.every(\n    (c) => Object.prototype.hasOwnProperty.call(values ?? {}, c.field),\n  );\n  if (!evaluable) return true;\n  return evaluateShowIfWith(config.showIf, (key) => values[key]);\n}\n\n/**\n * detailFieldLabel — the detail view honours the same admin-configured\n * Conditional Label (`labelWhen`) the add/edit forms do, so one field reads\n * correctly for every record: a submission's rate shows as \"Candidate Rate\" on\n * a W2 hire and \"Employer Rate\" on a C2C one, instead of the detail view\n * printing whichever label happened to be typed as the static default.\n *\n * Same rule and operators as the forms (conditionMatches), evaluated against\n * the record's own values instead of live form state.\n *\n * FAIL CLOSED, unlike visibleInDetail: when the referenced field is missing\n * from the record the condition cannot be judged, so the STATIC label is kept.\n * Showing the configured default is always safe; asserting the conditional\n * label on an unproven condition would mislabel real data.\n *\n * `ignoreLabelWhenInDetail` (per-field, set in Detail Groups) is the admin\n * escape hatch that pins the static label in the detail view while the forms\n * keep switching it.\n */\nexport function detailLabelRules(field) {\n  // Rules authored in Detail Groups win outright over the form's own\n  // Conditional Label: they are the more specific instruction, and an admin who\n  // opens the detail editor to write one expects it to take effect. With none\n  // authored, the field simply inherits the form rule, so a module that only\n  // ever configures Form Groups behaves exactly as before.\n  const own = field?.detailLabelWhen;\n  if (Array.isArray(own) && own.length) return own;\n  const inherited = field?.labelWhen;\n  return inherited ? [inherited] : [];\n}\n\nexport function detailFieldLabel(field, values) {\n  const fallback = field?.label;\n  if (truthy(field?.ignoreLabelWhenInDetail)) return fallback;\n\n  for (const rule of detailLabelRules(field)) {\n    if (!rule?.field || !rule?.label) continue;\n    // FAIL CLOSED: an unjudgeable rule is skipped, not guessed at.\n    if (!Object.prototype.hasOwnProperty.call(values ?? {}, rule.field)) continue;\n    if (conditionMatches(rule, values[rule.field])) return rule.label;\n  }\n  return fallback;\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// historyRateKeys — WHICH sub-key of an appendHistory entry is the amount,\n// which is the currency and which is the unit.\n//\n// An appendHistory container stores entries like:\n//   { candidateBudgetEnd: 0, candidateBudgetStart: 92,\n//     candidateBudgetCurrency: 'USD', candidateBudgetUnit: 'Hourly',\n//     candidateBudgetCurrencySymbol: '', timestamp, updatedBy }\n//\n// The detail view used to GUESS the amount with a regex over the entry's keys\n// (\"the first key matching rate|budget|amount that holds a number\"). Object key\n// order is insertion order, so on the entry above that guess returned\n// `candidateBudgetEnd: 0` and the Rate Details card rendered \"$0\" for a rate\n// the recruiter had actually saved as 92 — the QA bug this module fixes.\n//\n// The fix is not a better guess: the admin config ALREADY says which sub-key is\n// which. The group that declares the container configures exactly the sub-fields\n// that matter (\"<container>.<subKey>\"), so the amount is simply the first\n// configured sub-field that is not a currency/symbol/unit/type key — and\n// `candidateBudgetEnd`, which nobody configured, can never be picked.\n//\n// Resolution precedence, per slot (amount / currency / unit):\n//   1. group.historyAmountFields[container]   explicit admin override\n//      group.historyCurrencyFields[container]\n//      group.historyUnitFields[container]\n//   2. the group's configured \"<container>.<subKey>\" fields\n//   3. the legacy regex heuristic over the entry's own keys (unchanged, so a\n//      container whose group configures no sub-fields behaves exactly as before)\n//\n// Nothing here knows about submissions, candidateBudget, proposedRate or any\n// other module/field name: every input is admin config plus one stored entry.\n// ─────────────────────────────────────────────────────────────────────────\n\n// Sub-keys that describe an amount rather than BEING one.\nconst META_KEY = /(currency|symbol|unit|type)/i;\n// The legacy amount heuristic, kept verbatim as the fallback.\nconst AMOUNT_LIKE = /(rate|budget|amount)/i;\n\nconst isNumericish = (v) => typeof v === 'number'\n  || (typeof v === 'string' && v.trim() !== '' && !Number.isNaN(Number(v)));\n\nconst truthyFlag = (value) => value === true || value === 1 || value === '1';\n\n// A group \"owns\" a container when its appendHistory config declares it.\nexport function groupOwnsContainer(group, container) {\n  if (!group || !container || !truthyFlag(group.appendHistory)) return false;\n  return [group.historyField, ...(group.historyFields ?? [])].includes(container);\n}\n\n// Config may name a sub-key either bare (`candidateBudgetStart`) or fully\n// qualified (`candidateBudget.candidateBudgetStart`) — the field keys in the\n// group are written the qualified way, so admins reach for both. Both mean the\n// same sub-key of the same container.\nfunction subKeyOf(container, raw) {\n  const value = String(raw ?? '').trim();\n  if (!value) return '';\n  const prefix = `${container}.`;\n  return value.startsWith(prefix) ? value.slice(prefix.length) : value;\n}\n\n// The sub-keys this group configures under \"<container>.\", in config order.\n// Order is what makes the inference work: the admin already put the field they\n// consider \"the rate\" first, and the ones they don't care about (an End bound\n// nobody fills in) are not in the list at all.\nexport function configuredSubKeys(container, groups = []) {\n  const prefix = `${container}.`;\n  const out = [];\n  (groups ?? []).forEach((group) => {\n    if (!groupOwnsContainer(group, container)) return;\n    (group.fields ?? []).forEach((field) => {\n      const key = String(field?.field ?? '');\n      if (!key.startsWith(prefix)) return;\n      const sub = key.slice(prefix.length);\n      if (sub && !out.includes(sub)) out.push(sub);\n    });\n  });\n  return out;\n}\n\n// The explicit override for one slot, from the first owning group that sets it.\nfunction overrideFor(container, groups = [], mapKey) {\n  for (const group of groups ?? []) {\n    if (!groupOwnsContainer(group, container)) continue;\n    const named = subKeyOf(container, group?.[mapKey]?.[container]);\n    if (named) return named;\n  }\n  return '';\n}\n\n// Present means \"the entry actually carries this key\" — NOT \"the value is\n// truthy\". A stored rate of 0 is a real value and must not send us back to the\n// guess, and an empty currency symbol must not silently promote the code.\nconst present = (entry, key) => !!key && entry != null\n  && Object.prototype.hasOwnProperty.call(entry, key) && entry[key] !== undefined;\n\n// ── Legacy heuristic (fallback only) ────────────────────────────────────────\nfunction fallbackAmountKey(entry) {\n  const pair = Object.entries(entry ?? {}).find(([k, v]) => AMOUNT_LIKE.test(k)\n    && !META_KEY.test(k) && isNumericish(v));\n  return pair ? pair[0] : '';\n}\n\nfunction fallbackCurrencyKey(entry) {\n  const keys = Object.keys(entry ?? {});\n  return keys.find((k) => /currencysymbol/i.test(k) && String(entry[k] ?? '').trim() !== '')\n    || keys.find((k) => /currency/i.test(k) && String(entry[k] ?? '').trim() !== '')\n    || keys.find((k) => /symbol/i.test(k) && String(entry[k] ?? '').trim() !== '')\n    || '';\n}\n\nfunction fallbackUnitKey(entry) {\n  return Object.keys(entry ?? {}).find((k) => /unit/i.test(k)) || '';\n}\n\n// ── Public resolution ───────────────────────────────────────────────────────\n// resolveHistoryRateKeys — the three keys to read out of ONE entry of\n// `container`, given the admin's groups. Any slot can come back '' when nothing\n// resolves it; the caller renders that slot as empty rather than inventing one.\n//\n// The entry participates in the decision only as a presence check: a configured\n// key the stored entry never had (an old entry written before the field was\n// added) falls through to the next source instead of rendering blank.\nexport function resolveHistoryRateKeys(entry, container, groups = []) {\n  const configured = configuredSubKeys(container, groups);\n\n  // amount — override, else the first configured sub-key that is not metadata.\n  const amountOverride = overrideFor(container, groups, 'historyAmountFields');\n  const amountConfigured = configured.find((k) => !META_KEY.test(k));\n  const amountKey = (present(entry, amountOverride) && amountOverride)\n    || (present(entry, amountConfigured) && amountConfigured)\n    || fallbackAmountKey(entry);\n\n  // currency — override, else an explicit SYMBOL sub-key when the entry\n  // actually carries a symbol (a configured-but-empty symbol key is useless,\n  // so the code sub-key wins in that case), else the currency code.\n  const currencyOverride = overrideFor(container, groups, 'historyCurrencyFields');\n  const symbolConfigured = configured.find((k) => /symbol/i.test(k)\n    && present(entry, k) && String(entry[k] ?? '').trim() !== '');\n  const codeConfigured = configured.find((k) => /currency/i.test(k) && !/symbol/i.test(k));\n  const currencyKey = (present(entry, currencyOverride) && currencyOverride)\n    || symbolConfigured\n    || (present(entry, codeConfigured) && codeConfigured)\n    || fallbackCurrencyKey(entry);\n\n  // unit — override, else the configured unit sub-key.\n  const unitOverride = overrideFor(container, groups, 'historyUnitFields');\n  const unitConfigured = configured.find((k) => /unit/i.test(k));\n  const unitKey = (present(entry, unitOverride) && unitOverride)\n    || (present(entry, unitConfigured) && unitConfigured)\n    || fallbackUnitKey(entry);\n\n  return { amountKey: amountKey || '', currencyKey: currencyKey || '', unitKey: unitKey || '' };\n}\n\n// readHistoryRateParts — the raw values behind those keys. Formatting (symbol,\n// unit wording, thousands separators) is NOT done here: it belongs to\n// src/utils/currency.js, which every money surface shares.\nexport function readHistoryRateParts(entry, container, groups = []) {\n  const { amountKey, currencyKey, unitKey } = resolveHistoryRateKeys(entry, container, groups);\n  return {\n    amountKey,\n    currencyKey,\n    unitKey,\n    amount: amountKey ? entry?.[amountKey] : undefined,\n    currency: currencyKey ? entry?.[currencyKey] : '',\n    unit: unitKey ? entry?.[unitKey] : '',\n  };\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// currency — ONE place that knows how a stored money value becomes display\n// text. Before this file the same three rules were re-implemented (slightly\n// differently) in the finance panel, DetailViewV1's rate history, the detail\n// field render engine and each host app's header config, so the same rate\n// could read as \"$100\", \"USD100\" and \"1.2e+06\" on three surfaces of one record.\n//\n// Nothing here is module-, field- or customer-specific: callers pass the values\n// their admin config resolved, these helpers only normalise them.\n// ─────────────────────────────────────────────────────────────────────────\n\n// ISO code → symbol. A value that is ALREADY a symbol passes through, so a\n// record storing \"$\" and one storing \"USD\" render identically.\nexport const CURRENCY_SYMBOLS = {\n  USD: '$', INR: '₹', GBP: '£', EUR: '€', CAD: 'C$', AUD: 'A$', SGD: 'S$', JPY: '¥',\n};\n\n// currencySymbol('USD') → '$' | currencySymbol('₹') → '₹' | currencySymbol('') → fallback\n//\n// The `/^[A-Za-z]{2,}$/` test is what separates \"an unmapped ISO-ish CODE\" from\n// \"an actual symbol\": a 2+ letter run is a code we don't know (rendering it\n// verbatim would print \"AEDX100\"), anything else is already printable.\nexport function currencySymbol(value, fallback = '$') {\n  const raw = String(value ?? '').trim();\n  if (!raw) return fallback;\n  const mapped = CURRENCY_SYMBOLS[raw.toUpperCase()];\n  if (mapped) return mapped;\n  return /^[A-Za-z]{2,}$/.test(raw) ? fallback : raw;\n}\n\n// Duration words, however they were stored, collapsed to one display label.\nconst RATE_UNITS = {\n  hr: 'Hourly', hour: 'Hourly', hours: 'Hourly', hourly: 'Hourly',\n  day: 'Daily', daily: 'Daily',\n  week: 'Weekly', weekly: 'Weekly',\n  month: 'Monthly', monthly: 'Monthly',\n  year: 'Yearly', yearly: 'Yearly', annual: 'Yearly', annually: 'Yearly',\n};\n\n// rateUnitLabel('hr') → 'Hourly'. An unmapped unit keeps its own wording\n// (capitalised) rather than being forced into a guess — a project that adds\n// \"Per Sprint\" as a unit shows \"Per Sprint\", not \"Hourly\".\nexport function rateUnitLabel(value, fallback = '') {\n  const raw = String(value ?? '').trim();\n  if (!raw) return fallback;\n  return RATE_UNITS[raw.toLowerCase()] ?? (raw.charAt(0).toUpperCase() + raw.slice(1));\n}\n\n// The short form used inline after an amount (\"$100 /hr\").\nconst RATE_UNIT_SHORT = {\n  Hourly: 'hr', Daily: 'day', Weekly: 'wk', Monthly: 'mo', Yearly: 'yr',\n};\n\nexport function rateUnitShort(value, fallback = '') {\n  const label = rateUnitLabel(value, '');\n  if (!label) return fallback;\n  return RATE_UNIT_SHORT[label] ?? label.toLowerCase();\n}\n\n// toNumber — EXPONENT-SAFE parsing. This is the one that matters:\n// Go's encoding/json marshals a large float64 as \"1.2e+07\", so the API really\n// does return that string for a 12,000,000 client rate. The old approach\n// (`Number(String(v).replace(/[^0-9.-]/g, ''))`) stripped the \"e\" and the \"+\"\n// and silently produced 1.207 — a corrupted number that still looked plausible.\n//\n// So: strip only the characters that are definitely decoration (currency\n// symbols, spaces, thousands separators) and let Number() handle the rest,\n// because Number('1.2e+07') is exactly 12000000.\nexport function toNumber(value) {\n  if (typeof value === 'number') return Number.isFinite(value) ? value : NaN;\n  const raw = String(value ?? '').trim().replace(/[,\\s]/g, '').replace(/[^0-9eE+.\\-]/g, '');\n  if (!raw) return NaN;\n  const n = Number(raw);\n  return Number.isFinite(n) ? n : NaN;\n}\n\n// formatAmount(12000000) → '12,000,000'   formatAmount('1.2e+07') → '12,000,000'\n// Never returns exponent notation. A value that isn't numeric at all comes back\n// untouched, so a free-text rate (\"Negotiable\") is not mangled into \"NaN\".\nexport function formatAmount(value, { decimals } = {}) {\n  const n = toNumber(value);\n  if (Number.isNaN(n)) return String(value ?? '');\n  return n.toLocaleString(undefined, {\n    minimumFractionDigits: decimals ?? 0,\n    maximumFractionDigits: decimals ?? 2,\n  });\n}\n\n// formatMoney(12000000, 'USD') → '$12,000,000'\n// Negatives use a real unicode minus so amounts line up in tabular-nums columns.\nexport function formatMoney(value, currency = '$', options = {}) {\n  const n = toNumber(value);\n  if (Number.isNaN(n)) return String(value ?? '');\n  const symbol = currencySymbol(currency);\n  return `${n < 0 ? '−' : ''}${symbol}${formatAmount(Math.abs(n), options)}`;\n}\n\n// formatRate — amount + unit, with the separator emitted ONLY when there is a\n// unit to separate. The trailing-slash bugs (\"$12,000,000 /\") all came from\n// templates that appended the separator unconditionally.\nexport function formatRate(value, currency = '$', unit, options = {}) {\n  const money = formatMoney(value, currency, options);\n  const label = rateUnitLabel(unit, '');\n  return label ? `${money} / ${label}` : money;\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// emptyText — what the detail view shows where there is no value.\n//\n// THE PROBLEM\n// Everything empty rendered as one global \"-\" (detailViewDefaults.\n// emptyPlaceholder). A dash tells the reader nothing: it cannot distinguish\n// \"this candidate has no work experience\" from \"this field was never part of\n// the form\", and it reads as a rendering fault rather than as information.\n// Worse, an addRow group with zero rows rendered as an EMPTY CARD — no text at\n// all.\n//\n// THE RESOLUTION ORDER (most specific wins)\n//   1. field.emptyText          — Detail Groups, per field\n//   2. group.emptyText          — Detail Groups, per group (used when a\n//                                 repeatable group has NO rows)\n//   3. defaults.emptyTexts[<render type>] — tenant-wide, per kind of value\n//   4. defaults.emptyTexts.default\n//   5. defaults.emptyPlaceholder — the legacy single value, kept as the final\n//      fallback so nothing regresses before any of the above is configured\n//\n// Nothing here knows a module or a field name; (1) and (2) are config and (3)\n// keys off the render type the field already declares.\n// ─────────────────────────────────────────────────────────────────────────\nimport { getDefaults } from '../../services/detailDefaults';\n\n// Sensible built-ins, so the improvement is visible with ZERO configuration and\n// an admin only overrides what they disagree with. Keyed by render type.\nexport const BUILT_IN_EMPTY_TEXTS = Object.freeze({\n  document: 'No document uploaded',\n  documents: 'No documents uploaded',\n  date: 'Not provided',\n  phone: 'No contact number added',\n  email: 'No email address added',\n  link: 'No link added',\n  url: 'No link added',\n  tags: 'None added',\n  multitag: 'None added',\n  skills: 'No skills added',\n  currency: 'Not provided',\n  money: 'Not provided',\n  number: 'Not provided',\n  boolean: 'Not specified',\n  default: 'Not provided',\n});\n\nconst text = (value) => {\n  const s = value === null || value === undefined ? '' : String(value).trim();\n  return s === '' ? null : s;\n};\n\n/**\n * resolveEmptyText — the text for a single empty FIELD.\n *\n * @param {object} field         the detail field config (carries emptyText, type/renderType)\n * @param {string} [renderType]  the resolved render type, when the caller already computed it\n * @param {object} [defaults]    injectable for tests\n */\nexport function resolveEmptyText(field, renderType, defaults = getDefaults()) {\n  const own = text(field?.emptyText ?? field?.renderOptions?.emptyText);\n  if (own) return own;\n\n  const key = String(renderType ?? field?.renderType ?? field?.type ?? 'default').toLowerCase();\n  const configured = defaults?.emptyTexts ?? {};\n\n  return text(configured[key])\n    ?? text(BUILT_IN_EMPTY_TEXTS[key])\n    ?? text(configured.default)\n    ?? text(BUILT_IN_EMPTY_TEXTS.default)\n    // The legacy single placeholder is LAST, not first: a tenant that never\n    // touched it still has \"-\" saved, and honouring that ahead of the built-ins\n    // would mean this whole feature silently did nothing for existing tenants.\n    ?? text(defaults?.emptyPlaceholder)\n    ?? '—';\n}\n\n/**\n * resolveGroupEmptyText — the text for a repeatable group that has NO rows.\n * This is the \"No experience added\" case from the requirement: previously an\n * empty card with nothing in it.\n */\nexport function resolveGroupEmptyText(group, defaults = getDefaults()) {\n  const own = text(group?.emptyText);\n  if (own) return own;\n\n  const configured = defaults?.emptyTexts ?? {};\n  if (text(configured.group)) return text(configured.group);\n\n  // Derived from the group's own label, so a NEW repeatable group gets a\n  // sentence that reads correctly with no configuration at all:\n  // \"Work Experience\" → \"No work experience added\".\n  const label = text(group?.label ?? group?.name);\n  if (label) return `No ${label.toLowerCase()} added`;\n  return text(BUILT_IN_EMPTY_TEXTS.default) ?? '—';\n}\n","import { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport dayjs from 'dayjs';\nimport { Badge, Tag, Typography } from 'antd';\nimport {\n  DownloadOutlined,\n  EyeOutlined,\n  FileImageOutlined,\n  FileOutlined,\n  FilePdfOutlined,\n  FileTextOutlined,\n  FileWordOutlined,\n  LinkOutlined,\n  MailOutlined,\n  PaperClipOutlined,\n  PhoneOutlined,\n} from '@ant-design/icons';\nimport { getDefaults } from '../../services/detailDefaults';\nimport { resolveEmptyText } from './emptyText';\nimport { formatApp, formatAppDateTime } from '../../services/timezone';\nimport { currencySymbol, formatAmount, toNumber } from '../../utils/currency';\nimport DocumentViewer from '../DocumentViewer';\nimport { displayPhoneForField } from './phoneDisplay';\nimport { buildFileUrl, extractDocuments } from './renderConfig';\nimport '../../styles/FileField.css';\n\nconst { Text } = Typography;\n\n// ════════════════════════════════════════════════════════════════════════════\n//  GENERIC DETAIL-VIEW RENDER ENGINE\n//  One renderer for every detail page. Each field carries a `renderType` (set\n//  from Admin → Detail Groups, stored in the detailViewConfig registry) plus\n//  optional `renderOptions`. Adding or switching a supported render type is a\n//  config change — no frontend deploy required.\n//\n//  Backward compatible: when `renderType` is absent we fall back to the legacy\n//  `documentPreview` / `displayAs` flags, then to the original auto behaviour.\n// ════════════════════════════════════════════════════════════════════════════\n\n// ── value helpers ────────────────────────────────────────────────────────────\nconst fvIsEmpty = (v) => v === undefined || v === null || v === '';\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}|$)/;\n\nfunction toTitleCase(str) {\n  return String(str).replace(/\\w\\S*/g, (t) => {\n    if (t.length > 1 && t === t.toUpperCase()) return t; // keep acronyms (VMS, C2H)\n    return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();\n  });\n}\n\nfunction shouldTitleCase(str) {\n  if (typeof str !== 'string' || !str.trim()) return false;\n  if (!/[a-z]/i.test(str)) return false;\n  if (str.includes('@')) return false;\n  if (/^https?:\\/\\//i.test(str)) return false;\n  if (/^[a-f0-9]{24}$/i.test(str)) return false;\n  if (/<[a-z][\\s\\S]*>/i.test(str)) return false;\n  return true;\n}\n\nfunction smartText(v, capitalize) {\n  if (fvIsEmpty(v)) return '';\n  const s = String(v);\n  if (capitalize === false) return s;\n  return shouldTitleCase(s) ? toTitleCase(s) : s;\n}\n\nfunction objectToText(obj, capitalize, separator) {\n  return Object.values(obj)\n    .filter((x) => !fvIsEmpty(x) && typeof x !== 'object')\n    .map((x) => smartText(x, capitalize))\n    .join(separator);\n}\n\n// applyTransform applies an explicit textTransform render option.\nfunction applyTransform(s, transform) {\n  if (!s) return s;\n  switch (transform) {\n    case 'upper': return String(s).toUpperCase();\n    case 'lower': return String(s).toLowerCase();\n    case 'title': return toTitleCase(s);\n    default: return s;\n  }\n}\n\nconst isReference = (v) =>\n  v && typeof v === 'object' && !Array.isArray(v) && 'value' in v && 'id' in v;\n\n// toScalarString flattens any value into a single display string.\nfunction toScalarString(value, capitalize, separator) {\n  if (fvIsEmpty(value)) return '';\n  if (isReference(value)) return smartText(value.value ?? value.id, capitalize);\n  if (Array.isArray(value)) {\n    return value\n      .map((it) => (isReference(it) ? smartText(it.value ?? it.id, capitalize)\n        : it && typeof it === 'object' ? objectToText(it, capitalize, separator)\n          : smartText(it, capitalize)))\n      .filter(Boolean)\n      .join(separator);\n  }\n  if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n  if (typeof value === 'object') return objectToText(value, capitalize, separator);\n  return smartText(value, capitalize);\n}\n\n// toItemList splits arrays / comma-separated strings into individual tag items.\nfunction toItemList(value, capitalize, separator) {\n  if (Array.isArray(value)) {\n    return value\n      .map((it) => (isReference(it) ? smartText(it.value ?? it.id, capitalize)\n        : it && typeof it === 'object' ? objectToText(it, capitalize, separator)\n          : smartText(it, capitalize)))\n      .filter((t) => t !== '');\n  }\n  if (typeof value === 'string') {\n    return value.split(',').map((s) => smartText(s.trim(), capitalize)).filter(Boolean);\n  }\n  const s = toScalarString(value, capitalize, separator);\n  return s ? [s] : [];\n}\n\n// ── file chip icon ───────────────────────────────────────────────────────────\nfunction FileChipIcon({ name }) {\n  const ext = String(name || '').split('.').pop().toLowerCase();\n  if (ext === 'pdf') return <FilePdfOutlined className=\"v1-file-chip__icon\" />;\n  if (ext === 'doc' || ext === 'docx') return <FileWordOutlined className=\"v1-file-chip__icon\" />;\n  if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg'].includes(ext)) return <FileImageOutlined className=\"v1-file-chip__icon\" />;\n  if (['txt', 'csv', 'json', 'md'].includes(ext)) return <FileTextOutlined className=\"v1-file-chip__icon\" />;\n  return <FileOutlined className=\"v1-file-chip__icon\" />;\n}\nFileChipIcon.propTypes = { name: PropTypes.string };\n\n// resolveRenderType: explicit renderType wins; otherwise map the legacy flags.\nfunction resolveRenderType(field) {\n  if (field?.renderType && field.renderType !== 'auto') return field.renderType;\n  if (field?.documentPreview === true) return 'document';\n  // Any phone-typed field (or one the form masks with formatter:'phone') renders\n  // through the common phone formatter — one format for every contact number.\n  if (field?.formatter === 'phone' || field?.type === 'phone') return 'phone';\n  if (field?.displayAs === 'tag') return 'tag';\n  if (field?.displayAs === 'text') return 'text';\n  return 'auto';\n}\n\n// Phone formatting (mask + this record's own country code) lives in\n// ./phoneDisplay.js — see that file for why the code can never come from a\n// global default alone.\n\n// ── render-type implementations ──────────────────────────────────────────────\nfunction DocumentRender({ value, mode, empty, style }) {\n  const [open, setOpen] = useState(false);\n  const [index, setIndex] = useState(0);\n  const docs = extractDocuments(value);\n  if (!docs.length) return <Text strong className=\"v1-detail-value\" style={style}>{empty}</Text>;\n  const previewable = docs.filter((d) => d.url);\n\n  if (mode === 'text') {\n    return <Text strong className=\"v1-detail-value\" style={style}>{docs.map((d) => d.name).join(', ')}</Text>;\n  }\n  if (mode === 'tag') {\n    return (\n      <span className=\"v1-detail-value v1-detail-tags\">\n        {docs.map((d, i) => <Tag key={i} icon={<PaperClipOutlined />}>{d.name}</Tag>)}\n      </span>\n    );\n  }\n  if (mode === 'link' || mode === 'download') {\n    return (\n      <span className=\"v1-detail-value v1-doc-list\">\n        <span className=\"v1-file-list\">\n          {docs.map((d, i) => (d.url ? (\n            <a\n              key={i}\n              className=\"v1-file-chip\"\n              href={d.url}\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              download={mode === 'download' ? (d.name || '') : undefined}\n              title={d.name}\n            >\n              <FileChipIcon name={d.name} />\n              <span className=\"v1-file-chip__name\">{d.name}</span>\n              {mode === 'download' ? <DownloadOutlined className=\"v1-file-chip__action\" /> : <LinkOutlined className=\"v1-file-chip__action\" />}\n            </a>\n          ) : (\n            <span key={i} className=\"v1-file-chip v1-file-chip--disabled\" title=\"No file location\"><FileChipIcon name={d.name} /><span className=\"v1-file-chip__name\">{d.name}</span></span>\n          )))}\n        </span>\n      </span>\n    );\n  }\n\n  // default: preview (slider viewer)\n  return (\n    <div className=\"v1-detail-value v1-doc-list\">\n      <div className=\"v1-file-list\">\n        {docs.map((d, i) => (d.url ? (\n          <button type=\"button\" key={i} className=\"v1-file-chip\" onClick={() => { setIndex(previewable.indexOf(d)); setOpen(true); }} title={`Preview ${d.name}`}>\n            <FileChipIcon name={d.name} />\n            <span className=\"v1-file-chip__name\">{d.name}</span>\n            <EyeOutlined className=\"v1-file-chip__action\" />\n          </button>\n        ) : (\n          <span key={i} className=\"v1-file-chip v1-file-chip--disabled\" title=\"No preview available for this file\"><FileChipIcon name={d.name} /><span className=\"v1-file-chip__name\">{d.name}</span></span>\n        )))}\n      </div>\n      <DocumentViewer documents={previewable} open={open} onClose={() => setOpen(false)} initialIndex={index} />\n    </div>\n  );\n}\n\nDocumentRender.propTypes = {\n  value: PropTypes.any,\n  mode: PropTypes.string,\n  empty: PropTypes.string,\n  style: PropTypes.object,\n};\n\n// formatCurrency — through the SHARED money helpers (utils/currency.js).\n//\n// This used to parse with `Number(String(value).replace(/[^0-9.-]/g, ''))`,\n// which stripped the \"e\" and the \"+\" out of an exponent. Go's encoding/json\n// marshals a large float64 as \"1.2e+07\", so a 12,000,000 client rate arrived as\n// that string and was silently rendered as 1.207 — a plausible-looking number\n// that was wrong by seven orders of magnitude. toNumber is exponent-safe, and\n// formatAmount never emits exponent notation back.\nfunction formatCurrency(value, opts = {}) {\n  if (Number.isNaN(toNumber(value))) return String(value ?? '');\n  // `currencySymbol` on renderOptions may hold either a symbol or an ISO code;\n  // normalising here means a field configured with \"USD\" no longer prints\n  // \"USD12,000,000\". An unset option keeps rendering the bare amount.\n  const symbol = opts.currencySymbol ? currencySymbol(opts.currencySymbol, '') : '';\n  return `${symbol}${formatAmount(value, { decimals: opts.decimals })}`;\n}\n\n// ── main component ───────────────────────────────────────────────────────────\n// `record` is the flattened value map of the record being rendered (or, inside a\n// repeatable group, that ROW). Render types that need a SIBLING value read it\n// from here — today the phone renderer's country code, resolved per record\n// instead of from one global default.\nexport default function FieldValue({ field, record }) {\n  const { value, type, prefix = '', suffix = '', color = '', capitalize } = field ?? {};\n  const opts = field?.renderOptions ?? {};\n  const defaults = getDefaults();\n  const sep = defaults.separator || ', ';\n  const style = color ? { color } : undefined;\n  const tagColor = opts.tagColor || color || undefined;\n  const transform = opts.textTransform && opts.textTransform !== 'none' ? opts.textTransform : null;\n\n  const wrap = (txt) => `${prefix ? `${prefix} ` : ''}${txt}${suffix ? ` ${suffix}` : ''}`;\n  const finish = (s) => (transform ? applyTransform(s, transform) : s);\n  const asText = (s) => <Text strong className=\"v1-detail-value\" style={style}>{finish(s)}</Text>;\n  // An ATOMIC value (a date, a phone number, an amount) must never wrap inside\n  // itself — CSS would happily break \"873-487-3847\" after the hyphen, and a\n  // number shown as \"873-\" reads as corrupted data. Prose values keep wrapping.\n  const asToken = (s) => <Text strong className=\"v1-detail-value v1-detail-token\" style={style}>{finish(s)}</Text>;\n  const asTagEl = (s) => <span className=\"v1-detail-value v1-detail-tags\"><Tag color={tagColor}>{finish(s)}</Tag></span>;\n\n  const renderType = resolveRenderType(field);\n  // The empty text is resolved per FIELD and per RENDER TYPE, so a missing\n  // document reads \"No document uploaded\" and a missing date reads\n  // \"Not provided\" — instead of every absence rendering as one bare \"-\".\n  const empty = resolveEmptyText(field, renderType, defaults);\n\n  // Documents handle their own emptiness; everything else short-circuits on empty\n  // unless the field explicitly opts to show empty values.\n  if (renderType !== 'document' && fvIsEmpty(value) && !opts.showEmpty) {\n    return asText(empty);\n  }\n\n  switch (renderType) {\n    case 'document':\n      return <DocumentRender value={value} mode={opts.documentMode || 'preview'} empty={empty} style={style} />;\n\n    case 'text':\n      return asText(wrap(toScalarString(value, capitalize, sep)));\n\n    case 'tag':\n    case 'chip':\n      return asTagEl(wrap(toScalarString(value, capitalize, sep)));\n\n    case 'badge': {\n      const s = finish(toScalarString(value, capitalize, sep));\n      return <span className=\"v1-detail-value\"><Badge color={tagColor || 'blue'} text={s} /></span>;\n    }\n\n    case 'tags':\n    case 'multitag':\n    case 'skills': {\n      const items = toItemList(value, capitalize, sep);\n      if (!items.length) return asText(empty);\n      return (\n        <span className=\"v1-detail-value v1-detail-tags\">\n          {items.map((t, i) => <Tag key={i} color={tagColor}>{finish(t)}</Tag>)}\n        </span>\n      );\n    }\n\n    case 'link': {\n      const raw = toScalarString(value, false, sep);\n      const href = /^https?:\\/\\//i.test(raw) ? raw : buildFileUrl(raw) || raw;\n      return <a className=\"v1-detail-value v1-doc-link\" href={href} target=\"_blank\" rel=\"noopener noreferrer\">{finish(wrap(raw))}</a>;\n    }\n\n    case 'email': {\n      const raw = toScalarString(value, false, sep);\n      return <a className=\"v1-detail-value\" href={`mailto:${raw}`}><MailOutlined /> {raw}</a>;\n    }\n\n    case 'phone': {\n      const raw = toScalarString(value, false, sep);\n      const shown = displayPhoneForField(field, raw, record);\n      // The dial string is built from the DISPLAYED value, not the raw one.\n      // `raw` is the bare number as stored, so a candidate whose country code\n      // lives in a sibling field (the normal case — see phoneDisplay.js) got a\n      // tel: link with no country code at all: tapping it from another country\n      // dialled a wrong or unreachable number, silently.\n      const dial = shown.replace(/[^0-9+]/g, '');\n      return (\n        <a\n          className=\"v1-detail-value v1-detail-token v1-detail-call\"\n          href={`tel:${dial}`}\n          aria-label={`Call ${shown}`}\n          title={`Call ${shown}`}\n        >\n          <PhoneOutlined /> {finish(wrap(shown))}\n        </a>\n      );\n    }\n\n    case 'date':\n    case 'datetime': {\n      // Rendered in the tenant's configured zone, not the browser's, so a\n      // record does not show a different day to a colleague in another country.\n      //\n      // A CALENDAR date and an INSTANT are formatted differently on purpose.\n      // A date of birth has no time and no zone — printing \"07:03 PM IST\" after\n      // one claims a precision the value does not have. A created/updated stamp\n      // is a moment, so it carries both.\n      //\n      // `withTime` is opt-in per field (Detail Groups → render type \"datetime\",\n      // or renderOptions.withTime), so nothing that is a plain date today\n      // suddenly grows a clock.\n      const withTime = renderType === 'datetime' || opts.withTime === true;\n      if (withTime) {\n        const shown = opts.dateFormat\n          ? formatApp(value, opts.dateFormat, defaults)\n          : formatAppDateTime(value, defaults);\n        return asToken(wrap(shown || toScalarString(value, capitalize, sep)));\n      }\n      const fmt = opts.dateFormat || defaults.dateFormat;\n      const shown = formatApp(value, fmt, defaults);\n      return asToken(wrap(shown || toScalarString(value, capitalize, sep)));\n    }\n\n    case 'currency':\n      return asToken(wrap(formatCurrency(value, opts)));\n\n    case 'budget': {\n      // currency value + optional unit mapped via budgetUnitMap (Monthly → mon).\n      const money = formatCurrency(value, opts);\n      const unitRaw = opts.unit ? String(opts.unit) : '';\n      const unit = unitRaw && opts.budgetUnitMap ? (opts.budgetUnitMap[unitRaw] ?? unitRaw) : unitRaw;\n      return asToken(`${money}${unit ? `/${unit}` : ''}`);\n    }\n\n    case 'html':\n      return (\n        <span\n          className=\"v1-detail-value\"\n          style={style}\n          // Content comes from the tenant's own records (same trust level as the\n          // existing DescriptionBlock); rendered only when the admin opts in.\n          dangerouslySetInnerHTML={{ __html: String(value ?? '') }}\n        />\n      );\n\n    default:\n      break;\n  }\n\n  // ── 'auto' — original behaviour (kept verbatim for backward compatibility) ──\n  if (fvIsEmpty(value)) return asText(empty);\n\n  const isDateField = type === 'date';\n  const isDateString = typeof value === 'string' && ISO_DATE_RE.test(value.trim());\n  if (isDateField || isDateString) {\n    const d = dayjs(value);\n    if (d.isValid()) return asText(wrap(d.format(defaults.dateFormat)));\n  }\n  if (isReference(value)) return asText(wrap(smartText(value.value ?? value.id, capitalize)));\n  if (Array.isArray(value)) {\n    const items = toItemList(value, capitalize, sep);\n    if (!items.length) return asText(empty);\n    return (\n      <span className=\"v1-detail-value v1-detail-tags\">\n        {items.map((t, i) => <Tag key={i} color={tagColor}>{t}</Tag>)}\n      </span>\n    );\n  }\n  if (typeof value === 'boolean') return asText(value ? defaults.booleanTrueLabel : defaults.booleanFalseLabel);\n  if (typeof value === 'object') return asText(objectToText(value, capitalize, sep) || empty);\n  return asText(wrap(smartText(value, capitalize)));\n}\n\nFieldValue.propTypes = { field: PropTypes.object, record: PropTypes.object };\n","import { useEffect, useMemo, useState } from 'react';\nimport dayjs from 'dayjs';\nimport { Alert, Card, Empty, Input, Space, Spin, Typography, message } from 'antd';\nimport {\n  EditOutlined,\n  ClockCircleOutlined,\n  EnvironmentOutlined,\n  FileTextOutlined,\n  HistoryOutlined,\n  InfoCircleOutlined,\n  SolutionOutlined,\n  UserOutlined,\n} from '@ant-design/icons';\nimport { getFormGroups } from '../services/dropdownApi';\nimport { loadDetailDefaults, getDefaults } from '../services/detailDefaults';\nimport { getModuleDocuments } from '../services/documentApi';\nimport { getModuleDataList } from '../services/moduleDataApi';\nimport { fetchJsonWithAuth } from '../services/authApi';\nimport { AUTH_URL } from '../services/apiConfig';\nimport { updateJobDescription } from '../services/jobsApi';\nimport { getDeep } from './form/payloadTransformer';\nimport { extractDocuments } from './detail/renderConfig';\nimport { hasResolvedDocuments, skipEmptyCell } from './detail/detailEmptiness';\nimport { displayPhoneForField, countryCodeKeys } from './detail/phoneDisplay';\nimport { fetchUserName, indexUserRows } from './detail/userNames';\nimport { recordValues, visibleInDetail, detailFieldLabel } from './detail/detailVisibility';\nimport { readHistoryRateParts } from './detail/historyRateKeys';\nimport { currencySymbol, formatAmount, rateUnitLabel } from '../utils/currency';\nimport AppButton from './AppButton';\nimport FieldValue from './detail/fieldRenderEngine';\nimport { resolveGroupEmptyText } from './detail/emptyText';\nimport { formatAppDateTime } from '../services/timezone';\n\n\nconst { Text } = Typography;\n\nconst sectionIcons = [\n  <UserOutlined />,\n  <EnvironmentOutlined />,\n  <SolutionOutlined />,\n  <InfoCircleOutlined />,\n  <FileTextOutlined />,\n];\n\nconst truthy = (value) => value === true || value === 1 || value === '1';\n\n// Field keys that hold the job's free-text description (whichever the API uses).\nconst DESCRIPTION_KEYS = ['jobDescription', 'description', 'rawDescription', 'jobDescriptionText'];\n\n// Pull the description field out of the raw form-groups (jobs module only).\nfunction extractDescription(formGroups = []) {\n  for (const group of formGroups) {\n    for (const field of group.fields ?? []) {\n      const matchesKey = DESCRIPTION_KEYS.includes(field.field);\n      const matchesLabel = /description/i.test(field.label ?? '');\n      if ((matchesKey || matchesLabel) && typeof field.value === 'string' && field.value.trim()) {\n        return { ...field, key: field.field, value: field.value };\n      }\n    }\n  }\n  return null;\n}\n\nfunction normalizeGroups(formGroups = []) {\n  const values = recordValues(formGroups);\n  return [...formGroups]\n    // hideGroup hides everywhere (same flag as the forms); hideGroupInDetail is\n    // the detail-only variant — the add/edit forms never read it.\n    .filter((group) => !truthy(group.hideGroup) && !truthy(group.hideGroupInDetail))\n    .filter((group) => visibleInDetail(group, values))\n    .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n    .map((group) => ({\n      ...group,\n      fields: [...(group.fields ?? [])]\n        .filter((field) => String(field.field ?? '').trim() !== ''\n          && (field.show === undefined || truthy(field.show))\n          && visibleInDetail(field, values))\n        // Resolve the Conditional Label against this record, so the detail view\n        // reads the same as the add/edit form did for the same contract type.\n        .map((field) => ({ ...field, label: detailFieldLabel(field, values) }))\n        .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0)),\n    }))\n    .filter((group) => group.fields.length);\n}\n\nfunction rowsFromResponse(response) {\n  const payload = response?.data ?? response;\n  if (Array.isArray(payload)) return payload;\n  return payload?.data ?? payload?.rows ?? payload?.records ?? payload?.items ?? payload?.list ?? [];\n}\n\nfunction getValue(record, ...keys) {\n  for (const key of keys) {\n    const value = String(key).split('.').reduce((current, part) => current?.[part], record);\n    if (value !== undefined && value !== null && value !== '') return value;\n  }\n  return '';\n}\n\nfunction activeBatchAssignment(record) {\n  const deleted = String(getValue(record, 'isDeleted', 'deleted')).toLowerCase();\n  const status = String(getValue(record, 'assignmentStatus', 'status')).toLowerCase();\n  return deleted !== 'true' && deleted !== '1' && !['removed', 'inactive', 'deleted'].includes(status);\n}\n\nfunction recordIdsFromGroups(formGroups = [], id) {\n  const ids = {\n    candidateIds: new Set(),\n    engagementIds: new Set([String(id ?? '')].filter(Boolean)),\n  };\n  const meta = formGroups?.recordMeta;\n  ['_id', 'id', 'workforceEngagementId', 'engagementId'].forEach((key) => {\n    const value = meta?.[key];\n    if (value !== undefined && value !== null && value !== '') ids.engagementIds.add(String(value));\n  });\n  ['candidateId', 'candidate_id', 'applicantId'].forEach((key) => {\n    const value = meta?.[key];\n    if (value !== undefined && value !== null && value !== '') ids.candidateIds.add(String(value));\n  });\n  for (const group of formGroups ?? []) {\n    for (const field of group.fields ?? []) {\n      if (['candidateId', 'candidate_id', 'applicantId'].includes(field?.field) && field.value) {\n        ids.candidateIds.add(String(field.value?.id ?? field.value?.value ?? field.value));\n      }\n      if (['workforceEngagementId', 'engagementId'].includes(field?.field) && field.value) {\n        ids.engagementIds.add(String(field.value?.id ?? field.value?.value ?? field.value));\n      }\n    }\n  }\n  return ids;\n}\n\nasync function resolveBatchName(assignment) {\n  const explicitName = getValue(assignment, 'batchName', 'batch_name', 'batch.name', 'batch.title');\n  if (explicitName) return String(explicitName);\n\n  const batchId = String(getValue(assignment, 'batchId', 'batch_id'));\n  if (!batchId) return '';\n\n  for (const moduleName of ['batches', 'batch']) {\n    try {\n      const rows = rowsFromResponse(await getModuleDataList(moduleName, 500, 0));\n      const batch = rows.find((record) => String(getValue(record, '_id', 'id', 'batchId', 'batch_id')) === batchId);\n      const name = getValue(batch, 'batchName', 'batch_name', 'name', 'title');\n      if (name) return String(name);\n    } catch {\n      // Some projects register the batch module under only one of these names.\n    }\n  }\n  return batchId;\n}\n\nasync function appendBatchGroup(formGroups, id, moduleName) {\n  const normalizedModule = String(moduleName ?? '').trim().toLowerCase();\n  if (!['candidate', 'candidates', 'onboarding'].includes(normalizedModule)) return formGroups;\n\n  const { candidateIds, engagementIds } = recordIdsFromGroups(formGroups, id);\n  if (!candidateIds.size && !engagementIds.size) return formGroups;\n\n  const assignments = rowsFromResponse(await getModuleDataList('batchCandidates', 1000, 0))\n    .filter(activeBatchAssignment);\n  const assignment = assignments.find((record) => (\n    candidateIds.has(String(getValue(record, 'candidateId', 'candidate_id')))\n    || engagementIds.has(String(getValue(record, 'workforceEngagementId', 'engagementId')))\n  ));\n  if (!assignment) return formGroups;\n\n  const name = await resolveBatchName(assignment);\n  if (!name) return formGroups;\n\n  return [\n    ...formGroups,\n    {\n      id: 'candidate-batch-summary',\n      name: 'candidateBatch',\n      label: 'Batch',\n      order: 9999,\n      fields: [\n        {\n          field: 'batchName',\n          label: 'Batch Name',\n          type: 'text',\n          value: name,\n          show: true,\n          order: 1,\n        },\n      ],\n    },\n  ];\n}\n\nfunction SectionTitle({ icon, title }) {\n  return (\n    <Space size={10} align=\"center\">\n      <div className=\"v1-section-icon-box\">{icon}</div>\n      <Text strong className=\"v1-section-label\">{title}</Text>\n    </Space>\n  );\n}\n\nfunction RawDescription({ value }) {\n  const text = String(value ?? '');\n  if (/<[a-z][\\s\\S]*>/i.test(text)) {\n    return (\n      <div\n        className=\"v1-detail-value\"\n        style={{ whiteSpace: 'normal', lineHeight: 1.7 }}\n        dangerouslySetInnerHTML={{ __html: text }}\n      />\n    );\n  }\n  return (\n    <div className=\"v1-detail-value\" style={{ whiteSpace: 'pre-wrap', lineHeight: 1.7 }}>\n      {text}\n    </div>\n  );\n}\n\n/*\n * DetailViewV1 — renders ONLY the left column of a detail view: the grouped\n * field cards plus (for jobs) the parsed Description card.\n *\n * Self-contained: given `moduleName` + `id` it fetches its own form-groups\n * (the backend embeds each field's value when an id is supplied) and manages\n * its own loading/error state. DetailViewPage just drops it into the left\n * <Col> and passes moduleName + id.\n */\nexport default function DetailViewV1({ moduleName, id, refreshKey = 0, onDescriptionSaved }) {\n  const [formGroups, setFormGroups] = useState([]);\n  const [loading, setLoading] = useState(Boolean(moduleName));\n  const [error, setError] = useState('');\n  const [descEditing, setDescEditing] = useState(false);\n  const [descEditRaw, setDescEditRaw] = useState('');\n  const [descSaving, setDescSaving] = useState(false);\n  // Files registered in the central `documents` collection (keyed by module +\n  // record id + fieldName). Fetched alongside the form groups so document/file\n  // fields open from that collection's presigned URLs — not only the inline\n  // record value (which is often empty once uploads moved to the registry).\n  const [centralDocs, setCentralDocs] = useState([]);\n\n  useEffect(() => {\n    if (!moduleName || !id) {\n      Promise.resolve().then(() => setCentralDocs([]));\n      return undefined;\n    }\n    let cancelled = false;\n    getModuleDocuments(moduleName, id)\n      .then((docs) => { if (!cancelled) setCentralDocs(Array.isArray(docs) ? docs : (docs?.data ?? [])); })\n      .catch(() => { if (!cancelled) setCentralDocs([]); });\n    return () => { cancelled = true; };\n  }, [moduleName, id, refreshKey]);\n\n  // ── Rate history (config-driven via the admin's appendHistory groups) ───────\n  // A field the admin marked append-only (group.appendHistory + historyField/\n  // historyFields) stores an ARRAY of { <rate…>, timestamp, updatedBy }. The\n  // form-groups response only exposes the LATEST entry, so we fetch the raw\n  // record for the full array, plus a user map to resolve updatedBy → a name.\n  const [rawRecord, setRawRecord] = useState(null);\n  const [userMap, setUserMap] = useState({});\n  // Actors the users directory could not account for, resolved one-by-one\n  // through the auth service (cached per id for the session).\n  const [resolvedUsers, setResolvedUsers] = useState({});\n  useEffect(() => {\n    if (!moduleName || !id) { setRawRecord(null); return undefined; }\n    let cancelled = false;\n    fetchJsonWithAuth(AUTH_URL, `/module/list?module=${encodeURIComponent(moduleName)}&id=${encodeURIComponent(id)}`)\n      .then((res) => {\n        const rows = res?.data?.data ?? res?.data ?? [];\n        if (!cancelled) setRawRecord(Array.isArray(rows) ? rows[0] : null);\n      })\n      .catch(() => { if (!cancelled) setRawRecord(null); });\n    return () => { cancelled = true; };\n  }, [moduleName, id, refreshKey]);\n\n  // The users directory, indexed on EVERY id a row carries (legacyUserId /\n  // userId / _id / id — see detail/userNames.js). Indexing on legacyUserId\n  // alone is what made an auth-stamped `updatedBy` fall through to \"User #123\".\n  useEffect(() => {\n    let cancelled = false;\n    fetchJsonWithAuth(AUTH_URL, '/module/list?module=users')\n      .then((res) => {\n        const rows = res?.data?.data ?? res?.data ?? [];\n        if (!cancelled) setUserMap(indexUserRows(rows));\n      })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, []);\n\n  useEffect(() => {\n    if (!moduleName) return undefined;\n\n    let cancelled = false;\n\n    async function fetchFormGroups() {\n      try {\n        setLoading(true);\n        setError('');\n        // Passing id makes the backend embed each field's actual record value.\n        // view:'detail' makes the backend apply the admin Detail-Groups config\n        // (field overrides + merges) and shape reference/document fields as\n        // objects. Load the display defaults in parallel so FieldValue renders\n        // with the configured S3 base / date format on first paint.\n        const [data] = await Promise.all([\n          getFormGroups({ module: moduleName, id, view: 'detail' }),\n          loadDetailDefaults(),\n        ]);\n        const groupsWithBatch = await appendBatchGroup(\n          Array.isArray(data) ? data : [],\n          id,\n          moduleName,\n        );\n        if (!cancelled) setFormGroups(groupsWithBatch);\n      } catch (err) {\n        console.error(`Failed to fetch ${moduleName} detail fields:`, err);\n        if (!cancelled) setError(err?.message || 'Failed to fetch detail fields');\n      } finally {\n        if (!cancelled) setLoading(false);\n      }\n    }\n\n    fetchFormGroups();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [moduleName, id, refreshKey]);\n\n  const groups = useMemo(() => normalizeGroups(formGroups), [formGroups]);\n\n  // The append-history containers this record has, per the admin's config.\n  // Shared by the actor-resolution effect and the history blocks themselves so\n  // both always look at exactly the same set of arrays.\n  const historyKeys = useMemo(() => {\n    const keys = new Set();\n    formGroups.forEach((g) => {\n      if (truthy(g.appendHistory)) {\n        [g.historyField, ...(g.historyFields || [])].filter(Boolean).forEach((k) => keys.add(k));\n      }\n    });\n    return keys;\n  }, [formGroups]);\n\n  // Resolve every history actor the users directory did not cover. One call per\n  // DISTINCT unknown id (cached in detail/userNames.js), so a long negotiation\n  // history costs nothing extra, and a failure resolves to '' — the row then\n  // renders without attribution rather than with a meaningless \"User #123\".\n  useEffect(() => {\n    if (!rawRecord || !historyKeys.size) return undefined;\n    const unknown = new Set();\n    historyKeys.forEach((key) => {\n      const arr = rawRecord[key];\n      if (!Array.isArray(arr)) return;\n      arr.forEach((entry) => {\n        const by = entry?.updatedBy ?? entry?.changedBy;\n        if (by === undefined || by === null || by === '') return;\n        const id = String(by);\n        if (!userMap[id] && !resolvedUsers[id]) unknown.add(id);\n      });\n    });\n    if (!unknown.size) return undefined;\n    let cancelled = false;\n    Promise.all([...unknown].map((id) => fetchUserName(id).then((name) => [id, name])))\n      .then((pairs) => {\n        const found = Object.fromEntries(pairs.filter(([, name]) => name));\n        if (!cancelled && Object.keys(found).length) {\n          setResolvedUsers((prev) => ({ ...prev, ...found }));\n        }\n      })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, [rawRecord, historyKeys, userMap, resolvedUsers]);\n\n  // Last-resort labels for rate-history containers. These are a FALLBACK only:\n  // the real label comes from the form-group field that owns the container (see\n  // historyBlockLabel), so it honours the admin's label and its Conditional\n  // Label instead of being hardcoded per module here.\n  const HISTORY_LABELS = { proposedRate: 'Proposed Rate', candidateBudget: 'Candidate Rate' };\n\n  // historyBlockLabel — the heading for one history container, resolved from\n  // admin config in priority order:\n  //   1. group.historyLabels[key]        explicit static label\n  //   2. group.historyLabelFrom[key]     the field whose label titles it\n  //   3. the first field under \"<key>.\"  (every group authored so far)\n  //   4. HISTORY_LABELS / the raw key    last-resort fallback\n  //\n  // 2 and 3 both go through detailFieldLabel, so the heading honours the\n  // field's Conditional Label and re-titles itself per record — \"Employer Rate\"\n  // on a C2C submission, \"Candidate Rate\" on a W2 one.\n  const historyBlockLabel = (key, groupsForLabels, values) => {\n    const prefix = `${key}.`;\n    const owns = (group) => [group?.historyField, ...(group?.historyFields || [])].includes(key);\n\n    for (const group of groupsForLabels ?? []) {\n      if (!owns(group)) continue;\n      const explicit = group.historyLabels?.[key];\n      if (explicit) return explicit;\n      const fromKey = group.historyLabelFrom?.[key];\n      if (fromKey) {\n        const named = (group.fields ?? []).find((f) => f?.field === fromKey);\n        if (named) return detailFieldLabel(named, values) || HISTORY_LABELS[key] || key;\n      }\n    }\n    for (const group of groupsForLabels ?? []) {\n      for (const field of group?.fields ?? []) {\n        if (String(field?.field ?? '').startsWith(prefix)) {\n          return detailFieldLabel(field, values) || HISTORY_LABELS[key] || key;\n        }\n      }\n    }\n    return HISTORY_LABELS[key] || key;\n  };\n  // Format ONE history entry of `container` into { amount, unit, when, by }.\n  //\n  // WHICH sub-key holds the amount (and its currency / unit siblings) is NOT\n  // guessed here any more — see detail/historyRateKeys.js. The old guess was\n  // \"the first key matching rate|budget|amount that holds a number\", and on a\n  // stored candidateBudget entry the first such key is `candidateBudgetEnd: 0`\n  // (Mongo returns keys in insertion order), so a rate saved as 92 rendered as\n  // \"$0\". The admin config already identifies the amount: the group that\n  // declares the container configures exactly the \"<container>.<subKey>\" fields\n  // that matter, and the End bound is not among them.\n  //\n  // Precedence is override → configured fields → the old regex (fallback only,\n  // so containers whose group configures no sub-fields are untouched). Still\n  // fully generic: no module, container or field name appears here.\n  const formatHistoryEntry = (entry, container) => {\n    const { amount, currency, unit } = readHistoryRateParts(entry, container, formGroups);\n    const rawTs = entry?.timestamp?.$date ?? entry?.timestamp ?? entry?.updatedAt?.$date\n      ?? entry?.updatedAt ?? entry?.changedAt?.$date ?? entry?.changedAt;\n    const by = entry?.updatedBy ?? entry?.changedBy;\n    const amountNum = amount === undefined || amount === null || amount === ''\n      ? null : Number(amount);\n    // Normalise currency to a SYMBOL so every row reads the same (\"$100\"), and\n    // the unit to a consistent duration word (\"Hourly\"), so candidate + proposed\n    // rows share one \"$value / Duration\" format regardless of how each was saved.\n    // Both come from utils/currency — the one place that knows these rules, and\n    // the same one the detail field engine and the finance panel render through.\n    return {\n      amount: amountNum != null && !Number.isNaN(amountNum)\n        ? `${currencySymbol(currency)}${formatAmount(amountNum)}` : '—',\n      unit: rateUnitLabel(unit),\n      when: rawTs && dayjs(rawTs).isValid()\n        // Tenant clock + zone name, like every other moment in the app.\n        ? formatAppDateTime(rawTs) : '',\n      // WHO, or nothing. An id we cannot turn into a person is not information\n      // — \"User #123\" told the recruiter nothing and looked like a defect — so\n      // the attribution chip is simply omitted for an unresolvable actor.\n      by: by != null ? (userMap[String(by)] || resolvedUsers[String(by)] || '') : '',\n    };\n  };\n  const historyBlocks = useMemo(() => {\n    if (!rawRecord) return [];\n    // Same value source the field labels use, so a history block and its field\n    // can never disagree about what the record says.\n    const values = recordValues(formGroups);\n    const blocks = [];\n    historyKeys.forEach((key) => {\n      const arr = rawRecord[key];\n      if (!Array.isArray(arr) || arr.length === 0) return;\n      // Only real, attributed changes: an entry must carry a timestamp (a\n      // stray push with no timestamp/updatedBy is an incomplete duplicate, not\n      // a distinct rate change).\n      const valid = arr.filter((e) => e && (e.timestamp || e.updatedAt || e.changedAt));\n      if (valid.length === 0) return;\n      blocks.push({\n        key,\n        label: historyBlockLabel(key, formGroups, values),\n        // newest first. The container is passed through so each entry resolves\n        // its amount/currency/unit against the config of the group that owns it.\n        entries: [...valid].reverse().map((entry) => formatHistoryEntry(entry, key)),\n      });\n    });\n    return blocks;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [rawRecord, formGroups, historyKeys, userMap, resolvedUsers]);\n\n  // An appendHistory container is ALREADY shown by the synthetic Rate Details\n  // card below — richer than a plain field row, since it carries the timeline,\n  // who changed it and when. Rendering the owning group's fields as well prints\n  // the same rate twice under two identically-titled cards.\n  //\n  // So: strip the covered fields from the group that declares the container,\n  // and drop the group entirely once nothing else is left in it. Fields in that\n  // group that are NOT part of a container still render normally, and groups\n  // without appendHistory are untouched.\n  //\n  // This is what `hideGroupInDetail` was standing in for on the submission rate\n  // group — a manual switch that also hid any future non-history field in it,\n  // and had to be remembered for every new appendHistory group.\n  const displayGroups = useMemo(() => {\n    const covered = new Set(historyBlocks.map((b) => b.key));\n    if (!covered.size) return groups;\n    return groups\n      .map((group) => {\n        if (!truthy(group.appendHistory)) return group;\n        const owned = [group.historyField, ...(group.historyFields || [])]\n          .filter((k) => k && covered.has(k));\n        if (!owned.length) return group;\n        return {\n          ...group,\n          fields: group.fields.filter(\n            (f) => !owned.some((k) => String(f.field ?? '').startsWith(`${k}.`)),\n          ),\n        };\n      })\n      .filter((group) => group.fields.length);\n  }, [groups, historyBlocks]);\n\n  // Title the synthetic card from the group that declares the history, instead\n  // of a hardcoded module-specific string, so renaming the group in admin\n  // renames the card.\n  const historyCardTitle = useMemo(() => {\n    const covered = new Set(historyBlocks.map((b) => b.key));\n    const owner = formGroups.find((g) => truthy(g.appendHistory)\n      && [g.historyField, ...(g.historyFields || [])].some((k) => k && covered.has(k)));\n    return owner?.label ?? owner?.name ?? 'Rate Details';\n  }, [formGroups, historyBlocks]);\n\n  const isJob = moduleName === 'job';\n  // For jobs we render the description in its own dedicated section (below),\n  // so we keep it out of the normal field grid.\n  const jobDescription = useMemo(\n    () => (isJob ? extractDescription(formGroups) : null),\n    [isJob, formGroups],\n  );\n\n  const handleDescEditCancel = () => {\n    setDescEditing(false);\n    setDescEditRaw('');\n  };\n\n  const handleDescEditSave = async () => {\n    if (!descEditRaw.trim()) {\n      message.warning('Please enter a job description');\n      return;\n    }\n    setDescSaving(true);\n    try {\n      await updateJobDescription(id, descEditRaw.trim());\n      setDescEditing(false);\n      setDescEditRaw('');\n      setLoading(true);\n      const data = await getFormGroups({ module: moduleName, id, view: 'detail' });\n      setFormGroups(Array.isArray(data) ? data : []);\n      message.success('Description updated and parsed successfully');\n      onDescriptionSaved?.();\n    } catch {\n      message.error('Failed to update description');\n    } finally {\n      setDescSaving(false);\n      setLoading(false);\n    }\n  };\n\n  // renderField renders one labelled cell. `cellField` already carries its value\n  // (the field config for flat groups; a per-row pseudo-field for addRow rows).\n  // The detail grid is a UNIFORM CSS grid, not Ant's 24-column Row/Col.\n  //\n  // It used to size each cell from `detailCol ?? col ?? 8` — and `col` is the\n  // FORM's width, chosen for INPUT controls. Read-only label/value pairs have\n  // completely different needs, so the detail view inherited widths of 4, 6, 8\n  // and 12 that never tile evenly in a 24-column grid (8+8+4 = 20, 12+8 = 20 …),\n  // leaving ragged half-empty rows and 4-wide cells too narrow for their label.\n  //\n  // Now every cell is one equal track (auto-fill, min 220px), so fields always\n  // line up in clean rows at any width. `detailCol` remains the admin's explicit\n  // override — it maps to a column SPAN, so wide content (a description, a\n  // document list) can still take more room without breaking the rhythm.\n  const cellSpan = (cellField) => {\n    const explicit = Number(cellField.detailCol);\n    if (Number.isFinite(explicit) && explicit > 0) {\n      // Config speaks in 24ths; the grid speaks in tracks (3 per row at the\n      // reference width). Round so 24 → full row, 12 → half, 8 → one track.\n      return Math.max(1, Math.min(3, Math.round(explicit / 8)));\n    }\n    // Content that is inherently long gets the full row instead of being\n    // squeezed into one track and wrapping into a tall, ragged cell.\n    const text = typeof cellField.value === 'string' ? cellField.value : '';\n    if (cellField.renderType === 'document' || cellField.type === 'text-editor' || text.length > 120) {\n      return 3;\n    }\n    // A MERGED value is several parts joined by a separator — a date range\n    // (\"13 Jul 2026 - 17 Jul 2026\") or a rate (\"300 · USD · Hourly\"). In one\n    // track those wrap onto three lines and read as broken data, so give them\n    // two. Deliberately narrow: only multi-part values that are actually too\n    // long for a single track, so ordinary short values keep the tight rhythm.\n    const merged = /\\s(?:·|-|–|\\/)\\s/.test(text);\n    return merged && text.length >= 16 ? 2 : 1;\n  };\n\n  // Prose wraps; an atomic token (phone, date range, rate, id) never does — it\n  // ellipsises instead, with the full value on hover. Anything genuinely\n  // sentence-like, or rendered as a document/rich text, opts back into wrapping.\n  const wantsWrap = (cellField) => {\n    if (cellField.renderType === 'document' || cellField.type === 'text-editor') return true;\n    // Length ALONE. A token count would misread \"13 Jul 2026 - 17 Jul 2026\"\n    // (seven tokens, one atomic value) as prose.\n    const text = typeof cellField.value === 'string' ? cellField.value : '';\n    return text.length > 60;\n  };\n\n  // The record's own flattened values — what a render type consults when it\n  // needs a SIBLING key (e.g. the phone renderer's country code). Inside a\n  // repeatable group the ROW is passed instead, so each row speaks for itself.\n  const recordValueMap = useMemo(() => recordValues(formGroups), [formGroups]);\n\n  const renderField = (cellField, keySuffix = '', record = recordValueMap) => {\n    const label = cellField.label ?? cellField.field;\n    const wrap = wantsWrap(cellField);\n    // Truncated text must never be unreachable — the title carries the full\n    // value for both the label and any value clipped to one line.\n    const fullValue = typeof cellField.value === 'string' ? cellField.value : undefined;\n    return (\n      <div\n        key={`${cellField.field}${keySuffix}`}\n        className={`v1-detail-cell${wrap ? ' v1-detail-cell--wrap' : ''}`}\n        style={{ '--v1-cell-span': cellSpan(cellField) }}\n      >\n        <div className=\"v1-detail-field\" title={!wrap && fullValue ? `${label}: ${fullValue}` : undefined}>\n          <Text type=\"secondary\" className=\"v1-detail-label\" title={label}>\n            {label}\n          </Text>\n          <FieldValue field={cellField} record={record} />\n        </div>\n      </div>\n    );\n  };\n\n  // Render a list of cells honoring `combineKey`: fields that share a combineKey\n  // collapse into ONE merged cell (label from the combineLabel field, value =\n  // each field's display joined with \" · \") — the read-side counterpart of the\n  // form's combined row, so the SAME admin config drives both views identically.\n  // `buildCell(field)` yields a cell-field carrying that field's `.value`.\n  // Format one field's value for a merged cell the SAME way the detail engine\n  // would render it standalone: dates → the common dateFormat, phones → the\n  // common phone mask, everything else → trimmed text. So a combined \"Start /\n  // End Date\" (2 parts) or a \"Passport\" combo (4 parts) shows formatted values,\n  // never raw ISO strings.\n  const ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}|$)/;\n  const formatCellValue = (field, v, record = recordValueMap) => {\n    if (v == null || typeof v === 'object') return '';\n    const s = String(v).trim();\n    if (!s) return '';\n    if (field?.type === 'date' || field?.renderType === 'date' || ISO_DATE_RE.test(s)) {\n      const d = dayjs(s);\n      if (d.isValid()) return d.format(field?.renderOptions?.dateFormat || getDefaults().dateFormat);\n    }\n    // Same phone resolution a standalone phone cell uses — mask from the admin\n    // defaults, country code from THIS record (see detail/phoneDisplay.js).\n    if (field?.formatter === 'phone' || field?.type === 'phone' || field?.renderType === 'phone') {\n      return displayPhoneForField(field, s, record) || s;\n    }\n    return s;\n  };\n  // partLabel — what to call ONE part of a combined block. The block already\n  // carries the shared name (\"Passport\"), so a part only needs what is left of\n  // its own label after the shared words are removed: \"Passport Number\" →\n  // \"Number\", \"Alt Visa Expiry\" (block \"Alternate Visa\") → \"Expiry\". Matching is\n  // word-wise and prefix-tolerant so an abbreviated label (\"Alt\" vs \"Alternate\")\n  // still resolves. When nothing distinct remains — a \"Start / End Date\" range,\n  // where each part's label IS the block's — the part shows plain, exactly as\n  // before, so only genuinely ambiguous blocks gain labels.\n  const partLabel = (field, blockLabel) => {\n    // Admin opt-out (Detail Groups → \"Hide this part's label\"). A qualifier\n    // whose value already names itself needs no sub-label: a Notice Period of\n    // 12 Days printed \"12 · Unit Days\", because \"Notice Period Unit\" under the\n    // block \"Notice Period\" leaves the word \"Unit\".\n    // Both shapes: FormGroupField has no key of its own for a display-only\n    // flag, so the backend forwards it inside renderOptions — the same carrier\n    // hideWhenZero/hideWhenEmpty use. Reading only the top-level key is what\n    // makes a switch like this look wired and do nothing.\n    if (field?.hidePartLabel || field?.renderOptions?.hidePartLabel) return '';\n    const own = String(field?.label ?? '').trim();\n    if (!own) return '';\n    const shared = String(blockLabel ?? '').toLowerCase().split(/[\\s/]+/).filter(Boolean);\n    const words = own.split(/\\s+/);\n    let i = 0;\n    while (i < words.length) {\n      const w = words[i].toLowerCase();\n      if (!shared.some((s) => s === w || s.startsWith(w) || w.startsWith(s))) break;\n      i += 1;\n    }\n    // Nothing stripped means the label shares nothing with the block name (a\n    // \"Country\" part under \"Passport\") — it keeps its own label in full.\n    return words.slice(i).join(' ').trim();\n  };\n\n  const renderMergedCell = (pack, labelField, buildCell, keySuffix, record = recordValueMap) => {\n    // A combined pack can hold BOTH scalars and a file — the Documents group\n    // combines \"Passport\" (the uploaded copy) with its number and expiry under\n    // one label. Joining every part into a string silently DROPPED the file\n    // (its value is an object, and formatCellValue only stringifies scalars),\n    // so a configured document never rendered inside a combined block. Split\n    // the pack instead: scalars keep the \"a · b\" line, file parts render\n    // through the same document engine a standalone file field uses.\n    const cells = pack.map((field) => ({ field, cell: buildCell(field) }));\n    // A file part is only a part when there is a FILE. A \"Passport\" pack whose\n    // record holds just a number and an expiry still carries the container\n    // object, and extractDocuments turns any object into one nameless\n    // \"Document\" — so the block printed a file chip for a file nobody uploaded.\n    // hasResolvedDocuments counts only documents that resolve to something\n    // openable (a storage location or a URL), which is the honest test.\n    const docCells = cells\n      .filter(({ cell }) => isFileField(cell))\n      .map(({ cell }) => ({ ...cell, renderType: 'document' }))\n      .filter((cell) => hasResolvedDocuments(cell.value));\n    // A phone-formatted field folds its country-code SIBLING into its own\n    // displayed text (formatCellValue → displayPhoneForField, e.g. \"+1\n    // 555-1234\"). When that sibling is ALSO its own part of this same\n    // combined pack — the ordinary \"code | number\" combine layout — showing\n    // it again prints the code twice (\"+1  ·  +1 555-1234\"). Drop any pack\n    // field that is such an absorbed country-code companion of another field\n    // in the SAME pack.\n    const absorbedKeys = new Set();\n    cells.forEach(({ field }) => {\n      const isPhone = field?.formatter === 'phone' || field?.type === 'phone' || field?.renderType === 'phone';\n      if (!isPhone) return;\n      const candidates = [field?.renderOptions?.countryCodeField ?? field?.countryCodeField, ...countryCodeKeys(field)]\n        .filter(Boolean);\n      cells.forEach(({ field: sibling }) => {\n        if (sibling === field) return;\n        if (candidates.includes(sibling.field)) absorbedKeys.add(sibling.field);\n      });\n    });\n    // Mirror the form: the pack's label is combineLabel (a string) when set,\n    // else the label-owning field's label.\n    const labelText = typeof labelField.combineLabel === 'string' && labelField.combineLabel.trim()\n      ? labelField.combineLabel\n      : (labelField.label ?? labelField.field);\n    const parts = cells\n      .filter(({ cell }) => !isFileField(cell))\n      .filter(({ field }) => !absorbedKeys.has(field.field))\n      // Per-field `hideWhenEmpty` / `hideWhenZero` (Detail Groups) INSIDE the\n      // block, not only on a standalone cell: the end of a start/end range that\n      // was never filled in stores 0, and a \"92 · 0\" reads as a range that was\n      // priced at nothing. Dropping the part here — before the separators are\n      // laid down below, which are index-based on this very array — takes the\n      // dangling \"·\" with it, so the block shows a bare \"92\". An unflagged part\n      // is untouched: a real 0 still prints.\n      .filter(({ cell }) => !skipEmptyCell(cell, cell.value))\n      .map(({ field, cell }) => ({\n        key: field.field,\n        label: partLabel(field, labelText),\n        text: formatCellValue(field, cell.value, record),\n      }))\n      .filter((part) => part.text !== '');\n    // `hideWhenEmpty` (Detail Groups) on the pack's label field: a block with\n    // nothing left to say disappears instead of rendering a bare heading with a\n    // \"—\" under it. Unflagged blocks keep the previous behaviour exactly.\n    if (!parts.length && !docCells.length && skipEmptyCell(labelField, undefined)) return null;\n    // Same uniform grid cell as every other field (this used to emit an antd\n    // <Col> into a CSS-grid container, which never sized correctly). A pack\n    // carrying a document needs at least two tracks for the file chip/preview.\n    // Size from the SCALAR line (an admin detailCol still wins), then widen to\n    // two tracks when a document rides along, so the file chip has room without\n    // every document pack eating a whole row.\n    const joined = parts.map((part) => `${part.label ? `${part.label} ` : ''}${part.text}`).join('  ·  ');\n    const textSpan = cellSpan({ detailCol: labelField.detailCol, value: joined });\n    const span = docCells.length ? Math.max(textSpan, 2) : textSpan;\n    return (\n      <div\n        key={`${labelField.field}-merged${keySuffix}`}\n        className=\"v1-detail-cell v1-detail-cell--wrap\"\n        style={{ '--v1-cell-span': span }}\n      >\n        <div className=\"v1-detail-field\">\n          <Text type=\"secondary\" className=\"v1-detail-label\" title={labelText}>\n            {labelText}\n          </Text>\n          {(parts.length > 0 || docCells.length === 0) && (\n            <div className=\"v1-detail-value v1-detail-parts\">\n              {parts.length ? parts.map((part, i) => (\n                <span className=\"v1-detail-part\" key={`${part.key}-part`}>\n                  {i > 0 && <span className=\"v1-detail-part-sep\" aria-hidden=\"true\">·</span>}\n                  {part.label && <span className=\"v1-detail-part-label\">{part.label}</span>}\n                  <span>{part.text}</span>\n                </span>\n              )) : '—'}\n            </div>\n          )}\n          {docCells.map((cell) => (\n            <FieldValue key={`${cell.field}-doc`} field={cell} />\n          ))}\n        </div>\n      </div>\n    );\n  };\n  const renderFieldCells = (fields, buildCell, keySuffix = '', record = recordValueMap) => {\n    const used = new Set();\n    const out = [];\n    fields.forEach((field) => {\n      const ck = field.combineKey?.trim?.();\n      if (ck) {\n        if (used.has(ck)) return;\n        used.add(ck);\n        const pack = fields.filter((f) => f.combineKey?.trim?.() === ck);\n        if (pack.length > 1) {\n          const labelField = pack.find((f) => f.combineLabel) ?? pack[0];\n          const merged = renderMergedCell(pack, labelField, buildCell, keySuffix, record);\n          if (merged) out.push(merged);\n          return;\n        }\n      }\n      const cell = buildCell(field);\n      // Per-field `hideWhenEmpty` (Detail Groups): an empty value the admin\n      // marked as \"not worth a row\" is dropped rather than shown as \"-\".\n      if (skipEmptyCell(cell, cell.value)) return;\n      out.push(renderField(cell, keySuffix, record));\n    });\n    return out;\n  };\n\n  // Central documents grouped by their fieldName (the clean form-field key the\n  // upload registered them under — e.g. \"resume\", \"passport\", or a group's\n  // fileKey like \"documents\"). Each carries the presigned fileUrl.\n  const centralDocsByField = useMemo(() => {\n    const map = {};\n    for (const d of centralDocs) {\n      const fn = d.fieldName || d.field || 'file';\n      (map[fn] ??= []).push({\n        location: d.s3Key ?? d.location ?? d.uniqueName ?? '',\n        name: d.fileName ?? d.name ?? '',\n        fileUrl: d.fileUrl ?? d.url ?? '',\n      });\n    }\n    return map;\n  }, [centralDocs]);\n\n  // If the central `documents` collection has files for this file/document\n  // field (matched by field key OR its fileKey), render them from that\n  // collection's presigned URLs. Only activates when such files exist, so a\n  // field with no registry entry keeps its existing inline behaviour.\n  const isFileField = (field) => field.type === 'file' || field.type === 'document' || field.renderType === 'document';\n  const centralDocsFor = (field) => centralDocsByField[field.field]\n    || (field.fileKey && centralDocsByField[field.fileKey])\n    || null;\n\n  // ── document value helpers ─────────────────────────────────────────────────\n  // A file lives in TWO places: inline on the record (the container object the\n  // module's update handler writes — passport.passportCopyLocation, …) and, for\n  // anything uploaded since the shared registry existed, in the central\n  // `documents` collection. Neither alone is complete, so every file cell shows\n  // the UNION of both, de-duplicated by S3 location (falling back to the file\n  // name). Registry entries come first: they carry the presigned `fileUrl` that\n  // actually opens a private-bucket file.\n  // Identity is the ORIGINAL FILE NAME, not the storage path: the very same\n  // upload is written to two different keys (the module record stores\n  // \"submissions/<id>/passport_<file>\", the registry stores\n  // \"documents/submissions/<id>/<timestamp>_passport_<file>\"), so keying on the\n  // path would list every file twice. Both sides preserve the user's file name.\n  const docIdentityOf = (doc) => String(doc?.name || doc?.location || '').trim().toLowerCase();\n  const docIdentity = (item) => {\n    const [doc] = extractDocuments(item);\n    if (!doc || (!doc.location && !doc.url)) return null;\n    return docIdentityOf(doc);\n  };\n  const mergeDocValues = (inlineValue, registryDocs = []) => {\n    const seen = new Set();\n    const out = [];\n    const add = (item) => {\n      if (item == null || item === '') return;\n      const key = docIdentity(item);\n      // Not a file at all (e.g. a passport container holding only a number and\n      // an expiry date) — nothing to list.\n      if (key === null) return;\n      if (key && seen.has(key)) return;\n      if (key) seen.add(key);\n      out.push(item);\n    };\n    registryDocs.forEach(add);\n    (Array.isArray(inlineValue) ? inlineValue : [inlineValue]).forEach(add);\n    return out;\n  };\n  // Every document a set of rows already displays inline, so the group-level\n  // leftover list never repeats a file that is shown on its row.\n  const docKeysOf = (value) => extractDocuments(value).map(docIdentityOf).filter(Boolean);\n\n  // How many files this field HOLDS — mirrors the upload control's own capacity\n  // rule (maxFiles validation → multiple/maxCount → single). The registry keeps\n  // every version ever uploaded, so a single-file field (Passport, Visa, …)\n  // must show the CURRENT file, not its whole upload history; a genuinely\n  // multi-file field still shows its full set.\n  const fileCapacity = (field) => {\n    const maxFilesRule = (field.validations ?? []).find((rule) => rule?.type === 'maxFiles');\n    if (maxFilesRule) return Math.max(1, Number(maxFilesRule.value ?? 1));\n    if (truthy(field.multiple)) return Math.max(1, Number(field.maxCount ?? 5));\n    return Math.max(1, Number(field.maxCount ?? 1));\n  };\n\n  // Trim a merged file list to the field's capacity, newest first. The record's\n  // own inline value is authoritative for \"current\", so when it names a file\n  // that file leads; otherwise the registry's newest entry does (the API sorts\n  // createdAt descending).\n  const limitDocs = (field, merged, inlineValue) => {\n    const capacity = fileCapacity(field);\n    if (merged.length <= capacity) return merged;\n    const [current] = docKeysOf(inlineValue);\n    const ordered = current\n      ? [...merged].sort((a, b) => Number(docIdentity(b) === current) - Number(docIdentity(a) === current))\n      : merged;\n    return ordered.slice(0, capacity);\n  };\n\n  // For an addRow row, build a per-cell pseudo-field carrying that row's value.\n  // File/document fields get the whole row as their value (so the render engine's\n  // extractDocuments finds the stored file's location/name) and are forced to the\n  // document render type; every other field reads its key off the row.\n  const cellFieldForRow = (field, row) => {\n    if (field.type === 'file' || field.type === 'document') {\n      return { ...field, renderType: 'document', value: row };\n    }\n    // A RENAMED field is stored under its payloadKey, not its config key — e.g.\n    // the employer group's isVMSRequired → isVmsRequired, vmsCommission →\n    // vmsPercentage, vmsCommissionType → vmsType. Reading only field.field made\n    // every such cell render \"-\" even though the row held the value. Same\n    // field → payloadKey precedence the rest of the stack uses.\n    const value = [field.field, field.payloadKey]\n      .filter(Boolean)\n      .map((key) => getDeep(row, key))\n      .find((v) => v !== undefined && v !== null);\n    return { ...field, value };\n  };\n\n  // Flat file field → inline record value + the central registry's files.\n  const withCentralDocs = (field) => {\n    if (!isFileField(field)) return field;\n    const merged = limitDocs(field, mergeDocValues(field.value, centralDocsFor(field) ?? []), field.value);\n    return merged.length ? { ...field, renderType: 'document', value: merged } : field;\n  };\n\n  // Repeatable (addRow) group → one indexed sub-block per stored row. The backend\n  // embeds the full row array on group.rows (workExperience / educationDetails /\n  // documents). Renders nothing extra when there are no rows.\n  const renderAddRowGroup = (group, index, fields) => {\n    const key = group.name ?? group.id ?? String(index);\n    const rows = Array.isArray(group.rows) ? group.rows : [];\n    // Files a repeatable group registered in the central `documents` collection\n    // carry only the group's fileKey — the row index is stripped when they are\n    // registered, so they cannot be attributed to a specific row. Rather than\n    // guess (and risk showing row 2's file on row 1), list whatever is NOT\n    // already displayed inline on a row as the group's own attachment list. A\n    // group whose rows carry their files inline shows nothing extra here.\n    const rowDocKeys = new Set(rows.flatMap((row) => docKeysOf(row)));\n    const leftoverDocs = [];\n    const leftoverSeen = new Set();\n    fields.filter(isFileField).forEach((field) => {\n      (centralDocsFor(field) ?? []).forEach((doc) => {\n        const id = docIdentityOf(doc);\n        if (!id || rowDocKeys.has(id) || leftoverSeen.has(id)) return;\n        leftoverSeen.add(id);\n        leftoverDocs.push(doc);\n      });\n    });\n    return (\n      <Card\n        size=\"small\"\n        key={key}\n        className=\"v1-card v1-detail-card\"\n        title={<SectionTitle icon={sectionIcons[index % sectionIcons.length]} title={group.label ?? group.name ?? 'Details'} />}\n      >\n        {rows.length === 0 && leftoverDocs.length === 0 ? (\n          // Admin-configurable (Detail Groups → group → Empty text). Falls back\n          // to a sentence derived from the group's own label, so a new\n          // repeatable group reads correctly with no configuration at all.\n          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={resolveGroupEmptyText(group)} />\n        ) : (\n          rows.map((row, rowIndex) => (\n            <div key={rowIndex} className=\"v1-detail-addrow-item\">\n              {rows.length > 1 && (\n                <Text strong className=\"v1-detail-addrow-index\">\n                  {(group.label ?? 'Record')} {rowIndex + 1}\n                </Text>\n              )}\n              <div className=\"v1-detail-grid\">\n                {renderFieldCells(fields, (f) => cellFieldForRow(f, row), `-${rowIndex}`, row)}\n              </div>\n            </div>\n          ))\n        )}\n        {leftoverDocs.length > 0 && (\n          <div className=\"v1-detail-addrow-item\">\n            <div className=\"v1-detail-grid\">\n              {renderField({\n                field: `${key}-files`,\n                label: 'Uploaded Files',\n                renderType: 'document',\n                detailCol: 24,\n                value: leftoverDocs,\n              })}\n            </div>\n          </div>\n        )}\n      </Card>\n    );\n  };\n\n  const renderGroup = (group, index) => {\n    const key = group.name ?? group.id ?? String(index);\n    // Hide the raw description field — it gets its own section for jobs.\n    const fields = jobDescription\n      ? group.fields.filter((field) => field.field !== jobDescription.key)\n      : group.fields;\n    if (!fields.length) return null;\n\n    if (group.addRow) return renderAddRowGroup(group, index, fields);\n\n    return (\n      <Card\n        size=\"small\"\n        key={key}\n        className=\"v1-card v1-detail-card\"\n        title={<SectionTitle icon={sectionIcons[index % sectionIcons.length]} title={group.label ?? group.name ?? 'Details'} />}\n      >\n        <div className=\"v1-detail-grid\">{renderFieldCells(fields, withCentralDocs)}</div>\n      </Card>\n    );\n  };\n\n  // One merged \"Rate Details\" card holding every rate-history sub-section\n  // (Candidate Rate, Proposed Rate) in the SAME \"$value / Duration\" format.\n  const renderRateDetailsCard = () => (\n    <Card\n      size=\"small\"\n      key=\"rate-details-history\"\n      className=\"v1-card v1-detail-card\"\n      title={<SectionTitle icon={<HistoryOutlined />} title={historyCardTitle} />}\n    >\n      {historyBlocks.map((block, bi) => (\n        <div className={`v1-rh-section${bi > 0 ? ' v1-rh-section--gap' : ''}`} key={block.key}>\n          <div className=\"v1-rh-section-title\">{block.label}</div>\n          <div className=\"v1-rate-history\">\n            {block.entries.map((e, i) => (\n              <div className={`v1-rh-item${i === 0 ? ' v1-rh-latest' : ''}`} key={i}>\n                <span className=\"v1-rh-amount\">{e.amount}</span>\n                {e.unit && <span className=\"v1-rh-unit\">/ {e.unit}</span>}\n                {e.by && <span className=\"v1-rh-chip\"><UserOutlined /> {e.by}</span>}\n                {e.when && <span className=\"v1-rh-chip\"><ClockCircleOutlined /> {e.when}</span>}\n                {i === 0 && <span className=\"v1-rh-badge\">Latest</span>}\n              </div>\n            ))}\n          </div>\n        </div>\n      ))}\n    </Card>\n  );\n\n  // Where the history card goes. `group.historyAfterGroup` (admin config) names\n  // the group it should follow; with none configured it falls back to the\n  // employer group — by name or by carrying employerId — which is where every\n  // module placed it before the setting existed.\n  const historyAfterGroupName = useMemo(() => {\n    const owner = formGroups.find((g) => truthy(g.appendHistory) && g.historyAfterGroup);\n    return String(owner?.historyAfterGroup ?? '').trim().toLowerCase();\n  }, [formGroups]);\n\n  const isEmployerGroup = (group) => {\n    if (historyAfterGroupName) {\n      return String(group.name ?? '').trim().toLowerCase() === historyAfterGroupName;\n    }\n    return /current_employer|employer_details/i.test(group.name || '')\n      || (group.fields || []).some((f) => f.field === 'employerId');\n  };\n\n  return (\n    <Spin spinning={loading} tip=\"Loading detail fields...\">\n      <div className=\"v1-detail-left\">\n        {error && (\n          <Alert\n            type=\"error\"\n            showIcon\n            message=\"Unable to load detail fields\"\n            description={error}\n            className=\"v1-detail-alert\"\n          />\n        )}\n\n        {!loading && !error && displayGroups.length === 0 && historyBlocks.length === 0 && (\n          <Empty description=\"No detail fields are configured.\" />\n        )}\n        {/* Groups, with the merged \"Rate Details\" history card injected right\n            after the Employer Details group (driven by appendHistory config). */}\n        {displayGroups.flatMap((group, index) => {\n          const els = [renderGroup(group, index)];\n          if (isEmployerGroup(group) && historyBlocks.length > 0) els.push(renderRateDetailsCard());\n          return els;\n        })}\n        {/* No employer group on this module → show Rate Details at the end. */}\n        {historyBlocks.length > 0 && !displayGroups.some(isEmployerGroup) && renderRateDetailsCard()}\n\n        {/* Description — jobs module only, displayed exactly as saved. */}\n        {isJob && jobDescription?.value && (\n          <Card\n            size=\"small\"\n            className=\"v1-card v1-detail-card\"\n            title={<SectionTitle icon={<FileTextOutlined />} title=\"Description\" />}\n            // extra={\n            //   !descEditing && (\n            //     <AppButton type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={handleDescEditStart}>\n            //       Edit\n            //     </AppButton>\n            //   )\n            // }\n          >\n            {descEditing ? (\n              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n                <div style={{\n                  background: '#ffffff',\n                  border: '1px solid #d6e4f0',\n                  borderRadius: 8,\n                  padding: '4px',\n                  boxShadow: '0 2px 8px rgba(0,0,0,0.04)',\n                }}>\n                  <Input.TextArea\n                    rows={10}\n                    value={descEditRaw}\n                    onChange={(e) => setDescEditRaw(e.target.value)}\n                    placeholder={jobDescription.hidePlaceholder ? undefined : jobDescription.placeholder}\n                    style={{\n                      fontSize: 13,\n                      lineHeight: 1.65,\n                      border: 'none',\n                      boxShadow: 'none',\n                      resize: 'vertical',\n                      padding: '12px 14px',\n                    }}\n                  />\n                </div>\n                <div style={{ display: 'flex', gap: 8 }}>\n                  <AppButton variant=\"primary\" size=\"small\" loading={descSaving} onClick={handleDescEditSave}>\n                    Save & Parse\n                  </AppButton>\n                  <AppButton size=\"small\" onClick={handleDescEditCancel}>Cancel</AppButton>\n                </div>\n              </div>\n            ) : (\n              <RawDescription value={jobDescription.value} />\n            )}\n          </Card>\n        )}\n      </div>\n    </Spin>\n  );\n}\n","import React from 'react';\nimport { Col, Row } from 'antd';\nimport { asText, capitalize, symbol, formatRate, has, lookupId } from '../configUtils';\nimport DetailViewV1 from '../../../DetailViewV1';\nimport ActivityNotesCard from '../../ActivityNotesCard';\n\n/*\n * Job detail config.\n *\n *   tabs / actions / tabContent → the static parts of the page.\n *   header                      → fill-in-the-blanks header description.\n *\n * In `header` you just list which fields go where (title, ids, meta, …). See\n * headerSpec.js for the full list of options. A `field` is the API field name;\n * ['a', 'b'] means \"a, or b if a is empty\".\n */\nexport const jobConfig = {\n  module: 'job',\n  tabs: [\n    { key: 'details', label: 'Details' },\n    { key: 'candidates', label: 'Candidates' },\n  ],\n  tabContent: {\n    details: {\n      render: ({ id, refreshKey, onDescriptionSaved }) =>\n        React.createElement(\n          Row, { gutter: [16, 16], align: 'stretch' },\n          React.createElement(Col, { key: 'main', xs: 24, lg: 16 },\n            React.createElement(DetailViewV1, { moduleName: 'job', id, refreshKey, onDescriptionSaved })\n          ),\n          React.createElement(Col, { key: 'side', xs: 24, lg: 8 },\n            React.createElement(ActivityNotesCard, { moduleName: 'job', id })\n          )\n        ),\n    },\n\n  },\n  header: {\n    title: 'jobTitle',\n\n    // \"Client - MSP Id 123\"; falls back to the Zinnext job id when neither is set.\n    eyebrow: ({ val }) => {\n      const parts = [];\n      if (has(clientName(val))) parts.push(asText(clientName(val)));\n      if (has(mspId(val))) parts.push(`MSP Id ${asText(mspId(val))}`);\n      if (parts.length) return parts.join(' - ');\n      return has(val('jobReferenceId')) ? String(val('jobReferenceId')) : '';\n    },\n\n    clientName: ({ val }) => clientName(val),\n\n       // Shown next to the title.\n    titleIds: [\n      // { label: 'MS Req ID',     field: ['mspReqId', 'mspreqId', 'msReqId', 'mspId', 'mspRequirementId'] },\n      // { label: 'Client Req ID', field: ['clientJobReferenceId', 'clientReqId', 'clientRequirementId', 'clientReferenceId'] },\n    ],\n\n    status: { field: 'jobStatus' },\n\n    // Shown under the title.\n    ids: [\n      { label: 'Zinnext Job ID', field: 'jobReferenceId' },\n      { label: 'Client Rate',    compute: clientRate },\n    ],\n\n    meta: [\n      { icon: 'location',   field: 'jobLocation' },\n      { icon: 'experience', compute: experienceRange },\n      { icon: 'employment', fields: ['employmentType', 'jobRemoteStatus'], join: ' · ' },\n    ],\n\n    // Summary numbers on the right.\n    stats: [\n      { label: 'Target submissions', field: ['targetSubmission', 'targetSubmissions'] },\n      { label: 'In Pipeline',        compute: inPipeline, always: true },\n    ],\n\n    timestamp: { label: 'Created Date', field: ['createdAt', 'jobCreatedDateTime', 'createdDate'] },\n  },\n};\n\n// First field (from a list) that has a value — for the little formulas below.\nconst first = (val, ...keys) => keys.map((k) => val(k)).find(has);\n\nconst clientName = (val) => first(val, 'clientName', 'client.name', 'client', 'clientId', 'accountName');\nconst mspId = (val) => first(val, 'mspReqId', 'mspreqId', 'msReqId', 'mspId', 'mspRequirementId');\n\n// \"3 - 6 years\" (the upper bound is optional).\nfunction experienceRange({ val }) {\n  const from = val('experience.experienceRequiredFrom');\n  if (!has(from)) return '';\n  const to = val('experience.experienceRequiredTo');\n  return `${from}${has(to) ? ` - ${to}` : ''} years`;\n}\n\n// Client budget, e.g. \"₹34 - 55/Monthly\".\nfunction clientRate({ val }) {\n  const pay = val('jobPayDetails') ?? {};\n  const start = pay.clientBudgetStart ?? first(val, 'clientBudgetStart', 'clientRateStart');\n  if (!has(start)) return '';\n  return formatRate({\n    start,\n    end: pay.clientBudgetEnd ?? first(val, 'clientBudgetEnd', 'clientRateEnd'),\n    sym: pay.clientBudgetCurrencySymbol ?? symbol(pay.clientBudgetCurrency) ?? '',\n    unit: pay.clientBudgetUnit ?? first(val, 'clientBudgetUnit'),\n  });\n}\n\n// Count of candidates currently in the pipeline (0 when none).\nfunction inPipeline({ val }) {\n  const subs = val('submissions');\n  const count = first(val, 'pipelineCount', 'PipelineCount', 'inPipeline', 'inPipelineCount')\n    ?? (Array.isArray(subs) ? subs.length : undefined);\n  return has(count) ? count : 0;\n}\n\nexport default jobConfig;\n\n\nexport function buildJobHeaderData({ val, has }) {\n  let eyebrow;\n  const meta = [];\n\n  if (has(val('jobReferenceId'))) eyebrow = String(val('jobReferenceId'));\n\n  const title = [val('jobTitle')].filter(has).map(asText).join(' ') || '-';\n\n  let status = null;\n  if (has(val('jobSource'))) {\n    status = {\n      label: capitalize(val('jobSource')),\n      color: '#10b981',\n      textColor: '#ffffff',\n    };\n  }\n\n  if (has(val('jobLocation'))) meta.push({ icon: 'location', text: asText(val('jobLocation')) });\n\n  if (has(val('experience.experienceRequiredFrom'))) {\n    const from = val('experience.experienceRequiredFrom');\n    const to = val('experience.experienceRequiredTo');\n    meta.push({ icon: 'experience', text: `${from}${has(to) ? ` - ${to}` : ''} years` });\n  }\n\n  const employment = [val('employmentType'), asText(val('jobRemoteStatus'))]\n    .filter(has)\n    .join(' - ');\n  if (employment) meta.push({ icon: 'employment', text: employment });\n\n  // clientId rides along so callers (e.g. QuickSubmitForm's client-scope\n  // gate) can read it off the header data DetailHeaderCard already fetched,\n  // instead of issuing a second, duplicate getFormGroups({module:'job'}) call.\n  const clientId = has(val('clientId')) ? lookupId(val('clientId')) : null;\n\n  return { eyebrow, title, status, meta, clientId };\n}\n","import { financeChips } from '../financeHeaderCommon';\n\n/*\n * Payroll detail config (built-in) — mirror of billingConfig.js. Auto-registered\n * under module key \"payroll\". Same DetailHeaderCard `variant: 'finance'` path\n * (finance header design), resolved against financeRecords\n * (recordKey:\"timesheetId\"). Only the status field differs (payroll.status).\n */\nexport const payrollConfig = {\n  module: 'payroll',\n  tabs: [],\n  header: {\n    variant: 'finance',\n    title: 'candidateName',\n    eyebrow: 'designation',\n    statusField: 'payroll.status',\n    chips: financeChips,\n  },\n};\n\nexport default payrollConfig;\n","import { asText, capitalize, statusColor, symbol, formatRate } from '../configUtils';\n\n/*\n * Submission detail header — fill-in-the-blanks config.\n * See headerSpec.js for what each part means. In short: list the fields you\n * want under title / eyebrow / status / ids / meta and the engine formats them.\n */\nexport const submissionConfig = {\n  module: 'submission',\n  tabs: [],\n  header: {\n    title: ['firstName', 'lastName'],\n\n    // \"Client - Job Title\" — the role this candidate was submitted to.\n    eyebrow: ({ val, has }) => [clientName(val), val('jobTitle')]\n      .filter(has).map(asText).join(' - '),\n\n    clientName: ({ val }) => clientName(val),\n\n    // Internal submission status, coloured by its type (positive/negative/…).\n    status: ({ val, has }) => {\n      const internal = val('internalSubmissionStatus') ?? {};\n      const text = internal.internalSubmissionStatusText;\n      if (!has(text)) return null;\n      const byType = { positive: 'success', negative: 'error', neutral: 'default' };\n      return { label: capitalize(text), color: byType[internal.internalSubmissionStatusType] ?? statusColor(text) };\n    },\n\n    ids: [\n      { label: 'Submission ID', field: ['submissionId', 'clientSubmissionId'] },\n      { label: 'MS Req ID',     field: ['mspReqId', 'mspreqId'] },\n      { label: 'Client Req ID', field: ['jobClientRefrenceId', 'jobClientReferenceId', 'clientJobReferenceId'] },\n      { label: 'Job ID',        field: ['jobRefrenceId', 'jobReferenceId'] },\n    ],\n\n    meta: [\n      { icon: 'location',   field: 'jobLocation' },\n      { icon: 'experience', field: ['relevantExperienceYears', 'workExperienceYears'], suffix: ' yrs' },\n      { icon: 'employment', field: 'workAuthorisation' },\n      { icon: 'rate',       prefix: 'Client rate: ',    compute: clientRate },\n      { icon: 'rate',       prefix: 'Candidate rate: ', compute: candidateRate },\n    ],\n\n    timestamp: { label: 'Created Date', field: ['submittedAt', 'createdAt', 'createdDate'] },\n  },\n};\n\n// Client name, falling back to the nested client.name shape.\nconst clientName = (val) => {\n  const raw = val('clientName') ?? val('client.name');\n  return raw;\n};\n\n// Client rate (clientBudget), falling back to the legacy candidateBudget shape.\nfunction clientRate({ val }) {\n  const cb = val('clientBudget') ?? val('candidateBudget') ?? {};\n  return formatRate({\n    start: cb.clientBudgetStart ?? cb.candidateBudgetStart,\n    end: cb.clientBudgetEnd ?? cb.candidateBudgetEnd,\n    sym: cb.clientBudgetCurrencySymbol ?? cb.candidateBudgetCurrencySymbol\n      ?? symbol(cb.clientBudgetCurrency ?? cb.candidateBudgetCurrency),\n    unit: cb.clientBudgetUnit ?? cb.candidateBudgetUnit ?? 'Hour',\n  });\n}\n\n// Candidate rate — accepted rate first, then the proposed rate.\nfunction candidateRate({ val }) {\n  const accepted = val('candidateRate') ?? {};\n  const proposed = val('proposedRate') ?? {};\n  return formatRate({\n    start: accepted.candidateAcceptedRate,\n    sym: accepted.candidateAcceptedCurrencySymbol ?? symbol(accepted.candidateAcceptedCurrency),\n    unit: accepted.candidateAcceptedPayUnit ?? 'Hour',\n  }) || formatRate({\n    start: proposed.candidateProposedRate,\n    sym: proposed.candidateProposedRateCurrencySymbol ?? symbol(proposed.candidateProposedRateCurrency),\n    unit: proposed.candidateProposedRateUnit ?? 'Hour',\n  });\n}\n\nexport default submissionConfig;\n","import { buildJobHeaderData } from './jobConfig';\n\n/*\n * Custom header config for Add Submission.\n * It fetches job form-groups through DetailHeaderCard's moduleName=\"job\",\n * but renders a simpler job context card for the submission create flow.\n */\nexport const submissionJobConfig = {\n  module: 'submissionJob',\n  tabs: [],\n  buildData: buildJobHeaderData,\n};\n\nexport default submissionJobConfig;\n","/*\n * Tiny engine that turns a plain-data `header` spec into the header parts the\n * detail page expects (eyebrow / title / status / ids / meta / stats / …).\n *\n * The goal: a module's header should read like a form you fill in, not code.\n * Each config just lists WHICH fields to show, their labels, icons and order –\n * this file does the boring work of reading the values and formatting them.\n *\n * A \"field\" is the API field key. Anywhere a field is expected you may pass:\n *   'fieldName'                    → that one field\n *   ['fieldA', 'fieldB']           → the first of these that has a value\n *\n * For the rare value that needs real maths (a salary range, years+months, …)\n * use `compute: ({ val, has }) => 'text'` and write the little formula there.\n */\nimport { asText, capitalize, statusColor, formatDateTime, has } from './configUtils';\n\n// First field (from a key or list of keys) that actually has a value.\nfunction pick(val, source) {\n  const keys = Array.isArray(source) ? source : [source];\n  for (const key of keys) if (has(val(key))) return val(key);\n  return undefined;\n}\n\n// Join several fields together, skipping the empty ones (e.g. first + last).\nfunction joinFields(val, keys, separator = ' ') {\n  return keys.map((k) => val(k)).filter(has).map(asText).join(separator);\n}\n\n// Resolve one \"line of text\" item used by meta rows and the eyebrow.\n// Honours: compute | join (fields) | field, plus an optional prefix/suffix.\nfunction buildText(ctx, item) {\n  const { val } = ctx;\n  let text;\n  if (typeof item.compute === 'function') text = item.compute(ctx);\n  else if (item.join) text = joinFields(val, item.fields ?? [], item.join);\n  else { const raw = pick(val, item.field); text = has(raw) ? asText(raw) : ''; }\n\n  if (!has(text)) return '';\n  return `${item.prefix ?? ''}${asText(text)}${item.suffix ?? ''}`;\n}\n\n// Normalise the eyebrow shorthand: a bare string/array means \"show this field\".\nfunction normaliseItem(item) {\n  if (typeof item === 'function') return { compute: item };\n  if (typeof item === 'string' || Array.isArray(item)) return { field: item };\n  return item;\n}\n\nexport function buildFromSpec(spec = {}, ctx) {\n  const { val } = ctx;\n  const out = {};\n\n  // ── Title — joins every listed field with a space (one field is fine too) ──\n  if (spec.title !== undefined) {\n    const keys = Array.isArray(spec.title) ? spec.title : [spec.title];\n    out.title = joinFields(val, keys) || '-';\n  }\n\n  // ── Eyebrow — small line above the title ───────────────────────────────────\n  if (spec.eyebrow !== undefined) {\n    out.eyebrow = buildText(ctx, normaliseItem(spec.eyebrow)) || undefined;\n  }\n\n  // ── Client name (used by some modules next to the title) ───────────────────\n  if (spec.clientName !== undefined) {\n    out.clientName = buildText(ctx, normaliseItem(spec.clientName)) || undefined;\n  }\n\n  // ── Status pill ────────────────────────────────────────────────────────────\n  if (spec.status !== undefined) {\n    if (typeof spec.status === 'function') {\n      out.status = spec.status(ctx) ?? null;\n    } else {\n      const raw = pick(val, spec.status.field);\n      out.status = has(raw)\n        ? { label: capitalize(raw), color: statusColor(raw) }\n        : null;\n    }\n  }\n\n  // ── Identifier chips (ids = under the title, titleIds = beside it) ─────────\n  const buildChips = (chips = []) =>\n    chips\n      .map((chip) => {\n        const value = typeof chip.compute === 'function'\n          ? chip.compute(ctx)\n          : asText(pick(val, chip.field) ?? '');\n        return { label: chip.label, value };\n      })\n      .filter((chip) => has(chip.value));\n\n  if (spec.ids !== undefined) out.ids = buildChips(spec.ids);\n  if (spec.titleIds !== undefined) out.titleIds = buildChips(spec.titleIds);\n\n  // ── Meta row (icon + text) ─────────────────────────────────────────────────\n  if (spec.meta !== undefined) {\n    out.meta = spec.meta\n      .map((item) => ({ icon: item.icon, text: buildText(ctx, item) }))\n      .filter((item) => has(item.text));\n  }\n\n  // ── Stats (right-hand summary numbers) ─────────────────────────────────────\n  if (spec.stats !== undefined) {\n    out.stats = spec.stats\n      .map((stat) => {\n        const raw = typeof stat.compute === 'function' ? stat.compute(ctx) : pick(val, stat.field);\n        const value = has(raw) ? asText(raw) : (stat.always ? asText(stat.fallback ?? 0) : undefined);\n        return { label: stat.label, value };\n      })\n      .filter((stat) => stat.value !== undefined);\n  }\n\n  // ── Timestamp line (a date, e.g. \"Created Date : …\") ───────────────────────\n  if (spec.timestamp !== undefined) {\n    const value = formatDateTime(pick(val, spec.timestamp.field));\n    out.timestamp = has(value) ? { label: spec.timestamp.label, value } : null;\n  }\n\n  return out;\n}\n\nexport default buildFromSpec;\n","/*\n * Common detail-header builder — module-centric and self-completing.\n *\n * Every file under ./modules/*.js is auto-imported and registered by its\n * `module` key. Adding a brand-new module is optional: if a config exists its\n * `buildData` is used, otherwise a GENERIC builder derives a sensible header\n * from common field-name patterns. Either way every module page gets a header.\n *\n * Each module config may expose:\n *   module                         → key matched against `moduleName`\n *   tabs → static navigation UI. Actions are loaded from Admin configuration.\n *   buildData({ val, has })        → dynamic header parts from the API fields\n *\n * Data parts (eyebrow / title / status / ids / meta / stats / timestamp) come\n * from buildData, with generic fallbacks merged in for anything it omits.\n * Icons are kept as string keys and mapped to components in DetailHeaderCard.\n */\nimport {\n  asText,\n  capitalize,\n  formatDateTime,\n  has,\n  isEmpty,\n  statusColor,\n} from './configUtils';\nimport { buildFromSpec } from './headerSpec';\n\n// Vite glob — eagerly pulls in every module config at build time.\nconst moduleFiles = import.meta.glob('./modules/*.js', { eager: true });\n\nconst REGISTRY = {};\nObject.values(moduleFiles).forEach((mod) => {\n  const config = mod.default ?? Object.values(mod)[0];\n  if (config?.module) REGISTRY[config.module] = config;\n});\n\n// Singular/plural + alias map so 'jobs'/'job', 'candidates'/'candidate',\n// 'submissions'/'submission', etc. all resolve to the registered config key.\nconst MODULE_ALIASES = {\n  job: 'job', jobs: 'job',\n  candidate: 'candidate', candidates: 'candidate', applicant: 'candidate', applicants: 'candidate',\n  submission: 'submission', submissions: 'submission',\n  vendor: 'vendor', vendors: 'vendor',\n  onboarding: 'onboarding',\n  employer: 'employer', employers: 'employer',\n};\n\n// Returns the effective registry: built-in glob-discovered configs merged with\n// whatever the host injected via configureCoreTheme({ detailConfig: { … } }).\n// Called at render time so host configs registered in main.jsx are always seen.\nfunction getEffectiveRegistry() {\n  const hostConfigs =\n    (typeof window !== 'undefined' && window.__CORE_THEME_CONFIG__?.detailConfig) ?? {};\n  if (!Object.keys(hostConfigs).length) return REGISTRY;\n  return { ...REGISTRY, ...hostConfigs };\n}\n\n// Resolve whatever name a page passes to a registered config key (best-effort).\nfunction resolveModuleKey(moduleName = '', registry = REGISTRY) {\n  const raw = String(moduleName).trim();\n  if (registry[raw]) return raw;\n\n  const lower = raw.toLowerCase();\n  if (registry[lower]) return lower;\n\n  const alias = MODULE_ALIASES[lower];\n  if (alias && registry[alias]) return alias;\n\n  // Last-ditch singular/plural flip.\n  const flipped = lower.endsWith('s') ? lower.slice(0, -1) : `${lower}s`;\n  if (registry[flipped]) return flipped;\n\n  return alias ?? lower;\n}\n\n// Flatten every field across groups into a key → field lookup.\nfunction indexFields(formGroups = []) {\n  const map = new Map();\n  formGroups.forEach((group) => {\n    (group.fields ?? []).forEach((field) => {\n      if (!map.has(field.field)) map.set(field.field, field);\n    });\n  });\n  return map;\n}\n\n// Returns the first non-empty value across a list of candidate keys. A key may\n// be a \"a+b\" pair, which joins the two field values (e.g. firstName+lastName).\nfunction pickFirst(val, keys) {\n  for (const key of keys) {\n    if (key.includes('+')) {\n      const joined = key.split('+').map((k) => val(k)).filter(has).map(asText).join(' ');\n      if (joined) return joined;\n    } else if (has(val(key))) {\n      return val(key);\n    }\n  }\n  return undefined;\n}\n\n/*\n * Generic, module-agnostic header. Works for ANY module by probing the most\n * common field names. Per-module configs override these where they care.\n */\nfunction genericBuildData({ val }) {\n  const title = pickFirst(val, [\n    'jobTitle', 'firstName+lastName', 'name', 'fullName', 'title',\n    'clientName', 'vendorCompanyName', 'companyName',\n  ]) || '-';\n\n  const eyebrowRaw = pickFirst(val, [\n    'clientName', 'source', 'designation', 'jobReferenceId', 'applicantRefrenceId',\n  ]);\n  const eyebrow = has(eyebrowRaw) ? asText(eyebrowRaw) : undefined;\n\n  const statusRaw = pickFirst(val, ['status', 'jobStatus', 'submissionStatus', 'stage']);\n  const status = has(statusRaw)\n    ? { label: capitalize(statusRaw), color: statusColor(statusRaw) }\n    : null;\n\n  // Reference-id chips under the title.\n  const ids = [];\n  const idChips = [\n    ['Reference ID', ['jobReferenceId', 'applicantRefrenceId', 'submissionId', 'referenceId', 'refId']],\n    ['Client Req ID', ['clientJobReferenceId', 'jobClientRefrenceId', 'clientReqId']],\n    ['MS Req ID', ['mspreqId', 'mspReqId']],\n  ];\n  idChips.forEach(([label, keys]) => {\n    const v = pickFirst(val, keys);\n    if (has(v)) ids.push({ label, value: asText(v) });\n  });\n\n  // A small meta row.\n  const meta = [];\n  const location = pickFirst(val, ['jobLocation', 'currentLocation', 'location']);\n  if (has(location)) meta.push({ icon: 'location', text: asText(location) });\n  const designation = pickFirst(val, ['designation']);\n  if (has(designation)) meta.push({ icon: 'designation', text: asText(designation) });\n\n  const created = formatDateTime(pickFirst(val, ['createdAt', 'submittedAt', 'createdDate']));\n  const timestamp = has(created) ? { label: 'Created Date', value: created } : null;\n\n  return { eyebrow, title, status, ids, meta, timestamp };\n}\n\nexport function getModuleConfig(moduleName) {\n  const registry = getEffectiveRegistry();\n  return registry[resolveModuleKey(moduleName, registry)] ?? null;\n}\n\nexport function buildHeaderFromGroups(moduleName, formGroups = [], { aux } = {}) {\n  if (!formGroups.length) return null;\n\n  const registry = getEffectiveRegistry();\n  const config = registry[resolveModuleKey(moduleName, registry)];\n\n  const fields = indexFields(formGroups);\n  const val = (key) => {\n    const field = fields.get(key);\n    if (!field) {\n      // Not every value a header needs is a FORM field. getFormGroups rides the\n      // record's audit stamps and its top-level scalar ids along as\n      // `recordMeta`, and a header legitimately wants those: the job code\n      // (jobReferenceId) is generated by the backend and never appears on the\n      // add/edit form, so it was simply unreachable here and the card could not\n      // show it at all.\n      //\n      // This used to allow ONLY createdAt/updatedAt, which made the restriction\n      // arbitrary — the data was already present for every other key in the map.\n      // Reading the whole of recordMeta costs nothing and fixes the class.\n      return formGroups.recordMeta?.[key];\n    }\n    if (!isEmpty(field.value)) return field.value;\n\n    // Status defaults are meaningful in headers when an older record has no\n    // embedded status value. Other field defaults remain add-form concerns and\n    // must not be presented as persisted detail data.\n    if (['status', 'jobStatus', 'submissionStatus'].includes(key)\n      && !isEmpty(field.defaultValue)) {\n      return field.defaultValue;\n    }\n    return field.value;\n  };\n\n  // Generic defaults always run; a per-module header (when present) layers on\n  // top so every module renders a complete, consistent header. A module may\n  // describe its header declaratively via `header` (preferred, see headerSpec)\n  // or imperatively via `buildData` — both produce the same shape.\n  // `field(key)` hands a header config the field's whole ADMIN CONFIG (label,\n  // renderType, valueStyles, …) — not just its value. That is what lets a meta\n  // entry colour itself from the same seeded `valueStyles` array the ListView\n  // badge engine reads, instead of a palette hardcoded in the config file.\n  const field = (key) => fields.get(key) ?? null;\n\n  // `aux(key)` reaches a SECOND record the host asked DetailHeaderCard to\n  // resolve alongside this one (see ../auxRecords.js) — e.g. the Quick Submit\n  // job header reading the candidate's source. It always returns a reader\n  // function, so `aux('candidate')('source')` is safe even with no aux records\n  // declared, and a config that never calls it is completely unaffected.\n  const readAux = typeof aux === 'function' ? aux : () => () => undefined;\n\n  const generic = genericBuildData({ val, has });\n  const specific = config?.buildData\n    ? (config.buildData({ val, has, field, aux: readAux }) ?? {})\n    : (config?.header ? buildFromSpec(config.header, { val, has, field, aux: readAux }) : {});\n\n  // An explicitly configured array owns the section even when it is empty.\n  // This lets a host config intentionally suppress generic ids/meta by\n  // returning `ids: []` or `meta: []`, while an omitted property still falls\n  // back to the generic builder.\n  const preferArray = (specificValue, genericValue) => (\n    Array.isArray(specificValue) ? specificValue : (genericValue ?? [])\n  );\n\n  // The status pill is the one section a config could not previously suppress:\n  // returning `null` is indistinguishable from omitting it, so the generic\n  // builder's status/jobStatus/stage guess took over. `status: false` is the\n  // explicit \"this header has NO pill\" — falsy, so it never renders, but not\n  // nullish, so it survives the ?? chain below. Used by a header whose pill\n  // means something other than the record's status (e.g. Quick Submit's job\n  // card, whose pill is the candidate's source): when that value is missing the\n  // right answer is no pill, NOT the job's \"Active\". Configs that return null\n  // keep today's fall-through behavior untouched.\n  const status = specific.status === false ? null : (specific.status ?? generic.status ?? null);\n\n  return {\n    eyebrow: specific.eyebrow ?? generic.eyebrow,\n    title: specific.title ?? generic.title ?? '-',\n    clientName: specific.clientName ?? null,\n    clientId: specific.clientId ?? null,\n    status,\n    titleIds: preferArray(specific.titleIds, generic.titleIds),\n    meta: preferArray(specific.meta, generic.meta),\n    ids: preferArray(specific.ids, generic.ids),\n    stats: specific.stats ?? [],\n    timestamp: specific.timestamp ?? generic.timestamp ?? null,\n    tabs: config?.tabs ?? [],\n  };\n}\n\nexport { isEmpty, statusColor };\n","// ─────────────────────────────────────────────────────────────────────────\n// headerMeta — how ONE entry of a detail header's `meta` row is resolved.\n//\n// A meta entry used to be nothing but `{ icon, text }`: a finished string the\n// module's header config had already glued together (\"Candidate rate: $100\").\n// That made two things impossible, and both were reported as bugs:\n//\n//  1. A label that depends on the record. A C2C submission's rate belongs to\n//     the employer, so the header must read \"Employer rate\" — exactly the\n//     switch the FORM already performs through `field.labelWhen`. With the\n//     label baked into a template string the header could only ever say one\n//     thing, so it said the wrong one for half the records.\n//  2. A meta entry that is a STATE, not a sentence. \"Internal status: Shortlisted\"\n//     is a status and must read like one (a coloured pill), not like body text.\n//\n// So a meta entry may now describe itself instead of pre-rendering itself:\n//\n//   { label, value }        → rendered as \"label: value\" (text as before)\n//   { labelWhen: [rule] }   → label swapped when the rule matches the record;\n//                             SAME rule shape and matcher as showIf/labelWhen\n//                             in the form engine (one operator table, both\n//                             surfaces), so admin config transfers verbatim.\n//   { variant: 'pill', tone } → rendered through the status pill's own styling\n//   { valueStyles: [...] }  → colours from the admin field config, the SAME\n//                             array shape ListView's badge engine reads, so\n//                             recolouring a status stays admin work\n//\n// `text` still wins when a config supplies it, so every existing header config\n// keeps rendering byte-identically.\n// ─────────────────────────────────────────────────────────────────────────\n\nimport { conditionMatches } from '../form/conditionalFieldLabel';\n\nconst isEmpty = (v) => v === undefined || v === null || v === '';\n\n// Antd Tag colour keywords a `tone` maps onto. Tones — not colours — are what a\n// config declares, so the palette can change in one place.\nexport const META_TONE_COLORS = {\n  positive: 'success',\n  success: 'success',\n  negative: 'error',\n  error: 'error',\n  warning: 'warning',\n  info: 'processing',\n  neutral: 'default',\n  default: 'default',\n};\n\nfunction ruleList(raw) {\n  if (!raw) return [];\n  return (Array.isArray(raw) ? raw : [raw]).filter((rule) => rule?.field && rule?.label);\n}\n\n/**\n * resolveMetaLabel — the label this entry should carry for THIS record.\n *\n * FAIL CLOSED, exactly like detailFieldLabel: a rule whose field is absent from\n * the record cannot be judged, so it is skipped and the static label kept.\n * Asserting \"Employer rate\" on an unproven condition would mislabel real money.\n */\nexport function resolveMetaLabel(item, readValue) {\n  const read = typeof readValue === 'function' ? readValue : () => undefined;\n  for (const rule of ruleList(item?.labelWhen)) {\n    const value = read(rule.field);\n    if (value === undefined) continue;\n    if (conditionMatches(rule, value)) return rule.label;\n  }\n  return item?.label ?? '';\n}\n\n/**\n * metaValueStyle — the admin colour for this entry's value, matched\n * case-insensitively on value OR label. Mirrors ListView.getBadgeValueStyle and\n * financeUtils.getValueStyle so one seeded `valueStyles` array colours the list\n * cell, the finance table and this header pill identically.\n */\nexport function metaValueStyle(item) {\n  const styles = item?.valueStyles;\n  if (!Array.isArray(styles) || !styles.length) return null;\n  const needle = String(item?.value ?? item?.text ?? '').trim().toLowerCase();\n  if (!needle) return null;\n  const match = styles.find((style) => (\n    String(style?.value ?? '').trim().toLowerCase() === needle\n    || String(style?.label ?? '').trim().toLowerCase() === needle\n  ));\n  if (!match) return null;\n  return {\n    color: match.color || undefined,\n    bg: match.bg ?? match.background ?? match.backgroundColor ?? undefined,\n  };\n}\n\n/**\n * resolveMetaItem — everything the renderer needs for one entry:\n *   { icon, text, variant, tagColor, tagStyle }\n *\n * `readValue(fieldKey)` is supplied by the renderer (the flattened record on the\n * detail header), so this module stays free of any module/field knowledge.\n */\nexport function resolveMetaItem(item, readValue) {\n  const label = resolveMetaLabel(item, readValue);\n  const value = item?.value;\n  // A config that already produced its own sentence keeps it; otherwise the\n  // label and value are joined here, and ONLY when both exist — a value with no\n  // label must never render as \": Shortlisted\".\n  const text = !isEmpty(item?.text)\n    ? String(item.text)\n    : [label, isEmpty(value) ? '' : String(value)].filter(Boolean).join(label && !isEmpty(value) ? ': ' : '');\n\n  const variant = item?.variant === 'pill' ? 'pill' : 'text';\n  if (variant !== 'pill') return { icon: item?.icon, text, variant };\n\n  const style = metaValueStyle(item);\n  return {\n    icon: item?.icon,\n    // A pill shows the STATE; the label rides along as the pill's prefix only\n    // when the config asked for one via `pillLabel` (default: label + value, so\n    // \"Internal status: Shortlisted\" still reads as a labelled state).\n    text,\n    label,\n    value: isEmpty(value) ? '' : String(value),\n    variant,\n    // Explicit admin colours win over the tone keyword; with neither, the pill\n    // renders in antd's neutral default rather than guessing a meaning.\n    tagColor: style?.color || style?.bg ? undefined : (META_TONE_COLORS[item?.tone] ?? 'default'),\n    tagStyle: style?.color || style?.bg\n      ? { color: style.color, backgroundColor: style.bg, borderColor: style.bg ?? style.color }\n      : undefined,\n  };\n}\n\nexport default resolveMetaItem;\n","/*\n * Auxiliary header records — letting a header show a value that does NOT live\n * on the record it was built from.\n *\n * A detail header is single-record by construction: DetailHeaderCard is given\n * one `moduleName` + `id`, fetches that record's form-groups, and hands the\n * header config a `val(key)` bound to exactly those fields. That is right\n * almost everywhere, but some CONTEXT cards are deliberately rendered against\n * one module while describing a second one. The Quick Submit page is the case\n * that forced this: it renders the JOB header (moduleName=\"job\",\n * customConfigName=\"submissionJob\") on a page whose subject is a CANDIDATE\n * being submitted to that job, so a candidate-owned value such as \"where did\n * this candidate come from\" was simply unreachable from the header config.\n *\n * Rather than teach the header about candidates (or jobs, or submissions), the\n * host declares any number of EXTRA records it wants resolved alongside the\n * primary one:\n *\n *   <DetailHeaderCard\n *     moduleName=\"job\" customConfigName=\"submissionJob\" id={jobId}\n *     auxRecords={{ candidate: { module: 'candidate', id: applicantId } }}\n *   />\n *\n * and the header config reads them through an extra accessor that mirrors\n * `val`, one level deeper:\n *\n *   buildData({ val, has, field, aux }) → aux('candidate')('source')\n *\n * The HOST-PROP shape was chosen over a config-declared `auxiliary: [{ key,\n * module, idFrom }]` because only the host actually knows the other record's\n * id: on Quick Submit the candidate id is a URL query param, not a field of\n * the job — an `idFrom` pointing into the job's form-groups would have nothing\n * to read. The host already has both ids in hand, so passing them is exact\n * instead of inferred, and DetailHeaderCard stays free of any module-specific\n * routing/lookup knowledge.\n *\n * Everything here FAILS OPEN: an absent prop, a malformed entry, a missing id,\n * a failed request or an unknown key all resolve to `undefined` values. A\n * header must never blank out or throw because a secondary record could not be\n * loaded — it just renders without that part.\n */\n\n// Host prop → a stable, validated list of { key, module, id } fetch requests.\n// Entries without a module or without an id are dropped (not fetched): \"no id\n// yet\" is the normal state on a page whose candidate is still being chosen.\nexport function normalizeAuxRecords(auxRecords) {\n  if (!auxRecords || typeof auxRecords !== 'object') return [];\n  return Object.entries(auxRecords)\n    .map(([key, entry]) => {\n      if (!entry || typeof entry !== 'object') return null;\n      const module = String(entry.module ?? '').trim();\n      const id = entry.id == null ? '' : String(entry.id).trim();\n      if (!key || !module || !id) return null;\n      return { key: String(key), module, id };\n    })\n    .filter(Boolean);\n}\n\n// Cache/effect key: aux fetches must re-run when a declared record changes, but\n// NOT on every render (the prop is usually an inline object literal, so identity\n// alone is useless as a dependency).\nexport function auxRecordsSignature(auxRecords) {\n  return normalizeAuxRecords(auxRecords)\n    .map(({ key, module, id }) => `${key}:${module}:${id}`)\n    .sort()\n    .join('|');\n}\n\n// field key → value over one fetched form-groups payload. Deliberately simpler\n// than headerConfig's primary `val`: no status-default fallback and no\n// recordMeta audit stamps, because an auxiliary record is a value source, not\n// the subject of the header.\nexport function auxValueReader(formGroups) {\n  const values = new Map();\n  for (const group of formGroups ?? []) {\n    for (const item of group?.fields ?? []) {\n      if (item?.field != null && !values.has(item.field)) values.set(item.field, item.value);\n    }\n  }\n  return (key) => values.get(key);\n}\n\n// The `aux` accessor handed to buildData. `aux(key)` always returns a FUNCTION,\n// even for a key that was never declared or whose fetch failed, so a header\n// config can call aux('candidate')('source') unconditionally without guarding.\nexport function makeAuxAccessor(groupsByKey) {\n  const readers = new Map();\n  for (const [key, formGroups] of Object.entries(groupsByKey ?? {})) {\n    readers.set(key, auxValueReader(formGroups));\n  }\n  const missing = () => undefined;\n  return (key) => readers.get(key) ?? missing;\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// financeUtils — pure helpers for the Billing / Payroll finance module.\n// No JSX, no antd: formatting, lifecycle gating, timesheet derivations, CSV.\n//\n// The backend exposes NO lifecycle guards on the finance action endpoints —\n// any status can be set at any time. The gating functions here are therefore\n// the ONLY guard: they fail closed (everything disabled) on unknown status.\n// ─────────────────────────────────────────────────────────────────────────\n\nimport {\n  currencySymbol,\n  rateUnitShort,\n  toNumber,\n  formatMoney as formatMoneyShared,\n} from '../../utils/currency.js';\n\nconst num = (value) => {\n  const n = Number(value);\n  return Number.isFinite(n) ? n : 0;\n};\n\n// ── Formatting ─────────────────────────────────────────────────────────────\n// These delegate to the package-wide utils/currency helpers so the billing /\n// payroll tables print a number exactly the way the finance approval panel and\n// the detail view do. Both keep their old zero-argument behaviour ($ + hourly)\n// as the DEFAULT, so every existing call site is unaffected, but the currency\n// and the unit are now parameters — they used to be string literals, which is\n// what made a non-USD, non-hourly engagement render wrongly.\n\nexport function formatMoney(value, currency = '$') {\n  const n = toNumber(value);\n  return formatMoneyShared(Number.isNaN(n) ? 0 : n, currencySymbol(currency), { decimals: 2 });\n}\n\nexport function formatHours(value) {\n  return `${num(value).toFixed(2)} hrs`;\n}\n\n// formatRate(62.5) → \"$62.50/hr\" | formatRate(500, '₹', 'day') → \"₹500.00/day\"\n// An unresolvable unit yields the bare amount rather than a trailing slash.\nexport function formatRate(value, currency = '$', unit = 'hr') {\n  const short = rateUnitShort(unit, '');\n  const money = formatMoney(value, currency);\n  return short ? `${money}/${short}` : money;\n}\n\n// formatPercent renders a rate like 9.25 → \"9.25%\", 5.8 → \"5.8%\", 5 → \"5%\"\n// (up to two decimals, trailing zeros trimmed) for labelling a deduction with\n// the percentage it was derived from.\nexport function formatPercent(value) {\n  return `${parseFloat(num(value).toFixed(2))}%`;\n}\n\nexport function initialsOf(name) {\n  const words = String(name ?? '').trim().split(/\\s+/).filter(Boolean);\n  if (!words.length) return '·';\n  return words.slice(0, 2).map((w) => w[0].toUpperCase()).join('');\n}\n\n// ── Workflow events ────────────────────────────────────────────────────────\n\nconst WORKFLOW_EVENT_META = {\n  TIMESHEET_APPROVED: { label: 'Timesheet Approved', icon: 'check', tone: 'success' },\n  BILLING_READY: { label: 'Ready for Billing', icon: 'file', tone: 'info' },\n  BILLING_INVOICED: { label: 'Invoice Generated', icon: 'file', tone: 'info' },\n  BILLING_PAID: { label: 'Client Payment Received', icon: 'dollar', tone: 'success' },\n  PAYROLL_PROCESSING: { label: 'Payroll Processing Started', icon: 'sync', tone: 'warning' },\n  PAYROLL_PAID: { label: 'Payroll Disbursed', icon: 'dollar', tone: 'success' },\n  PAYSLIP_GENERATED: { label: 'Payslip Generated', icon: 'file', tone: 'info' },\n};\n\nexport function humanizeEvent(event) {\n  const known = WORKFLOW_EVENT_META[event];\n  if (known) return known;\n  const label = String(event ?? '')\n    .toLowerCase()\n    .split('_')\n    .filter(Boolean)\n    .map((w) => w[0].toUpperCase() + w.slice(1))\n    .join(' ');\n  return { label: label || 'Activity', icon: 'file', tone: 'neutral' };\n}\n\nexport function getApprovalDate(workflow) {\n  const hit = (Array.isArray(workflow) ? workflow : []).find((w) => w?.event === 'TIMESHEET_APPROVED');\n  return hit?.at ?? null;\n}\n\n// ── Lifecycle gating (client-side only — fail closed) ──────────────────────\n\nconst enabled = (variant) => ({ enabled: true, variant, disabledReason: null });\nconst disabled = (reason) => ({ enabled: false, variant: 'default', disabledReason: reason });\n\nexport const BILLING_STATUS_FLOW = ['PaymentNotReceived', 'Invoiced', 'Paid'];\nexport const PAYROLL_STATUS_FLOW = ['Ready', 'Processing', 'Paid'];\n\nexport function getBillingActionStates(status) {\n  switch (status) {\n    case 'PaymentNotReceived':\n      return {\n        generateInvoice: enabled('primary'),\n        recordPayment: disabled('Generate the invoice first'),\n        markPaid: disabled('Generate the invoice first'),\n      };\n    case 'Invoiced':\n      return {\n        generateInvoice: disabled('Invoice already generated'),\n        recordPayment: enabled('primary'),\n        markPaid: enabled('default'),\n      };\n    // Derived from the client-payment receipts log once money has moved\n    // (financeActualsSync.go deriveBillingStatus). Partially Received sits\n    // between Invoiced and fully paid: the invoice exists and still has a\n    // balance, so recording the next installment must stay available.\n    case 'Partially Received':\n      return {\n        generateInvoice: disabled('Invoice already generated'),\n        recordPayment: enabled('primary'),\n        markPaid: enabled('default'),\n      };\n    // Received is the fully-paid terminal state — reached automatically the\n    // moment the receipts cover the invoice — so it gates like Paid.\n    case 'Received':\n    case 'Paid':\n      return {\n        generateInvoice: disabled('Payment already received'),\n        recordPayment: disabled('Payment already received'),\n        markPaid: disabled('Payment already received'),\n      };\n    default:\n      return {\n        generateInvoice: disabled('Unavailable in the current status'),\n        recordPayment: disabled('Unavailable in the current status'),\n        markPaid: disabled('Unavailable in the current status'),\n      };\n  }\n}\n\n// Payslips are generated (and sent) AFTER the money has actually moved, never\n// before — so Generate Payslip only unlocks once the payroll is Paid, following\n// Process -> Mark Paid -> Generate Payslip in that order.\nexport function getPayrollActionStates(status) {\n  switch (status) {\n    case 'Ready':\n      return {\n        process: enabled('primary'),\n        generatePayslip: disabled('Mark the payroll paid first'),\n        markPaid: disabled('Process the payroll first'),\n      };\n    case 'Processing':\n      return {\n        process: disabled('Payroll is already processing'),\n        generatePayslip: disabled('Mark the payroll paid first'),\n        markPaid: enabled('primary'),\n      };\n    case 'Paid':\n      return {\n        process: disabled('Payroll already paid'),\n        generatePayslip: enabled('primary'),\n        markPaid: disabled('Payroll already paid'),\n      };\n    default:\n      return {\n        process: disabled('Unavailable in the current status'),\n        generatePayslip: disabled('Unavailable in the current status'),\n        markPaid: disabled('Unavailable in the current status'),\n      };\n  }\n}\n\n// Three-step progress strip. Step 1 is always done: a finance record only\n// exists after the timesheet is approved.\nexport function getWorkflowSteps(type, status) {\n  if (type === 'billing') {\n    const reached = Math.max(BILLING_STATUS_FLOW.indexOf(status), 0);\n    return [\n      { key: 'approved', label: 'Timesheet Approved', state: 'done' },\n      { key: 'invoiced', label: 'Invoice Raised', state: reached >= 1 ? 'done' : 'current' },\n      { key: 'paid', label: 'Payment Received', state: reached >= 2 ? 'done' : reached === 1 ? 'current' : 'pending' },\n    ];\n  }\n  const reached = Math.max(PAYROLL_STATUS_FLOW.indexOf(status), 0);\n  return [\n    { key: 'approved', label: 'Timesheet Approved', state: 'done' },\n    { key: 'processing', label: 'Processing', state: reached >= 1 ? 'done' : 'current' },\n    { key: 'paid', label: 'Paid', state: reached >= 2 ? 'done' : reached === 1 ? 'current' : 'pending' },\n  ];\n}\n\n// ── Timesheet derivations ──────────────────────────────────────────────────\n\nconst dayLeaveHours = (d) => num(d?.leave?.CL) + num(d?.leave?.SL);\nconst daySt = (d) => num(d?.workingHours?.ST);\nconst dayOt = (d) => num(d?.workingHours?.OT);\n\nexport function deriveDayStats(dailyLogs) {\n  const logs = Array.isArray(dailyLogs) ? dailyLogs : [];\n  const stats = {\n    loggedDays: 0,\n    approvedDays: 0,\n    rejectedDays: 0,\n    pendingDays: 0,\n    leaveDays: 0,\n    holidayDays: 0,\n    weekOffDays: 0,\n    stHours: 0,\n    otHours: 0,\n    leaveHours: 0,\n    totalHours: 0,\n    avgHoursPerLoggedDay: 0,\n  };\n  logs.forEach((d) => {\n    const st = daySt(d);\n    const ot = dayOt(d);\n    const leave = dayLeaveHours(d);\n    const logged = Boolean(d?.isLogged) || st > 0 || ot > 0;\n    if (logged) {\n      stats.loggedDays += 1;\n      if (d?.status === 'approved') stats.approvedDays += 1;\n      else if (d?.status === 'rejected') stats.rejectedDays += 1;\n      else stats.pendingDays += 1;\n    }\n    if (leave > 0) stats.leaveDays += 1;\n    if (d?.isHoliday) stats.holidayDays += 1;\n    if (d?.isWeekOff) stats.weekOffDays += 1;\n    stats.stHours += st;\n    stats.otHours += ot;\n    stats.leaveHours += leave;\n    stats.totalHours += st + ot;\n  });\n  stats.avgHoursPerLoggedDay = stats.loggedDays ? stats.totalHours / stats.loggedDays : 0;\n  return stats;\n}\n\n// Rows for the daily breakdown table: logged days plus leave/holiday markers.\nexport function buildDailyRows(dailyLogs, rate) {\n  const logs = Array.isArray(dailyLogs) ? dailyLogs : [];\n  return logs\n    .filter((d) => Boolean(d?.isLogged) || daySt(d) > 0 || dayOt(d) > 0 || dayLeaveHours(d) > 0 || d?.isHoliday)\n    .map((d) => {\n      const st = daySt(d);\n      const ot = dayOt(d);\n      const total = st + ot;\n      return {\n        key: d.date,\n        date: d.date,\n        day: d.day || '',\n        st,\n        ot,\n        leave: dayLeaveHours(d),\n        isHoliday: Boolean(d?.isHoliday),\n        total,\n        amount: total * num(rate),\n        status: d?.status || 'logged',\n        reviewer: d?.reviewedByName || '',\n        remarks: d?.rejectionReason || d?.notes || '',\n      };\n    });\n}\n\n// Parse \"YYYY-MM-DD\" as a LOCAL date (new Date('YYYY-MM-DD') would parse UTC\n// and can shift the weekday across timezones).\nfunction parseLocalDate(dateStr) {\n  const [y, m, d] = String(dateStr ?? '').split('-').map(Number);\n  if (!y || !m || !d) return null;\n  return new Date(y, m - 1, d);\n}\n\nconst shortDate = (date) => date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\n// Monday-based weekly rollup (matches the backend's Monday week boundaries).\nexport function buildWeeklyRollup(dailyLogs, rate) {\n  const logs = Array.isArray(dailyLogs) ? dailyLogs : [];\n  const weeks = new Map();\n  logs.forEach((d) => {\n    const date = parseLocalDate(d?.date);\n    if (!date) return;\n    const st = daySt(d);\n    const ot = dayOt(d);\n    const leave = dayLeaveHours(d);\n    if (!d?.isLogged && st <= 0 && ot <= 0 && leave <= 0) return;\n    const mondayOffset = (date.getDay() + 6) % 7;\n    const weekStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() - mondayOffset);\n    const key = weekStart.getTime();\n    if (!weeks.has(key)) {\n      const weekEnd = new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 6);\n      weeks.set(key, {\n        weekStart,\n        weekEnd,\n        label: `${shortDate(weekStart)} – ${shortDate(weekEnd)}`,\n        st: 0,\n        ot: 0,\n        leaveHours: 0,\n        total: 0,\n        amount: 0,\n        days: 0,\n      });\n    }\n    const week = weeks.get(key);\n    week.st += st;\n    week.ot += ot;\n    week.leaveHours += leave;\n    week.total += st + ot;\n    week.amount += (st + ot) * num(rate);\n    if (Boolean(d?.isLogged) || st > 0 || ot > 0) week.days += 1;\n  });\n  return [...weeks.values()].sort((a, b) => a.weekStart - b.weekStart);\n}\n\nexport function computeMarginBand(marginPercent, { high = 25, low = 10 } = {}) {\n  const pct = num(marginPercent);\n  if (pct >= high) return 'high';\n  if (pct < low) return 'low';\n  return 'mid';\n}\n\n// ── CSV export (client-side, RFC-4180 escaping) ────────────────────────────\n\nfunction csvCell(value) {\n  const text = value == null ? '' : String(value);\n  return /[\",\\n\\r]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\nexport function buildCsv(rows, columns) {\n  const header = columns.map((c) => csvCell(c.label)).join(',');\n  const lines = (rows ?? []).map((row) =>\n    columns.map((c) => csvCell(c.format ? c.format(row[c.key], row) : row[c.key])).join(','),\n  );\n  return [header, ...lines].join('\\r\\n');\n}\n\n// ── Admin field config (labels + status colors from userFieldConfig) ───────\n// `fields` is the `fields` array the /module-data-list response attaches for\n// module=billing|payroll — each entry is a FieldVisibilityConfig: { field,\n// label, renderType, valueStyles:[{value,label,color,bg,variant}], ... }.\n// These helpers let the finance table keep its own hand-built columns/cells\n// but source the LABEL and STATUS COLOR from admin config when present,\n// falling back to the built-in defaults when no config field matches.\n\nexport function indexFieldConfig(fields) {\n  const byKey = new Map();\n  (Array.isArray(fields) ? fields : []).forEach((field) => {\n    const key = field?.field ?? field?.key ?? field?.value;\n    if (key) byKey.set(key, field);\n  });\n  return byKey;\n}\n\nexport function getFieldLabel(fields, key, fallback) {\n  const byKey = fields instanceof Map ? fields : indexFieldConfig(fields);\n  return byKey.get(key)?.label || fallback;\n}\n\n// Matches case-insensitively on value or label, mirroring the ListView engine\n// (CORE-THEME/src/components/ListView.jsx getBadgeValueStyle).\nexport function getValueStyle(fields, key, value) {\n  const byKey = fields instanceof Map ? fields : indexFieldConfig(fields);\n  const styles = byKey.get(key)?.valueStyles;\n  if (!Array.isArray(styles) || !styles.length || value == null) return null;\n  const needle = String(value).toLowerCase();\n  const match = styles.find(\n    (s) => String(s.value ?? '').toLowerCase() === needle || String(s.label ?? '').toLowerCase() === needle,\n  );\n  if (!match) return null;\n  return { color: match.color, bg: match.bg ?? match.background ?? match.backgroundColor, label: match.label };\n}\n\nexport function downloadCsv(filename, csv) {\n  // Leading BOM so Excel opens the file as UTF-8.\n  const blob = new Blob(['\\uFEFF', csv], { type: 'text/csv;charset=utf-8;' });\n  const url = URL.createObjectURL(blob);\n  const link = document.createElement('a');\n  link.href = url;\n  link.download = filename;\n  document.body.appendChild(link);\n  link.click();\n  document.body.removeChild(link);\n  URL.revokeObjectURL(url);\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// Finance atoms — shared presentational building blocks for the Billing /\n// Payroll module. Purely presentational: no fetching, no routing.\n//\n// Back-compat: FinanceStatusPill / FinanceKpiRow / FinanceHoursGrid keep\n// their original prop shapes ({status}, {items:[{label,value,hint}]}, {days}).\n// ─────────────────────────────────────────────────────────────────────────\nimport { Tooltip } from 'antd';\nimport { formatAppDateTime } from '../../services/timezone';\nimport {\n  CheckCircleFilled,\n  CheckOutlined,\n  ClockCircleOutlined,\n  DollarCircleFilled,\n  FileTextFilled,\n  InboxOutlined,\n  SyncOutlined,\n} from '@ant-design/icons';\nimport { humanizeEvent } from './financeUtils';\nimport './finance-components.css';\n\n// ── Status pill ────────────────────────────────────────────────────────────\n\nconst STATUS_META = {\n  Draft: { label: 'Draft', tone: 'neutral' },\n  Ready: { label: 'Ready', tone: 'gold' },\n  Invoiced: { label: 'Invoiced', tone: 'info' },\n  Processing: { label: 'Processing', tone: 'info', pulse: true },\n  Paid: { label: 'Paid', tone: 'success' },\n  Overdue: { label: 'Overdue', tone: 'danger' },\n  PaymentNotReceived: { label: 'Not Received', tone: 'warning', full: 'Payment Not Received' },\n  // client-payment (receipts) statuses derived from Σ receipts vs invoice\n  'Partially Received': { label: 'Partially Received', tone: 'gold' },\n  Received: { label: 'Received', tone: 'success' },\n  'Ready to Pay': { label: 'Ready to Pay', tone: 'info', pulse: true },\n  // candidate-payment (disbursements) status — the payroll-side counterpart of\n  // 'Partially Received' above, derived from Σ disbursements vs netDisbursement\n  PartiallyPaid: { label: 'Partially Paid', tone: 'gold' },\n  // day-level statuses used inside the timesheet analysis table\n  approved: { label: 'Approved', tone: 'success' },\n  rejected: { label: 'Rejected', tone: 'danger' },\n  logged: { label: 'Pending', tone: 'gold' },\n};\n\n// styleOverride comes from an admin-configured userFieldConfig.valueStyles\n// entry ({ color, bg, label }, from financeUtils.getValueStyle) — when\n// present it wins over the built-in STATUS_META tone/label, so admins can\n// rename a status and recolor it from the Admin panel without a code change.\nexport function FinanceStatusPill({ status = 'Ready', size, styleOverride }) {\n  const meta = STATUS_META[status] ?? { label: String(status), tone: 'neutral' };\n  const label = styleOverride?.label ?? meta.label;\n  const inlineStyle = styleOverride\n    ? { color: styleOverride.color, background: styleOverride.bg, borderColor: styleOverride.color }\n    : undefined;\n  const pill = (\n    <span\n      className={`fin-pill${styleOverride ? '' : ` fin-pill--${meta.tone}`}${size === 'sm' ? ' fin-pill--sm' : ''}`}\n      style={inlineStyle}\n    >\n      <span className={`fin-pill__dot${meta.pulse ? ' fin-pill__dot--pulse' : ''}`} />\n      {label}\n    </span>\n  );\n  return meta.full ? <Tooltip title={meta.full}>{pill}</Tooltip> : pill;\n}\n\n// ── KPI cards ──────────────────────────────────────────────────────────────\n\nexport function FinanceKpiRow({ items = [], loading = false, compact = false }) {\n  const rowClass = `finance-kpi-row${compact ? ' finance-kpi-row--compact' : ''}`;\n  if (loading) {\n    const count = items.length || 4;\n    return (\n      <div className={rowClass}>\n        {Array.from({ length: count }, (_, i) => (\n          <div className=\"finance-kpi fin-kpi--skeleton\" key={i}>\n            <span className=\"fin-skeleton fin-skeleton--label\" />\n            <span className=\"fin-skeleton fin-skeleton--value\" />\n          </div>\n        ))}\n      </div>\n    );\n  }\n  return (\n    <div className={rowClass}>\n      {items.map((item) => (\n        <div className={`finance-kpi fin-kpi--${item.tone ?? 'neutral'}`} key={item.key ?? item.label}>\n          {item.icon ? <span className=\"fin-kpi__icon\">{item.icon}</span> : null}\n          <span className=\"fin-kpi__body\">\n            <span className=\"finance-kpi__label\">{item.label}</span>\n            <strong className=\"finance-kpi__value\">{item.value}</strong>\n            {item.sub ?? item.hint ? <span className=\"finance-kpi__hint\">{item.sub ?? item.hint}</span> : null}\n          </span>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// Legacy flat day grid — kept for API compatibility.\nexport function FinanceHoursGrid({ days = [] }) {\n  return (\n    <div className=\"finance-hours-grid\">\n      {days.map((day) => (\n        <div className=\"finance-hours-grid__day\" key={day.date}>\n          <span>{day.date}</span>\n          <strong>{Number(day?.workingHours?.ST ?? 0) + Number(day?.workingHours?.OT ?? 0)}</strong>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// ── Empty state ────────────────────────────────────────────────────────────\n\nexport function FinanceEmptyState({ icon, title, description, action, compact = false }) {\n  return (\n    <div className={`fin-empty${compact ? ' fin-empty--compact' : ''}`}>\n      <span className=\"fin-empty__icon\">{icon ?? <InboxOutlined />}</span>\n      <strong className=\"fin-empty__title\">{title}</strong>\n      {description ? <span className=\"fin-empty__desc\">{description}</span> : null}\n      {action ? <span className=\"fin-empty__action\">{action}</span> : null}\n    </div>\n  );\n}\n\n// ── Section card ───────────────────────────────────────────────────────────\n\nexport function FinanceSection({ title, extra, children, empty, className = '', span }) {\n  return (\n    <section className={`fin-section${span ? ' fin-section--span' : ''}${className ? ` ${className}` : ''}`}>\n      {title ? (\n        <header className=\"fin-section__head\">\n          <h4 className=\"fin-section__title\">{title}</h4>\n          {extra ? <span className=\"fin-section__extra\">{extra}</span> : null}\n        </header>\n      ) : null}\n      <div className=\"fin-section__body\">\n        {empty ? <FinanceEmptyState compact {...empty} /> : children}\n      </div>\n    </section>\n  );\n}\n\nexport function FinanceLine({ label, value, hint, strong, accent, negative }) {\n  const cls = [\n    'fin-line',\n    strong ? 'fin-line--strong' : '',\n    accent ? 'fin-line--accent' : '',\n    negative ? 'fin-line--negative' : '',\n  ].filter(Boolean).join(' ');\n  return (\n    <div className={cls}>\n      <span className=\"fin-line__label\">\n        {label}\n        {hint != null && hint !== '' ? <span className=\"fin-line__hint\">{hint}</span> : null}\n      </span>\n      <span className=\"fin-line__value\">{value}</span>\n    </div>\n  );\n}\n\nexport function FinanceDivider() {\n  return <div className=\"fin-divider\" />;\n}\n\n// ── Equation strip ─────────────────────────────────────────────────────────\n// terms: [{ value, label, tone: 'default'|'accent'|'strong' } | { op: '×'|'−'|'=' }]\n\nexport function FinanceEquation({ terms = [] }) {\n  return (\n    <div className=\"fin-equation\">\n      {terms.map((term, i) =>\n        term.op ? (\n          <span className=\"fin-eq__op\" key={`op-${i}`}>{term.op}</span>\n        ) : (\n          <span className={`fin-eq__term${term.tone ? ` fin-eq__term--${term.tone}` : ''}`} key={term.label ?? i}>\n            <span className=\"fin-eq__num\">{term.value}</span>\n            <span className=\"fin-eq__lbl\">{term.label}</span>\n          </span>\n        ),\n      )}\n    </div>\n  );\n}\n\n// ── Workflow progress steps ────────────────────────────────────────────────\n// steps: [{ key, label, state: 'done'|'current'|'pending' }]\n\nexport function FinanceWorkflowSteps({ steps = [] }) {\n  return (\n    <div className=\"fin-steps\">\n      {steps.map((step, i) => (\n        <div className={`fin-step fin-step--${step.state}`} key={step.key ?? step.label}>\n          {i > 0 ? <span className=\"fin-step__line\" /> : null}\n          <span className=\"fin-step__dot\">\n            {step.state === 'done' ? <CheckOutlined /> : null}\n          </span>\n          <span className=\"fin-step__label\">{step.label}</span>\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// ── History timeline ───────────────────────────────────────────────────────\n// events: raw workflow entries [{ event, at, by }] — newest rendered first.\n\nconst EVENT_ICONS = {\n  check: <CheckCircleFilled />,\n  dollar: <DollarCircleFilled />,\n  sync: <SyncOutlined />,\n  file: <FileTextFilled />,\n};\n\nfunction relativeTime(at) {\n  if (!at) return '';\n  const diffMs = Date.now() - new Date(at).getTime();\n  if (!Number.isFinite(diffMs) || diffMs < 0) return '';\n  const minutes = Math.floor(diffMs / 60000);\n  if (minutes < 1) return 'just now';\n  if (minutes < 60) return `${minutes}m ago`;\n  const hours = Math.floor(minutes / 60);\n  if (hours < 24) return `${hours}h ago`;\n  const days = Math.floor(hours / 24);\n  if (days < 30) return `${days}d ago`;\n  const months = Math.floor(days / 30);\n  if (months < 12) return `${months}mo ago`;\n  return `${Math.floor(months / 12)}y ago`;\n}\n\nexport function FinanceHistoryTimeline({ events = [], emptyState }) {\n  const list = (Array.isArray(events) ? [...events] : []).reverse();\n  if (!list.length) {\n    return (\n      <FinanceEmptyState\n        icon={<ClockCircleOutlined />}\n        title=\"No activity yet\"\n        description=\"Workflow events will appear here as this record moves through its lifecycle.\"\n        {...(emptyState ?? {})}\n      />\n    );\n  }\n  return (\n    <div className=\"fin-tl\">\n      {list.map((entry, i) => {\n        const meta = humanizeEvent(entry?.event);\n        return (\n          <div className=\"fin-tl__item\" key={`${entry?.event}-${entry?.at}-${i}`}>\n            <div className=\"fin-tl__rail\">\n              <span className={`fin-tl__icon fin-tl__icon--${meta.tone}`}>{EVENT_ICONS[meta.icon] ?? EVENT_ICONS.file}</span>\n              {i < list.length - 1 ? <span className=\"fin-tl__line\" /> : null}\n            </div>\n            <div className=\"fin-tl__body\">\n              <div className=\"fin-tl__head\">\n                <strong className=\"fin-tl__label\">{meta.label}</strong>\n                {entry?.by ? <span className=\"fin-tl__actor\">{entry.by}</span> : null}\n              </div>\n              <div className=\"fin-tl__meta\">\n                {entry?.at ? <span>{formatAppDateTime(entry.at)}</span> : null}\n                {entry?.at ? <span className=\"fin-tl__rel\">{relativeTime(entry.at)}</span> : null}\n              </div>\n            </div>\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// FinanceRecordsTable — enterprise list table for Billing / Payroll rows,\n// plus the cell primitives the host composes its columns from.\n// Server-side pagination is rendered with the shared CustomPagination.\n// ─────────────────────────────────────────────────────────────────────────\nimport { Table } from 'antd';\nimport { RightOutlined } from '@ant-design/icons';\nimport CustomPagination from '../CustomPagination.jsx';\nimport { FinanceEmptyState } from './FinanceComponents.jsx';\nimport { computeMarginBand, formatMoney, initialsOf } from './financeUtils';\nimport './finance-components.css';\n\n// ── Cell primitives ────────────────────────────────────────────────────────\n\nconst AVATAR_TONES = ['blue', 'indigo', 'purple', 'green'];\n\nfunction avatarTone(name) {\n  const text = String(name ?? '');\n  let hash = 0;\n  for (let i = 0; i < text.length; i++) hash = (hash * 31 + text.charCodeAt(i)) | 0;\n  return AVATAR_TONES[Math.abs(hash) % AVATAR_TONES.length];\n}\n\nexport function FinanceAvatar({ name, size = 'md' }) {\n  return (\n    <span className={`fin-avatar fin-avatar--${avatarTone(name)} fin-avatar--${size}`}>\n      {initialsOf(name)}\n    </span>\n  );\n}\n\n// `link` marks this cell as the row's \"click to open\" column — styles the\n// primary text the same blue the row chevron turns on hover, so a clickable\n// row reads as one before the user even hovers it. Only the first/name-like\n// column on a clickable table should set it.\nexport function FinanceEmployeeCell({ name, secondary, link = false }) {\n  return (\n    <div className=\"fin-cell-employee\">\n      <FinanceAvatar name={name} />\n      <span className=\"fin-cell-employee__text\">\n        <strong className={`fin-cell__primary${link ? ' fin-cell__primary--link' : ''}`}>{name || '—'}</strong>\n        {secondary ? <span className=\"fin-cell__secondary\">{secondary}</span> : null}\n      </span>\n    </div>\n  );\n}\n\nexport function FinanceTextCell({ primary, secondary, link = false }) {\n  return (\n    <div className=\"fin-cell-text\">\n      <span className={`fin-cell__primary${link ? ' fin-cell__primary--link' : ''}`}>{primary || '—'}</span>\n      {secondary ? <span className=\"fin-cell__secondary\">{secondary}</span> : null}\n    </div>\n  );\n}\n\nexport function FinanceMoneyCell({ value, sub, strong = false }) {\n  return (\n    <div className=\"fin-cell-money\">\n      <span className={`fin-cell-money__value${strong ? ' fin-cell-money__value--strong' : ''}`}>\n        {typeof value === 'number' ? formatMoney(value) : value ?? '—'}\n      </span>\n      {sub ? <span className=\"fin-cell__secondary\">{sub}</span> : null}\n    </div>\n  );\n}\n\nexport function FinanceBadge({ children, tone = 'neutral', title }) {\n  return (\n    <span className={`fin-badge fin-badge--${tone}`} title={title}>\n      {children}\n    </span>\n  );\n}\n\nexport function FinanceMarginBadge({ margin, marginPercent }) {\n  const band = computeMarginBand(marginPercent);\n  const tone = band === 'high' ? 'success' : band === 'low' ? 'danger' : 'neutral';\n  return (\n    <div className=\"fin-cell-margin\">\n      <FinanceBadge tone={tone}>{Number(marginPercent ?? 0).toFixed(1)}%</FinanceBadge>\n      {margin != null ? <span className=\"fin-cell__secondary\">{formatMoney(margin)}</span> : null}\n    </div>\n  );\n}\n\n// Trailing chevron cell the host appends as its last column to signal row\n// navigation: { key: 'chevron', width: 44, render: () => <FinanceRowChevron /> }\nexport function FinanceRowChevron() {\n  return <RightOutlined className=\"fin-table__chevron\" />;\n}\n\n// ── Skeleton ───────────────────────────────────────────────────────────────\n\nfunction SkeletonRows({ rows = 8 }) {\n  return (\n    <div className=\"fin-table-skeleton\">\n      {Array.from({ length: rows }, (_, i) => (\n        <div className=\"fin-table-skeleton__row\" key={i}>\n          <span className=\"fin-skeleton fin-skeleton--avatar\" />\n          <span className=\"fin-skeleton fin-skeleton--lg\" />\n          <span className=\"fin-skeleton fin-skeleton--md\" />\n          <span className=\"fin-skeleton fin-skeleton--md\" />\n          <span className=\"fin-skeleton fin-skeleton--sm\" />\n          <span className=\"fin-skeleton fin-skeleton--pill\" />\n        </div>\n      ))}\n    </div>\n  );\n}\n\n// ── Table ──────────────────────────────────────────────────────────────────\n\nexport default function FinanceRecordsTable({\n  columns,\n  rows = [],\n  rowKey = 'timesheetId',\n  loading = false,\n  onRowClick,\n  page,\n  limit,\n  total = 0,\n  onPageChange,\n  onLimitChange,\n  emptyState,\n  scrollX = 1100,\n}) {\n  if (loading && !rows.length) return <SkeletonRows />;\n\n  if (!loading && !rows.length) {\n    return (\n      <div className=\"fin-table-card\">\n        <FinanceEmptyState\n          title=\"No records found\"\n          description=\"Try widening the month filter or clearing quick filters — finance records live in their timesheet's month.\"\n          {...(emptyState ?? {})}\n        />\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"fin-table-card\">\n      <Table\n        className=\"fin-table\"\n        size=\"small\"\n        columns={columns}\n        dataSource={rows}\n        rowKey={rowKey}\n        loading={loading}\n        pagination={false}\n        sticky\n        scroll={{ x: scrollX }}\n        onRow={(row) => ({\n          onClick: (event) => {\n            // Full-row navigation, but never hijack clicks on interactive children.\n            if (event.target.closest('button, a, input, .fin-copy')) return;\n            onRowClick?.(row);\n          },\n        })}\n        rowClassName={() => (onRowClick ? 'fin-table__row fin-table__row--clickable' : 'fin-table__row')}\n      />\n      {total > 0 && page != null ? (\n        <div className=\"fin-table__pagination\">\n          <CustomPagination\n            current={page}\n            pageSize={limit}\n            total={total}\n            onChange={(next) => onPageChange?.(next)}\n            onPageSizeChange={(size) => onLimitChange?.(size)}\n          />\n        </div>\n      ) : null}\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useMenuPermission } from '../../hooks/useMenuPermission';\nimport { useVisibleTabs } from '../../hooks/useVisibleTabs';\nimport { getCrudPermissionKey } from '../../utils/actionPermission';\nimport { roleAllowsAction } from '../../utils/roleAllowsAction';\nimport { isRuleActionBlocked, ruleActionDisabledReason, actionDoneState } from '../../utils/actionRuleEngine';\nimport { Button, Card, Dropdown, Tag, Tooltip, message } from 'antd';\nimport {\n  AimOutlined,\n  BankOutlined,\n  CalendarOutlined,\n  CheckCircleOutlined,\n  ClockCircleOutlined,\n  CloseCircleOutlined,\n  DollarOutlined,\n  EditOutlined,\n  EnvironmentOutlined,\n  ExportOutlined,\n  FileDoneOutlined,\n  FileTextOutlined,\n  IdcardOutlined,\n  LaptopOutlined,\n  LinkOutlined,\n  MoreOutlined,\n  PlayCircleOutlined,\n  ProjectOutlined,\n  ShareAltOutlined,\n  SolutionOutlined,\n  SyncOutlined,\n  TeamOutlined,\n} from '@ant-design/icons';\nimport { getFormGroups } from '../../services/dropdownApi';\nimport { getModuleActions } from '../../services/detailedViewApi';\nimport { getModuleDocuments } from '../../services/documentApi';\nimport { clearAuthTokenOverride, fetchJsonWithAuth, setAuthTokenOverride } from '../../services/authApi';\nimport { AUTH_URL } from '../../services/apiConfig';\nimport { loadDetailDefaults } from '../../services/detailDefaults';\nimport { extractDocuments } from './renderConfig';\nimport { buildHeaderFromGroups, getModuleConfig } from './detailConfig/headerConfig';\nimport { resolveMetaItem } from './headerMeta';\nimport { auxRecordsSignature, makeAuxAccessor, normalizeAuxRecords } from './auxRecords';\nimport AppButton from '../AppButton';\nimport { FinanceStatusPill, FinanceWorkflowSteps } from '../finance/FinanceComponents';\nimport { FinanceAvatar } from '../finance/FinanceRecordsTable';\nimport { getWorkflowSteps } from '../finance/financeUtils';\nimport '../finance/finance-components.css';\nimport DocumentViewer from '../DocumentViewer';\nimport '../../styles/detail-header-card.css';\n\n// String icon keys (from headerConfig) → icon elements.\nconst ICONS = {\n  location: <EnvironmentOutlined />,\n  designation: <SolutionOutlined />,\n  experience: <ClockCircleOutlined />,\n  employment: <LaptopOutlined />,\n  rate: <DollarOutlined />,\n  source: <AimOutlined />,\n  resume: <FileTextOutlined />,\n  edit: <EditOutlined />,\n  approve: <CheckCircleOutlined />,\n  reject: <CloseCircleOutlined />,\n  // \"Open in / external\" icons for actions like Quick Submit's \"Open JD\".\n  // `export` matches the box-with-out-arrow look; the others are aliases so an\n  // admin-chosen icon key renders regardless of which of these they picked.\n  export: <ExportOutlined />,\n  openJd: <ExportOutlined />,\n  link: <LinkOutlined />,\n  shareAlt: <ShareAltOutlined />,\n  // Finance header chip icons (referenced by a finance module's header.chips)\n  idcard: <IdcardOutlined />,\n  bank: <BankOutlined />,\n  team: <TeamOutlined />,\n  project: <ProjectOutlined />,\n  cycle: <SyncOutlined />,\n  period: <CalendarOutlined />,\n  // Finance action icons — keyed by the antd component name stored on the\n  // seeded rowActionConfig entries, so config-driven finance buttons keep their\n  // icons (Process / Mark Paid / Generate Invoice / Generate Payslip).\n  PlayCircleOutlined: <PlayCircleOutlined />,\n  DollarOutlined: <DollarOutlined />,\n  FileTextOutlined: <FileTextOutlined />,\n  FileDoneOutlined: <FileDoneOutlined />,\n};\n\n// A single finance meta chip (icon + optional label + value + optional badge).\n// Rendered by the `variant: 'finance'` header below — no separate finance-header\n// component; the design is assembled here from the shared finance primitives.\nfunction MetaChip({ chip }) {\n  const icon = chip.icon ? <span className=\"fin-meta-chip__icon\">{chip.icon}</span> : null;\n  return (\n    <span className=\"fin-meta-chip\">\n      {chip.tooltip && icon ? <Tooltip title={chip.tooltip}>{icon}</Tooltip> : icon}\n      {chip.label ? <span className=\"fin-meta-chip__label\">{chip.label}</span> : null}\n      <span className=\"fin-meta-chip__value\">{chip.value ?? '—'}</span>\n      {chip.badge ? <span className=\"fin-badge fin-badge--brand\">{chip.badge}</span> : null}\n    </span>\n  );\n}\n\n// Build a flat record from the fetched form-groups so route templates such as\n// \"/app/candidates/edit/:_id\" can be filled with the record's real values.\nfunction actionRecordValue(value) {\n  if (Array.isArray(value)) return value.map(actionRecordValue);\n  if (value && typeof value === 'object' && 'id' in value && 'value' in value) {\n    return value.id ?? value.value;\n  }\n  return value;\n}\n\nfunction recordFromGroups(formGroups, id) {\n  const record = { _id: id, id };\n  // recordMeta (ridden along on the groups array by getFormGroups) carries the\n  // record's audit stamps and scalar linkage ids (jobId/applicantId/…) that are\n  // never form-group fields — merged FIRST so route templates like\n  // \"/submission/edit/:_id?jobId=:jobId\" resolve, while real form fields below\n  // still win on any key collision.\n  const meta = formGroups?.recordMeta;\n  if (meta && typeof meta === 'object') {\n    for (const [key, value] of Object.entries(meta)) {\n      if (!(key in record)) record[key] = value;\n    }\n  }\n  for (const group of formGroups ?? []) {\n    for (const field of group.fields ?? []) {\n      if (field?.field != null && field.value !== undefined) {\n        // Detail shaping turns lookups into { id, value }. Action rules and\n        // route templates must continue comparing/using the stored id, just as\n        // they did before the header opted into detail-view shaping.\n        record[field.field] = actionRecordValue(field.value);\n      }\n    }\n  }\n  return record;\n}\n\nfunction templatePart(value) {\n  if (value === null || value === undefined) return '';\n  if (Array.isArray(value)) return value.join(',');\n  if (typeof value === 'object') return String(value.id ?? value.value ?? '');\n  return String(value);\n}\n\n// Fill \":_id\", \":field\" and \"{field}\" placeholders in a route template.\nfunction fillRouteTemplate(template, record) {\n  return String(template)\n    .replace(/\\{([^}]+)\\}/g, (_, key) => encodeURIComponent(templatePart(record?.[key])))\n    .replace(/:([A-Za-z_][\\w]*)/g, (_, key) => encodeURIComponent(templatePart(record?.[key])));\n}\n\nfunction getNestedValue(record, path) {\n  return String(path || '').split('.').reduce((value, key) => value?.[key], record);\n}\n\nfunction comparable(value) {\n  return String(value ?? '').trim().toLowerCase();\n}\n\n// Rule evaluation (conditionMatches/isActionBlocked) lives in\n// ../../utils/actionRuleEngine, shared with ListView.jsx. Detail pages have no\n// VIEW scope (no myJobs/allJobs tabs), but a module's detail config may derive\n// a per-RECORD scope via `resolveScope(ctx)` (e.g. \"is this job assigned to\n// me → myJobs, else allJobs\") so the same admin scope rules that gate the List\n// also gate the Detail header. Without a resolver, scope stays `undefined` and\n// scope rules simply can't match — exactly the old behavior.\nfunction isBlocked(action, record, rules, scope) {\n  return isRuleActionBlocked(action.key, record, rules, scope);\n}\n\n// actionDoneState now lives in utils/actionRuleEngine (shared with ListView and\n// the row-action dropdown), so the \"done\" terminus renders identically on every\n// surface.\n\n// Admin-configured Module Action Rules can mark an action \"disabled\" instead\n// of \"blocked\" (see ruleActionDisabledReason): the button stays visible in its\n// normal spot with its normal label, just greyed out with a tooltip — used\n// e.g. for Approve/Reject while a submission sits in \"Resubmission\", so the\n// reviewer can see the actions exist and understand why they're not usable\n// yet, instead of them silently disappearing.\nfunction actionDisabledReason(action, record, rules, scope) {\n  return ruleActionDisabledReason(action.key, record, rules, scope);\n}\n\nfunction normalizeConfiguredAction(action) {\n  const key = String(action.key ?? '');\n  return {\n    ...action,\n    key,\n    label: action.label || key,\n    route: action.route || action.routeTemplate || (\n      action.actionType === 'modal' && (action.popupKey || key)\n        ? `/popup/${action.popupKey || key}`\n        : ''\n    ),\n  };\n}\n\n// Resolve document objects from the form-groups for the DocumentViewer.\n// `fieldName` is the preferred field key (e.g. 'resume'); falls back to any\n// resume/CV-looking field label or key.\nfunction resolveDocuments(formGroups, fieldName) {\n  const fields = (formGroups ?? []).flatMap((group) => group.fields ?? []);\n  const mayUseResumeFallback = !fieldName || /resume|cv/i.test(fieldName);\n  const target =\n    fields.find((field) => field.field === fieldName) ??\n    (mayUseResumeFallback\n      ? fields.find((field) => /resume|cv/i.test(`${field.field ?? ''} ${field.label ?? ''}`))\n      : undefined);\n  if (!target) return [];\n\n  const targetType = String(target.type ?? '').trim().toLowerCase();\n  const isFileField = targetType === 'file' || targetType === 'document' || targetType === 'upload';\n  if (!isFileField && typeof target.value === 'string' && target.value.trim()) {\n    const richText = targetType === 'text-editor' || /<[^>]+>/.test(target.value);\n    return [{\n      name: target.label || fieldName || 'Document',\n      type: richText ? 'html' : 'text',\n      content: target.value,\n    }];\n  }\n\n  const fileDocuments = extractDocuments(target.value).filter((document) => document.url);\n  if (fileDocuments.length) return fileDocuments;\n\n  // A document action may point at inline content instead of an uploaded file\n  // (for example a rich-text jobDescription). Preserve that content as an\n  // in-memory viewer document; DocumentViewer sanitizes HTML before rendering.\n  if (typeof target.value === 'string' && target.value.trim()) {\n    const richText = targetType === 'text-editor' || /<[^>]+>/.test(target.value);\n    return [{\n      name: target.label || fieldName || 'Document',\n      type: richText ? 'html' : 'text',\n      content: target.value,\n    }];\n  }\n\n  return [];\n}\n\n/*\n * Dynamic detail-view header. Self-contained: given `moduleName` + `id` it\n * fetches its own form-groups and builds the header object via\n * headerConfig.buildHeaderFromGroups — the page only passes moduleName + id.\n *\n *  moduleName, id  : forwarded back to onAction / onTabChange\n *  customConfigName : optional config key used only for rendering the card\n *  auxRecords      : optional { key: { module, id } } map of EXTRA records to\n *                    resolve alongside the primary one, exposed to the header\n *                    config as `aux(key)(field)` — see ./auxRecords.js for why\n *                    this is a host prop rather than config-declared\n *  onAction(key, { moduleName, id })  : button + more-menu clicks\n *                                       (custom parent-level handling)\n *  onTabChange(key, { moduleName, id }) : nav tab clicks\n *\n * Route-based actions (action.route defined in module config) are navigated\n * directly here so the click → navigate path is as short as possible.\n */\nexport default function DetailHeaderCard({\n  moduleName,\n  id,\n  customConfigName,\n  auxRecords,\n  authToken,\n  onAction,\n  onTabChange,\n  onHeaderData,\n  hideActions = false,\n  defaultTab,\n  refreshKey = 0,\n}) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const [formGroups, setFormGroups] = useState([]);\n  const [configuredActions, setConfiguredActions] = useState([]);\n  const [actionRules, setActionRules] = useState([]);\n  const [viewerOpen, setViewerOpen] = useState(false);\n  const [viewerDocs, setViewerDocs] = useState([]);\n  // Bumped after a same-page 'api' action (Process / Mark Paid / Generate\n  // Payslip / …) succeeds, so the fetch effect below re-runs and pulls the\n  // record's new status/chips/done-state without a full page reload. Route-\n  // based actions don't need this: they either navigate away or go through\n  // DynamicPopupRoute, which already refreshes via `refreshKey`.\n  const [actionRefreshTick, setActionRefreshTick] = useState(0);\n  const configName = customConfigName || moduleName;\n\n  useEffect(() => {\n    if (authToken) setAuthTokenOverride(authToken);\n    return () => {\n      if (authToken) clearAuthTokenOverride();\n    };\n  }, [authToken]);\n\n  useEffect(() => {\n    if (!moduleName) return undefined;\n\n    let cancelled = false;\n\n    async function fetchFormGroups() {\n      try {\n        // loadDetailDefaults() (cached) ensures resume/document URLs resolve\n        // against the admin-configured S3 base, same as DetailViewV1.\n        // Actions are fetched by configName (customConfigName, when given) so a\n        // context-specific card — e.g. the Quick Submit page's \"job\" module\n        // header rendered under customConfigName=\"submissionJob\" — can carry\n        // its own action set instead of always sharing the base module's\n        // (e.g. the real Job detail page's) actions. Falls back to moduleName\n        // when no customConfigName is passed, so every existing page keeps\n        // its current behavior unchanged.\n        const [data, actionConfig] = await Promise.all([\n          getFormGroups({ module: moduleName, id, view: 'detail' }),\n          getModuleActions(configName).catch(() => ({ actions: [], actionRules: [] })),\n          loadDetailDefaults(),\n        ]);\n        if (!cancelled) {\n          setFormGroups(Array.isArray(data) ? data : []);\n          setConfiguredActions(actionConfig.actions ?? []);\n          setActionRules(actionConfig.actionRules ?? []);\n        }\n      } catch (err) {\n        console.error(`Failed to fetch ${moduleName} header fields:`, err);\n        if (!cancelled) {\n          setFormGroups([]);\n          setConfiguredActions([]);\n          setActionRules([]);\n        }\n      }\n    }\n\n    fetchFormGroups();\n\n    return () => { cancelled = true; };\n  }, [moduleName, configName, id, refreshKey, actionRefreshTick]);\n\n  // ── Auxiliary records ──────────────────────────────────────────────────────\n  // Extra records the host declared via `auxRecords`, fetched with the SAME api\n  // as the primary record (getFormGroups + detail shaping) so an aux value is\n  // exactly what the detail view would show. Every request fails open to `[]`:\n  // a header must never blank out or throw because a secondary record 404'd,\n  // errored, or simply has no id yet. `auxSignature` (not the prop identity)\n  // drives the effect, since hosts pass an inline object literal.\n  // The fetched payload is stored WITH the signature it was fetched for, so a\n  // changed/cleared `auxRecords` invalidates it by comparison instead of by a\n  // synchronous setState in the effect body (which would cascade a render).\n  const [auxState, setAuxState] = useState({ signature: '', groups: {} });\n  const auxSignature = auxRecordsSignature(auxRecords);\n  useEffect(() => {\n    const requests = normalizeAuxRecords(auxRecords);\n    if (!requests.length) return undefined;\n    let cancelled = false;\n    Promise.all(requests.map(async (request) => {\n      const data = await getFormGroups({ module: request.module, id: request.id, view: 'detail' })\n        .catch(() => []);\n      return [request.key, Array.isArray(data) ? data : []];\n    }))\n      .then((entries) => {\n        if (!cancelled) setAuxState({ signature: auxSignature, groups: Object.fromEntries(entries) });\n      })\n      // fail open: no aux values, header renders exactly as it would without them\n      .catch(() => { if (!cancelled) setAuxState({ signature: auxSignature, groups: {} }); });\n    return () => { cancelled = true; };\n  }, [auxSignature, refreshKey]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const aux = useMemo(\n    () => makeAuxAccessor(auxState.signature === auxSignature ? auxState.groups : {}),\n    [auxState, auxSignature],\n  );\n\n  const header = useMemo(\n    () => buildHeaderFromGroups(configName, formGroups, { aux }),\n    [configName, formGroups, aux],\n  );\n\n  useEffect(() => {\n    if (header && onHeaderData) onHeaderData(header);\n  }, [header]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const {\n    eyebrow,\n    title = '-',\n    status,\n    titleIds = [],\n    meta = [],\n    ids = [],\n    tabs = [],\n    stats = [],\n    timestamp = null,\n  } = header ?? {};\n\n  const { canAdd, canEdit, canDelete } = useMenuPermission(moduleName);\n\n  const record = useMemo(() => recordFromGroups(formGroups, id), [formGroups, id]);\n\n  // Config-driven per-tab visibility (e.g. hide \"Candidates\" on a job that isn't\n  // assigned to the current user). A tab with no `visibleWhen` predicate always\n  // shows, so this changes nothing for existing modules/tabs.\n  const visibleTabs = useVisibleTabs(tabs, { id, moduleName, record });\n\n  // ── Per-record scope for admin action rules ─────────────────────────────\n  // The module's detail config may declare `resolveScope(ctx)` (sync or async)\n  // returning the scope string the admin's rules compare against (e.g.\n  // 'myJobs'/'allJobs' from \"is this record assigned to me\"). The SAME rules\n  // that gate the List rows then gate the Detail header — nothing hardcoded\n  // here. While a declared resolver is still pending, rule-gated actions stay\n  // hidden so a restricted action never flashes before disappearing; a module\n  // without a resolver keeps today's behavior (scope undefined, scope rules\n  // never match).\n  const scopeResolver = getModuleConfig(configName)?.resolveScope;\n  const [recordScope, setRecordScope] = useState(undefined);\n  useEffect(() => {\n    if (typeof scopeResolver !== 'function' || !id) return undefined;\n    let cancelled = false;\n    const currentUserId = Number(localStorage.getItem('userId')) || 0;\n    Promise.resolve()\n      .then(() => scopeResolver({ id, moduleName, record, currentUserId }))\n      .then((scope) => { if (!cancelled) setRecordScope(scope ?? null); })\n      .catch(() => { if (!cancelled) setRecordScope(null); }); // fail open: no scope\n    return () => { cancelled = true; };\n    // record is derived from formGroups; keying on formGroups avoids re-running\n    // on every render while still re-resolving once the record data arrives.\n  }, [scopeResolver, id, moduleName, formGroups]); // eslint-disable-line react-hooks/exhaustive-deps\n  const scopeReady = typeof scopeResolver !== 'function' || recordScope !== undefined;\n  const detailActions = useMemo(() => {\n    if (!scopeReady) return []; // resolver declared but still pending — no flash\n    return configuredActions\n      .filter((action) => action.showInDetail ?? action.showInList)\n      .map(normalizeConfiguredAction)\n      .filter((action) => !isBlocked(action, record, actionRules, recordScope ?? undefined));\n  }, [actionRules, configuredActions, record, recordScope, scopeReady]);\n\n  function isActionAllowed(action) {\n    const pk = getCrudPermissionKey(action);\n    if (pk === 'add'    && !canAdd)    return false;\n    if (pk === 'edit'   && !canEdit)   return false;\n    if (pk === 'delete' && !canDelete) return false;\n    if (!roleAllowsAction(action.permission, configName)) return false;\n    if (action.permissionKey) {\n      const rowPermission = getNestedValue(record, `actionPermission.${action.permissionKey}`);\n      if (rowPermission === false || rowPermission === 0 || rowPermission === '0') return false;\n    }\n    return true;\n  }\n\n  // Own the active tab locally so a click highlights immediately — waiting on\n  // defaultTab to round-trip back through the parent (URL state, re-fetches)\n  // let the highlight snap back to the first tab while content had already\n  // switched underneath it.\n  const [tabSelection, setTabSelection] = useState({\n    sourceDefaultTab: defaultTab,\n    selectedTab: defaultTab,\n  });\n  const localActiveTab = tabSelection.sourceDefaultTab === defaultTab\n    ? tabSelection.selectedTab\n    : defaultTab;\n  const activeTab = visibleTabs.some((tab) => tab.key === localActiveTab)\n    ? localActiveTab\n    : visibleTabs[0]?.key;\n\n  // `allowedTabs` spans TWO namespaces, and comparing it against only one of\n  // them is what hid Self Assign / Assign to Others on every job detail page.\n  //\n  //   • DETAIL tab keys   — 'details', 'candidates' (this page's own tabs)\n  //   • LIST tab keys     — 'myJobs', 'allJobs', 'fulfilled'\n  //\n  // One config field feeds both surfaces, and the admin editor's placeholder is\n  // literally \"e.g. allJobs\", so list keys are the expected input. The Detail\n  // header only ever compared against its OWN active tab, so [\"allJobs\",\n  // \"myJobs\"] could never match 'details' — and the two assign actions, the only\n  // ones that declare allowedTabs, were filtered out of every detail page while\n  // showing correctly in the List. Nothing was wrong with the config.\n  //\n  // The List's tab IS the record's scope, and the Detail page already resolves\n  // that per record (resolveScope → recordScope), so match against either.\n  const detailTabKeys = new Set(visibleTabs.map((tab) => comparable(tab.key)));\n  const isAllowedOnTab = (action) => {\n    const allowed = action.allowedTabs ?? [];\n    if (!allowed.length) return true;\n    // The detail tab actually open (\"only on the Candidates tab\").\n    if (allowed.some((tab) => comparable(tab) === comparable(activeTab))) return true;\n    // The record's own scope, which is what a List tab key means here.\n    if (recordScope && allowed.some((tab) => comparable(tab) === comparable(recordScope))) return true;\n    // At least one entry names a detail tab we know about, so the gate WAS\n    // evaluable and simply did not match — genuinely not allowed here.\n    if (allowed.some((tab) => detailTabKeys.has(comparable(tab)))) return false;\n    // Every entry is a list-scope key and this record has no resolved scope\n    // (no resolver, or the lookup failed). The gate cannot be evaluated, so it\n    // must not block — same fail-open rule the scope RULES above follow.\n    return !recordScope;\n  };\n  const visiblePrimaryActions = detailActions.filter(\n    (action) => action.detailPlacement === 'primary' && isActionAllowed(action) && isAllowedOnTab(action),\n  );\n  const visibleMoreActions = detailActions.filter(\n    (action) => action.detailPlacement !== 'primary' && isActionAllowed(action) && isAllowedOnTab(action),\n  );\n\n  if (!header) return null;\n\n  const fireAction = (key) => {\n    const action = [...visiblePrimaryActions, ...visibleMoreActions].find((a) => a.key === key);\n\n    // Open a document (e.g. resume) in the DocumentViewer modal.\n    if (action?.actionType === 'document' && action.documentField) {\n      const docs = resolveDocuments(formGroups, action.documentField);\n      if (docs.length) {\n        setViewerDocs(docs);\n        setViewerOpen(true);\n        return;\n      }\n      // Fallback: the file may live in the central documents registry, and\n      // possibly under a DIFFERENT module/record than the one on screen — e.g. a\n      // submission's resume is uploaded against the CANDIDATE (module\n      // \"candidates\", refId = the submission's applicantId). Admin config points\n      // at it: documentModule (source module) + documentIdField (the record key\n      // holding that module's id). Defaults to the current module + id.\n      const docModule = action.documentModule || moduleName;\n      const docId = action.documentIdField\n        ? getNestedValue(record, action.documentIdField)\n        : id;\n      getModuleDocuments(docModule, docId, action.documentField)\n        .then((res) => {\n          const central = (res?.data ?? [])\n            .map((d) => ({\n              name: d.fileName || d.name || d.uploadedFileName || action.documentField,\n              url: d.fileUrl || d.url || '',\n              type: 'file',\n            }))\n            .filter((d) => d.url);\n          if (central.length) {\n            setViewerDocs(central);\n            setViewerOpen(true);\n          } else {\n            message.warning(`No ${(action.label || 'document').toLowerCase()} available`);\n          }\n        })\n        .catch(() => message.warning(`No ${(action.label || 'document').toLowerCase()} available`));\n      return;\n    }\n\n    if (action?.actionType === 'copy') {\n      const value = getNestedValue(record, action.copyField || 'id');\n      navigator.clipboard.writeText(templatePart(value))\n        .then(() => message.success('Copied to clipboard'))\n        .catch(() => message.error('Could not copy to clipboard'));\n      return;\n    }\n\n    if (action?.actionType === 'api' && action.apiPath) {\n      const path = fillRouteTemplate(action.apiPath, record);\n      const method = String(action.apiMethod || 'POST').toUpperCase();\n      fetchJsonWithAuth(AUTH_URL, path.startsWith('/') ? path : `/${path}`, {\n        method,\n        body: ['GET', 'DELETE'].includes(method) ? undefined : JSON.stringify({ ids: [id], record }),\n      })\n        .then(() => {\n          message.success(`${action.label} completed`);\n          // The record just changed on the server (status, workflow step,\n          // computed fields) — refetch this header's own data so the status\n          // pill / chips / done-state buttons update immediately, and let the\n          // parent page know in case it holds its own copy of the record\n          // (e.g. FinanceDetailPage's KPI cards / overview tab).\n          setActionRefreshTick((tick) => tick + 1);\n          onAction?.(key, { moduleName, id, action, refreshed: true });\n        })\n        .catch((error) => message.error(error.message || `${action.label} failed`));\n      return;\n    }\n\n    if (action?.route) {\n      const resolvedRoute = typeof action.route === 'function'\n        ? action.route(id)\n        : fillRouteTemplate(action.route, recordFromGroups(formGroups, id));\n\n      // Admin-configured \"open in new tab\" (e.g. Quick Submit's \"Open JD\",\n      // so reviewing the job description never loses the in-progress form).\n      if (action.linkTarget === '_blank') {\n        window.open(resolvedRoute, '_blank', 'noopener');\n        return;\n      }\n\n      if (resolvedRoute.startsWith('/popup/')) {\n        navigate(resolvedRoute, {\n          state: {\n            background: location,\n            moduleName,\n            selectedIds: [id],\n            selectedRecords: [record],\n            popupContext: action.popupState ?? {},\n            popupAction: { key: action.key, apiMethod: action.apiMethod, apiPath: action.apiPath, defaultTemplateId: action.defaultTemplateId },\n            ...action.popupState,\n          },\n        });\n      } else {\n        navigate(resolvedRoute);\n      }\n      return;\n    }\n\n    // No route — bubble up to parent for custom handling.\n    onAction?.(key, { moduleName, id, action });\n  };\n\n  const selectTab = (key) => {\n    setTabSelection({ sourceDefaultTab: defaultTab, selectedTab: key });\n    onTabChange?.(key, { moduleName, id });\n  };\n\n  // Each item carries its own onClick so we don't rely on the global menu.onClick.\n  const moreMenuItems = visibleMoreActions.map((action) => {\n    const done = actionDoneState(action, record, recordScope ?? undefined);\n    const disabledReason = !done && actionDisabledReason(action, record, actionRules, recordScope ?? undefined);\n    return {\n      key: action.key,\n      label: done ? done.label : action.label,\n      danger: action.danger,\n      disabled: !!done || !!disabledReason,\n      title: disabledReason || undefined,\n      onClick: done || disabledReason ? undefined : () => fireAction(action.key),\n    };\n  });\n\n  // ── Finance variant ────────────────────────────────────────────────────────\n  // A module whose detailConfig declares header.variant === 'finance' renders\n  // the finance header design (avatar + icon chips + engagement badge +\n  // state-gated buttons + workflow stepper) INLINE here — assembled from the\n  // shared finance primitives (FinanceAvatar / FinanceStatusPill /\n  // FinanceWorkflowSteps), NOT a separate finance-header component. It stays\n  // fully config- and admin-driven: fields from Form Groups, buttons from Row\n  // Actions, gating from Module Action Rules. Opt-in per module, so every other\n  // module is completely unaffected.\n  const financeHeader = getModuleConfig(configName)?.header;\n  if (financeHeader?.variant === 'finance') {\n    const displayText = (value) => {\n      if (value == null) return '';\n      if (Array.isArray(value)) return value.map(displayText).filter(Boolean).join(', ');\n      // Lookups are shaped { id, value } — show the display name, not the id\n      // (unlike the action `record`, which flattens lookups to their id).\n      if (typeof value === 'object') return String(value.value ?? value.label ?? value.name ?? value.id ?? '');\n      return String(value);\n    };\n    // Field key → raw form-group value (dotted keys like \"billing.status\" and\n    // \"period.label\" are stored as literal keys), preserving { id, value }.\n    const fieldValues = {};\n    for (const group of formGroups ?? []) {\n      for (const field of group.fields ?? []) {\n        if (field?.field != null) fieldValues[field.field] = field.value;\n      }\n    }\n    const readField = (key) => displayText(fieldValues[key]);\n\n    const rawStatus = readField(financeHeader.statusField);\n    const financeChips = (financeHeader.chips ?? []).map((chip) => ({\n      key: chip.field,\n      icon: chip.icon ? ICONS[chip.icon] : undefined,\n      label: chip.label,\n      value: readField(chip.field) || '—',\n      badge: chip.badgeField ? (readField(chip.badgeField) || undefined) : undefined,\n      tooltip: chip.tooltip,\n    }));\n    const financeActions = hideActions ? [] : visiblePrimaryActions.map((action) => {\n      const done = actionDoneState(action, record, recordScope ?? undefined);\n      const disabledReason = !done && actionDisabledReason(action, record, actionRules, recordScope ?? undefined);\n      return {\n        key: action.key,\n        label: done ? done.label : action.label,\n        icon: action.icon ? ICONS[action.icon] : undefined,\n        enabled: !done && !disabledReason,\n        variant: action.tone,\n        disabledReason: disabledReason || undefined,\n        onClick: done || disabledReason ? undefined : () => fireAction(action.key),\n      };\n    });\n    const steps = rawStatus ? getWorkflowSteps(moduleName, rawStatus) : [];\n    return (\n      <div className=\"fin-detail-header\">\n        <div className=\"fin-dh__top\">\n          <div className=\"fin-dh__identity\">\n            <FinanceAvatar name={title} size=\"lg\" />\n            <div className=\"fin-dh__who\">\n              <div className=\"fin-dh__name-row\">\n                <h2 className=\"fin-dh__name\">{title || 'Details'}</h2>\n                {rawStatus ? <FinanceStatusPill status={rawStatus} /> : null}\n              </div>\n              {eyebrow ? <span className=\"fin-dh__designation\">{eyebrow}</span> : null}\n            </div>\n          </div>\n          {financeActions.length ? (\n            <div className=\"fin-dh__actions\">\n              {financeActions.map((action) => {\n                const button = (\n                  <AppButton\n                    key={action.key ?? action.label}\n                    variant={action.enabled ? action.variant ?? 'default' : 'default'}\n                    icon={action.icon}\n                    disabled={!action.enabled}\n                    onClick={action.onClick}\n                  >\n                    {action.label}\n                  </AppButton>\n                );\n                return action.enabled || !action.disabledReason ? button : (\n                  <Tooltip title={action.disabledReason} key={action.key ?? action.label}>\n                    {/* span wrapper: antd tooltips don't fire on disabled buttons */}\n                    <span className=\"fin-dh__action-wrap\">{button}</span>\n                  </Tooltip>\n                );\n              })}\n            </div>\n          ) : null}\n        </div>\n\n        {/* Full-width chip row starting at the header's left edge. */}\n        {financeChips.length ? (\n          <div className=\"fin-dh__chips\">\n            {financeChips.map((chip) => <MetaChip chip={chip} key={chip.key ?? chip.label} />)}\n          </div>\n        ) : null}\n\n        {steps.length ? <FinanceWorkflowSteps steps={steps} /> : null}\n      </div>\n    );\n  }\n\n  return (\n    <>\n    <Card className=\"znx-dh-card\">\n      <div className=\"znx-dh-top\">\n        <div className=\"znx-dh-left\">\n          {eyebrow && <div className=\"znx-dh-eyebrow\">{eyebrow}</div>}\n\n          <div className=\"znx-dh-titlerow\">\n            <span className=\"znx-dh-title\">{title}</span>\n              {titleIds.map((item) => (\n              <span className=\"znx-dh-titleid\" key={item.label}>\n                <span className=\"znx-dh-id-label\">{item.label}:</span> {item.value}\n              </span>\n            ))}\n            {status && (\n              // <Tag color={status.color} className=\"znx-dh-status\">\n              <Tag\n                color={status.color}\n                className=\"znx-dh-status\"\n                style={{\n                  backgroundColor: status.backgroundColor ?? status.color,\n                  borderColor: status.backgroundColor ?? status.color,\n                  color: status.textColor,\n                }}\n              >\n                {status.label}\n              </Tag>\n            )}\n\n          \n          </div>\n\n          {ids.length > 0 && (\n            <div className=\"znx-dh-ids\">\n              {ids.map((item) => (\n                <span className=\"znx-dh-id\" key={item.label}>\n                  <span className=\"znx-dh-id-label\">{item.label}:</span> {item.value}\n                </span>\n              ))}\n            </div>\n          )}\n\n          {meta.length > 0 && (\n            <div className=\"znx-dh-meta\">\n              {/* One meta entry, resolved against THIS record (see\n                  ./headerMeta.js): a `labelWhen` rule can re-label it — the\n                  same rule shape and matcher the forms use, so a C2C\n                  submission's rate reads \"Employer rate\" here exactly as it\n                  does on the form — and `variant:'pill'` renders it through the\n                  status pill's styling instead of as body text. */}\n              {meta.map((item, index) => {\n                const resolved = resolveMetaItem(item, (key) => getNestedValue(record, key) ?? record?.[key]);\n                return (\n                  <span className=\"znx-dh-meta-item\" key={index}>\n                    {resolved.icon && ICONS[resolved.icon] && (\n                      <span className=\"znx-dh-meta-icon\">{ICONS[resolved.icon]}</span>\n                    )}\n                    {resolved.variant === 'pill' ? (\n                      <>\n                        {resolved.label && <span className=\"znx-dh-meta-label\">{resolved.label}:</span>}\n                        <Tag\n                          className=\"znx-dh-meta-pill\"\n                          color={resolved.tagColor}\n                          style={resolved.tagStyle}\n                        >\n                          {resolved.value || resolved.text}\n                        </Tag>\n                      </>\n                    ) : (\n                      <span>{resolved.text}</span>\n                    )}\n                  </span>\n                );\n              })}\n            </div>\n          )}\n        </div>\n\n        {!hideActions && (\n          <div className=\"znx-dh-actions-col\">\n            <div className=\"znx-dh-actions\">\n              {visiblePrimaryActions.map((action) => {\n                const done = actionDoneState(action, record, recordScope ?? undefined);\n                const disabledReason = !done && actionDisabledReason(action, record, actionRules, recordScope ?? undefined);\n                const button = (\n                  <Button\n                    key={action.key}\n                    type=\"text\"\n                    disabled={!!done || !!disabledReason}\n                    className={`znx-dh-btn znx-dh-btn--${done ? done.tone : (action.tone ?? 'primary')}${done ? ' znx-dh-btn--done' : ''}`}\n                    icon={done ? <CheckCircleOutlined /> : (action.icon ? ICONS[action.icon] : undefined)}\n                    onClick={done || disabledReason ? undefined : () => fireAction(action.key)}\n                  >\n                    {done ? done.label : action.label}\n                  </Button>\n                );\n                return disabledReason\n                  // Disabled elements don't reliably fire the mouse events\n                  // Tooltip listens for, so give it a hoverable wrapper.\n                  ? <Tooltip key={action.key} title={disabledReason}><span>{button}</span></Tooltip>\n                  : button;\n              })}\n\n              {visibleMoreActions.length > 0 && (\n                <Dropdown\n                  trigger={['click']}\n                  placement=\"bottomRight\"\n                  menu={{ items: moreMenuItems }}\n                >\n                  <Button\n                    type=\"text\"\n                    className=\"znx-dh-more\"\n                    icon={<MoreOutlined />}\n                  />\n                </Dropdown>\n              )}\n            </div>\n\n            {stats.length > 0 && (\n              <div className=\"znx-dh-stats\">\n                {stats.map((stat) => (\n                  <div key={stat.label} className=\"znx-dh-stat\">\n                    <span className=\"znx-dh-stat-value\">{stat.value}</span>\n                    <span className=\"znx-dh-stat-label\">{stat.label}</span>\n                  </div>\n                ))}\n              </div>\n            )}\n\n            {timestamp?.value && (\n              <div className=\"znx-dh-created\">\n                Created on {timestamp.value}\n              </div>\n            )}\n          </div>\n        )}\n      </div>\n\n      {visibleTabs.length > 0 && (\n        <div className=\"znx-dh-tabs\">\n          {visibleTabs.map((tab) => (\n            <button\n              key={tab.key}\n              type=\"button\"\n              className={`znx-dh-tab${activeTab === tab.key ? ' is-active' : ''}`}\n              onClick={() => selectTab(tab.key)}\n            >\n              {tab.label}\n            </button>\n          ))}\n        </div>\n      )}\n    </Card>\n\n    <DocumentViewer\n      documents={viewerDocs}\n      open={viewerOpen}\n      onClose={() => setViewerOpen(false)}\n    />\n    </>\n  );\n}\n","/*\n * Tab content registry.\n *\n * Maps moduleName → tabKey → Component rendered below the header.\n * The 'details' tab always uses the default DetailViewV1 layout — never register it here.\n *\n * To add content for a new module/tab:\n *   1. Import the component.\n *   2. Add an entry: REGISTRY[moduleName][tabKey] = ({ id, ...rest }) => <YourTab ... />.\n *\n * Props passed to every registered component: { id, moduleName, onDescriptionSaved }\n */\n\nconst REGISTRY = {\n  // Add future modules here:\n  // candidate: { jobs: ({ id }) => <CandidateJobsTab candidateId={id} /> },\n};\n\n// Returns the effective registry: built-in entries merged with whatever the host\n// injected via configureCoreTheme({ tabContentRegistry: { job: { candidates: fn } } }).\n// Host entries WIN per tab key, so a consumer can replace any built-in tab renderer.\n// Called at render time so configs set in main.jsx are always picked up.\nfunction getEffectiveRegistry() {\n  const host =\n    (typeof window !== 'undefined' && window.__CORE_THEME_CONFIG__?.tabContentRegistry) ?? {};\n  if (!Object.keys(host).length) return REGISTRY;\n  const merged = { ...REGISTRY };\n  Object.entries(host).forEach(([mod, tabs]) => {\n    merged[mod] = { ...(merged[mod] ?? {}), ...tabs };\n  });\n  return merged;\n}\n\nexport function getTabContent(moduleName, tabKey) {\n  if (!tabKey || tabKey === 'details') return null;\n  return getEffectiveRegistry()[moduleName]?.[tabKey] ?? null;\n}\n","import { useLocation } from 'react-router-dom';\n\n/*\n * A detail page sits behind a popup route (see DynamicPopupRoute) without\n * ever unmounting, so its data-fetching children (DetailHeaderCard,\n * DetailViewV1, ActivityNotesCard, ...) only refetch when their own deps\n * (moduleName/id) change — never on their own after a popup mutates the\n * record. On a successful popup submit, DynamicPopupRoute re-enters this same\n * location with a fresh `refreshTimestamp` in its state; this hook reads that\n * value so it can be passed as `refreshKey` to those children, putting it in\n * their fetch effect's dependency array to force one refetch. The older\n * `__refreshedAt` key remains a fallback for existing callers.\n */\nexport function useRecordRefresh() {\n  const location = useLocation();\n  return location.state?.refreshTimestamp ?? location.state?.__refreshedAt ?? 0;\n}\n","import PropTypes from \"prop-types\";\nimport { useMemo, useState } from \"react\";\nimport { Button, Col, Row, Typography } from \"antd\";\nimport {\n  useLocation,\n  useNavigate,\n  useParams,\n  useSearchParams,\n} from \"react-router-dom\";\nimport ActivityNotesCard from \"./detail/ActivityNotesCard\";\nimport DetailHeaderCard from \"./detail/DetailHeaderCard\";\nimport DetailViewV1 from \"./DetailViewV1\";\nimport { getTabContent } from \"./detail/tabContentRegistry\";\nimport { getModuleConfig } from \"./detail/detailConfig/headerConfig\";\nimport { useVisibleTabs } from \"../hooks/useVisibleTabs\";\nimport { useRecordRefresh } from \"../hooks/useRecordRefresh\";\n\n// Defined at module level so the linter doesn't flag it as \"component created\n// during render\". Receives an already-defined component via the `component` prop.\nfunction DynamicTabContent({ component: Tab, id, moduleName, onDescriptionSaved }) {\n  if (!Tab) return null;\n  return <Tab id={id} moduleName={moduleName} onDescriptionSaved={onDescriptionSaved} />;\n}\n\nconst { Text } = Typography;\n\n/*\n * DetailViewPage — full detail screen layout.\n *\n * Pass only `moduleName` (and optionally `id`). When `id` is omitted the\n * component resolves it from the URL: params.id → ?id= → location.state.record.\n *\n * Tab switching and tab content are driven by the header config (jobConfig,\n * candidateConfig, …) + tabContentRegistry. The 'details' tab renders the\n * default DetailViewV1 + ActivityNotesCard layout. Every other tab is looked\n * up in tabContentRegistry and rendered in place of that layout.\n *\n * Route-based actions (popup overlays, page navigations) are handled directly\n * inside DetailHeaderCard using its own useNavigate / useLocation. This keeps\n * the click → navigate path as short as possible.\n *\n * onHeaderAction is only called for actions that have NO route configured\n * in the module config (custom parent-level handling).\n */\nexport default function DetailViewPage({\n  moduleName,\n  id: idProp,\n  backPath = \"\",\n  showFooter = true,\n  users = [],\n  showActivity = true,\n  showNotes = true,\n  onHeaderAction,\n  onHeaderTabChange,\n  onHeaderData,\n}) {\n  const navigate = useNavigate();\n  const params = useParams();\n  const [searchParams, setSearchParams] = useSearchParams();\n  const location = useLocation();\n\n  const id =\n    idProp ||\n    params.id ||\n    searchParams.get(\"jobId\") ||\n    searchParams.get(\"id\") ||\n    location.state?.record?._id ||\n    location.state?.record?.id;\n\n  // The active tab is driven by the `?tab=` URL param so a tab can be deep-linked\n  // directly (e.g. /jobs/:id?tab=candidates&subTab=pipeline). Defaults to details.\n  const activeTab = searchParams.get(\"tab\") || \"details\";\n  const [descRefreshKey, setDescRefreshKey] = useState(0);\n  const popupRefreshKey = useRecordRefresh();\n\n  const handleTabChange = (key, meta) => {\n    const next = new URLSearchParams(searchParams);\n    next.set(\"tab\", key);\n    setSearchParams(next, { replace: true });\n    onHeaderTabChange?.(key, meta);\n  };\n\n  const handleDescriptionSaved = () => setDescRefreshKey((k) => k + 1);\n\n  // Only fires for actions without a route (routed actions are handled inside DetailHeaderCard).\n  const handleHeaderAction = (key, payload) => {\n    onHeaderAction?.(key, payload);\n  };\n\n  // Same config-driven tab gate the header uses, so a deep-linked ?tab= that\n  // points at a tab hidden for this record (e.g. Candidates on a job that isn't\n  // assigned to the current user) falls back to the default details layout\n  // instead of rendering the restricted content.\n  const moduleTabs = useMemo(() => getModuleConfig(moduleName)?.tabs ?? [], [moduleName]);\n  const visibleTabs = useVisibleTabs(moduleTabs, { id, moduleName });\n  const isTabAllowed = activeTab === \"details\"\n    || !moduleTabs.some((tab) => tab.key === activeTab && typeof tab.visibleWhen === \"function\")\n    || visibleTabs.some((tab) => tab.key === activeTab);\n\n  const tabComponent = useMemo(\n    () => (isTabAllowed ? getTabContent(moduleName, activeTab) : null),\n    [moduleName, activeTab, isTabAllowed],\n  );\n\n  return (\n    <div className=\"v1-page v1-detail-page\">\n      <div className=\"v1-page-inner\">\n        <DetailHeaderCard\n          moduleName={moduleName}\n          id={id}\n          defaultTab={activeTab}\n          onAction={handleHeaderAction}\n          onTabChange={handleTabChange}\n          onHeaderData={onHeaderData}\n          refreshKey={popupRefreshKey}\n        />\n\n        {tabComponent ? (\n          <DynamicTabContent\n            component={tabComponent}\n            id={id}\n            moduleName={moduleName}\n            onDescriptionSaved={handleDescriptionSaved}\n          />\n        ) : (\n          <Row gutter={[16, 16]} align=\"stretch\">\n            <Col xs={24} lg={16}>\n              <DetailViewV1\n                moduleName={moduleName}\n                id={id}\n                refreshKey={descRefreshKey + popupRefreshKey}\n                onDescriptionSaved={handleDescriptionSaved}\n              />\n            </Col>\n            <Col xs={24} lg={8}>\n              <ActivityNotesCard\n                moduleName={moduleName}\n                id={id}\n                users={users}\n                showActivity={showActivity}\n                showNotes={showNotes}\n                refreshKey={popupRefreshKey}\n              />\n            </Col>\n          </Row>\n        )}\n      </div>\n\n      {backPath && showFooter && (\n        <div className=\"v1-footer\">\n          <Text type=\"secondary\">\n            {id ? `Record ID: ${id}` : \"Detail view\"}\n          </Text>\n          <Button onClick={() => navigate(backPath)}>Back</Button>\n        </div>\n      )}\n    </div>\n  );\n}\n\nDetailViewPage.propTypes = {\n  moduleName: PropTypes.string,\n  id: PropTypes.string,\n  backPath: PropTypes.string,\n  showFooter: PropTypes.bool,\n  users: PropTypes.array,\n  showActivity: PropTypes.bool,\n  showNotes: PropTypes.bool,\n  onHeaderAction: PropTypes.func,\n  onHeaderTabChange: PropTypes.func,\n  onHeaderData: PropTypes.func,\n};\n","const FALLBACK_OPTIONS_BY_FIELD = {\n  jobRemoteStatus: ['On-Site', 'Remote', 'Hybrid'],\n  jobRecruitmentStatus: ['unread', 'partially fulfilled', 'fulfilled'],\n  'experience.experienceRequiredUnit': ['Years', 'Months'],\n  'contractDuration.unit': ['Days', 'Weeks', 'Months', 'Years'],\n  noticePeriodUnit: ['Days', 'Weeks', 'Months'],\n  'jobPayDetails.clientBudgetCurrency': ['$', 'USD', 'INR'],\n  'jobPayDetails.clientBudgetUnit': ['Hour', 'Daily', 'Monthly', 'Yearly'],\n  workAuthorisation: ['US Citizen', 'Green Card', 'H1B', 'OPT', 'CPT', 'L2 EAD', 'H4 EAD', 'Other'],\n  // NOTE: `relocation` is a boolean CHECKBOX, not a Yes/No select — it must not\n  // get fallback options, or the edit form renders a Yes/No control while the\n  // add form shows a single checkbox. (The call site also guards checkbox\n  // fields, so this is belt-and-braces.)\n  source: ['LinkedIn', 'Referral', 'Dice', 'Indeed', 'Monster', 'Vendor', 'Other'],\n};\n\nexport function getEditFormFallbackOptions(field = {}) {\n  return FALLBACK_OPTIONS_BY_FIELD[field.field] ?? [];\n}\n","// verifyLockState — the pure decision behind a field's \"locked verified\" state.\n//\n// A field with `verifyAction` normally renders a Verify button that flips to a\n// soft success label once its `verifyResultField` sibling is true, and back to\n// a button the moment the verified value is edited. That is right for a check\n// that only ever proved a mailbox exists.\n//\n// It is NOT right once something irreversible has happened off the back of that\n// check — e.g. a login was provisioned for the address, stamped onto the SAME\n// row by a workflow. From then on the row is a record of a real account, not a\n// re-runnable check, so the control must stop offering \"Verify\" at all.\n//\n// `verifyLockedWhenFields` names the sibling row keys that carry that evidence\n// (comma / space / newline separated, resolved row-scoped exactly like\n// `verifyResultField`). Nothing here knows a module, group or field name — the\n// employers/recruiters/isAccountCreate case is pure admin config.\n//\n// This lives in its own module purely so it can be unit-tested: any vitest file\n// that imports EditFormV1 drags in react-pdf, which dies on jsdom's missing\n// DOMMatrix. The logic is the part worth testing, so the logic is the part that\n// is importable on its own.\n\n// isTruthyFlag decides whether ONE stored row value counts as \"set\".\n//\n// It has to be looser than `=== true`: a lock field is usually a boolean flag\n// (isAccountCreate) but an admin can just as reasonably point at the id or\n// timestamp the same workflow stamped (accountUserId: 144,\n// accountCreatedAt: \"2026-08-05T…\"), and those are the strongest evidence of\n// all. It also has to be tighter than JS truthiness, because a hidden <Input/>\n// carrier stringifies whatever it holds — so the STRING \"false\" must stay\n// false, and so must \"0\" and an empty string.\nconst FALSY_TEXT = new Set(['', 'false', '0', 'no', 'null', 'undefined']);\n\nexport function isTruthyFlag(value) {\n  if (value === undefined || value === null || value === false) return false;\n  if (typeof value === 'number') return value !== 0 && !Number.isNaN(value);\n  if (typeof value === 'string') return !FALSY_TEXT.has(value.trim().toLowerCase());\n  if (Array.isArray(value)) return value.length > 0;\n  return true;\n}\n\n// parseLockFieldKeys turns the admin's free-text list into field keys. Commas,\n// spaces and newlines all separate, so \"isAccountCreate, accountUserId\" and\n// \"isAccountCreate accountUserId\" mean the same thing. Returns [] for anything\n// unset — which is what keeps every field configured before this existed on\n// exactly its old behaviour.\nexport function parseLockFieldKeys(config) {\n  if (Array.isArray(config)) {\n    return config.map((k) => String(k ?? '').trim()).filter(Boolean);\n  }\n  return String(config ?? '')\n    .split(/[\\s,]+/)\n    .map((k) => k.trim())\n    .filter(Boolean);\n}\n\n// isVerifyLocked — true when the control must render as a non-interactive\n// \"Verified\" state instead of a button.\n//\n// `lockKeys` are ADDITIONAL to the existing result field: every lock key must be\n// truthy AND, when the field configures a `verifyResultField`, that result must\n// be true too. So \"account created\" alone never locks a row whose mailbox check\n// failed — which is the whole point of showing the state at all.\n//\n// readSibling(key) resolves one sibling key in the same scope the caller uses\n// for verifyResultField (the addRow row when nested, the form root otherwise).\nexport function isVerifyLocked({ lockKeys = [], resultValue, hasResultField = true, readSibling }) {\n  if (!lockKeys.length || typeof readSibling !== 'function') return false;\n  if (hasResultField && !isTruthyFlag(resultValue)) return false;\n  return lockKeys.every((key) => isTruthyFlag(readSibling(key)));\n}\n\n// readAtPath — plain deep read used to resolve a sibling path against a whole\n// form-values snapshot (Form.useWatch's selector form). Kept here so the lock\n// decision has no antd dependency and stays testable.\nexport function readAtPath(values, path = []) {\n  let cursor = values;\n  for (const segment of path) {\n    if (cursor === undefined || cursor === null) return undefined;\n    cursor = cursor[segment];\n  }\n  return cursor;\n}\n","/**\n * EditFormV1 — Generic reusable edit form component\n *\n * Works for any module (jobs, candidates, submissions, etc.)\n * All module-specific behaviour is passed in via props — zero hardcoding inside.\n *\n * Props:\n *   moduleName      string    — e.g. \"job\", \"candidate\"\n *   groupName       string    — optional; render/fetch/submit only the single\n *                              named group from moduleName's form config (e.g.\n *                              a module's own \"actuals\"/update-payment group)\n *                              instead of every group the module has\n *   recordId        string    — MongoDB _id of the record\n *   breadcrumbItems array     — passed to AppBreadcrumb\n *   submitText      string    — Save button label (default \"Save Changes\")\n *   cancelPath      string    — navigate here on cancel/success\n *   onSuccess       function  — called after successful save (overrides cancelPath)\n *   fieldNameMap    object    — rename form fields before sending to API\n *                              e.g. { mspReqId: 'mspreqId' }\n *   onFileUpload    function  — (fieldName, file, recordId) => Promise\n *                              handle multipart uploads per module\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n    Alert,\n    Button,\n    Card,\n    Checkbox,\n    Col,\n    DatePicker,\n    Form,\n    Input,\n    Radio,\n    Row,\n    Select,\n    Space,\n    Spin,\n    Switch,\n    TimePicker,\n    Tooltip,\n    Typography,\n    Upload,\n    message,\n} from 'antd';\nimport {\n    CalendarOutlined,\n    CloudUploadOutlined,\n    DeleteOutlined,\n    DownOutlined,\n    EnvironmentOutlined,\n    EyeOutlined,\n    FileExcelOutlined,\n    FileImageOutlined,\n    FileOutlined,\n    FilePdfOutlined,\n    FileTextOutlined,\n    FileWordOutlined,\n    InfoCircleOutlined,\n    LockOutlined,\n    MailOutlined,\n    PhoneOutlined,\n    PlusOutlined,\n    SolutionOutlined,\n    TagsOutlined,\n    UpOutlined,\n    UserOutlined,\n} from '@ant-design/icons';\nimport '../styles/AddFormV1.css';\nimport AppBreadcrumb from './Breadcrumb';\nimport TipTapEditor from './TipTapEditor';\nimport DocumentViewer from './DocumentViewer';\nimport { applyInputValidator, getKeyPattern } from './form/inputValidator';\nimport { PARENT_FILTER_UNSEEN, shouldClearDependentValue } from './form/dependentLookupReset';\nimport { configuredEmailRule } from './form/emailValidator';\nimport { securityValidationRule } from './form/inputSecurity';\nimport {\n    buildUniqueValidationRule,\n    attachUniqueSyncGuards,\n    collectUniqueRules,\n    createUniqueChecker,\n    extractDuplicateFieldErrors,\n} from './form/uniqueFieldValidation';\nimport { checkFieldUnique } from '../services/uniqueValidationApi';\nimport { uploadAcceptCategory } from './form/uploadAccept';\nimport { useQuickField } from './form/QuickCreateEditField';\nimport { maxFromFieldRule, maxFromFieldDependency, resolveScopedFieldPath } from './form/crossFieldRules';\nimport { checkMaxWithFallback, parseCompareFields, readCompareValue, resolveCompareFieldName } from './form/maxCeiling';\nimport { prefillWhenWatchFields, prefillWhenWatchPaths, resolvePrefillWhen } from './form/prefillWhenRules';\nimport { narrowOptionsByConstraint, stripExclusivePrefillOptions } from './form/optionConstraints';\nimport { filterLookupOptionRows, lookupExtraFieldKeys } from './form/optionRowFilters';\nimport { fieldTooltipText } from './form/fieldTooltip';\nimport { roleAllowsAction } from '../utils/roleAllowsAction';\nimport { groupAllowedByRole, fieldAllowedByRole, fieldEditableByRole } from '../utils/roleFormPermissionGate';\nimport { resolveAfterSubmit, safeNavTarget } from '../utils/afterSubmitNav';\nimport { goBackOrTo } from '../utils/backNav';\nimport {\n    resolveRegionRules,\n    inProgressAllowed,\n    inProgressBlocks,\n    inProgressError,\n    buildInProgressValidator,\n    promptRowMove,\n} from './form/educationRules';\nimport { openFormNotice, openFormDecision } from './form/formDecisionDialog';\nimport ValidationOverrideCheckbox from './form/ValidationOverrideCheckbox';\nimport {\n    overrideConfig,\n    overrideFlagPath,\n    overrideRuleMapper,\n} from './form/validationOverride';\nimport { getDefaults } from '../services/detailDefaults';\nimport { applyGroupClear } from './form/clearGroupOnChange';\nimport { fetchLookupLabels, mergeResolvedOptions, missingOptionValues } from './form/resolveStoredOptions';\nimport {\n    buildPairValidator,\n    buildRowHierarchyValidator,\n    buildDisabledDate,\n    defaultPickerValue,\n    getComparableDateTime,\n    getComparableTimeOfDay,\n} from './form/dateRules';\nimport { submitSuccessMessage, submitErrorMessage } from '../utils/submitMessages';\nimport { scrollToFirstFormError } from '../utils/scrollToFirstFormError';\nimport { conditionFieldPath, configuredFieldLabel, conditionMatches as labelConditionMatches, colWhenRules, resolveColSpan } from './form/conditionalFieldLabel';\nimport { useNavigate, useLocation } from 'react-router-dom';\nimport { clearAuthTokenOverride, fetchJsonWithAuth, setAuthTokenOverride } from '../services/authApi';\nimport { AUTH_URL } from '../services/apiConfig';\nimport { buildFileUrl } from './detail/renderConfig';\nimport { getDropdownValues } from '../services/moduleDataApi';\nimport { getFormGroups } from '../services/addFormApi';\nimport { updateRecord } from '../services/detailedViewApi';\nimport { getModuleDocuments, uploadModuleDocuments } from '../services/documentApi';\nimport { loadDetailDefaults, formatPhone, phoneDigits, parsePhoneFormat } from '../services/detailDefaults';\nimport { getRoleFormPermissions, getModuleDefaultFields } from '../services/adminApi';\nimport {\n    buildPayload as buildConfigPayload,\n    buildRepeatFieldInitial,\n    singleFieldOf,\n    collectFileParts,\n    isUploadField,\n    effectiveDataType,\n    getDeep,\n    toSelectControlValue,\n    usesLabeledSelectValue,\n    rowDefaultsFor,\n} from './form/payloadTransformer';\nimport { computeLinkedSets, findLinkedSet, padLinkedInitialValues } from './form/linkedAddRowGroups';\nimport { getEditFormFallbackOptions } from './form/editFormOptionFallbacks';\nimport useAiActions, { groupActionsByPosition } from './form/useAiActions';\nimport AiActionButtonGroup from './form/AiActionButtons';\nimport { namePathFromString, buildAddRowInitial, applyScalarFieldValues, writeFormValue } from './form/applyGroupValues';\nimport {\n    contextPrefillModules,\n    contextRecordId,\n    extractContextGroups,\n    flattenContextRecord,\n    isNonPersistentCarrier,\n    pickContextValue,\n} from './form/contextPrefill';\nimport { verifyEmail } from '../services/adminApi';\nimport { parseLockFieldKeys, isVerifyLocked, readAtPath } from './form/verifyLockState';\n\nconst { Text } = Typography;\nconst { TextArea } = Input;\n\nfunction siblingFieldPath(absoluteName, key) {\n    return Array.isArray(absoluteName) && absoluteName.length > 1\n        ? [...absoluteName.slice(0, -1), key]\n        : [key];\n}\n\n// VerifyFieldButton — mirrors AddFormV1.jsx's identical component.\nfunction VerifyFieldButton({ form, field, absoluteName }) {\n    const [checking, setChecking] = useState(false);\n    const [verdict, setVerdict] = useState(null);\n    const verifiedValueRef = useRef(null);\n    const resultValue = Form.useWatch(\n        field.verifyResultField ? siblingFieldPath(absoluteName, field.verifyResultField) : ['__noop_verify__'],\n        { form, preserve: true },\n    );\n    const currentValue = Form.useWatch(absoluteName, form);\n    // Locked \"verified\" state (EDIT ONLY — see the note on AddFormV1's copy).\n    // `verifyLockedWhenFields` names sibling row keys whose truthiness means\n    // something irreversible already happened for this value (a login was\n    // provisioned for the address), so the control must stop offering a\n    // re-check. One selector-form useWatch, not one per key: the key list is\n    // admin config and its LENGTH must never decide how many hooks run.\n    const lockKeys = useMemo(\n        () => parseLockFieldKeys(field.verifyLockedWhenFields),\n        [field.verifyLockedWhenFields],\n    );\n    const locked = Form.useWatch(\n        (values) => isVerifyLocked({\n            lockKeys,\n            resultValue: readAtPath(values, siblingFieldPath(absoluteName, field.verifyResultField)),\n            hasResultField: Boolean(field.verifyResultField),\n            readSibling: (key) => readAtPath(values, siblingFieldPath(absoluteName, key)),\n        }),\n        { form, preserve: true },\n    );\n\n    // Editing the value of a row that is LOCKED (an account already exists for\n    // the stored address) deliberately still runs this reset. It clears ONLY\n    // the two verify carriers — never the lock fields — which is the safe\n    // split:\n    //   • the lock/provisioning stamps (isAccountCreate, accountUserId, …)\n    //     describe an account that really was created and still exists, so\n    //     wiping them would make the record lie about the outside world;\n    //   • the validity stamp described the OLD address, so keeping it would\n    //     badge a freshly typed, never-checked address as \"Verified\".\n    // Because the lock requires the result field too, clearing the result\n    // UNLOCKS the row: the button comes back as \"Re Verify\", the group's\n    // requireValidatedField gate blocks the save until the new address passes,\n    // and re-verifying re-locks it. Suppressing the reset instead would strand\n    // the row in a Verified state with no way to re-check it.\n    useEffect(() => {\n        const normalized = String(currentValue ?? '').trim();\n        if (resultValue === true && verifiedValueRef.current === null && normalized) {\n            verifiedValueRef.current = normalized;\n            return;\n        }\n        if (resultValue === true && verifiedValueRef.current !== null && normalized !== verifiedValueRef.current) {\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), false);\n            if (field.verifyTimestampField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), undefined);\n            verifiedValueRef.current = null;\n        }\n    }, [absoluteName, currentValue, field.verifyResultField, field.verifyTimestampField, form, resultValue]);\n\n    if (field.verifyAction !== 'email') return null;\n\n    const runVerify = async () => {\n        const email = String(currentValue ?? '').trim();\n        if (!email) {\n            message.warning('Enter an email first');\n            return;\n        }\n        setChecking(true);\n        try {\n            const result = await verifyEmail(email);\n            verifiedValueRef.current = result.valid ? email : null;\n            setVerdict(result.valid ? result : null);\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), result.valid);\n            if (field.verifyTimestampField) {\n                form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), result.valid ? new Date().toISOString() : undefined);\n            }\n            // Three outcomes, not two. \"Accepted but unconfirmed\" is the common\n            // case on catch-all domains (Google Workspace's default, and most\n            // corporate mail) — reporting it as a plain success would tell the\n            // user the mailbox exists when nothing proved that.\n            if (!result.valid) {\n                message.error(result.reason ? `Invalid email: ${result.reason}` : 'Email could not be verified');\n            } else if (result.mailboxConfirmed) {\n                message.success('Email verified \\u2014 the mail server confirmed this mailbox');\n            } else {\n                message.warning(result.reason || 'The domain can receive mail, but this exact mailbox could not be confirmed');\n            }\n        } catch (err) {\n            verifiedValueRef.current = null;\n            setVerdict(null);\n            if (field.verifyResultField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyResultField), false);\n            if (field.verifyTimestampField) form.setFieldValue(siblingFieldPath(absoluteName, field.verifyTimestampField), undefined);\n            message.error(err?.message || 'Could not verify email');\n        } finally {\n            setChecking(false);\n        }\n    };\n\n    if (locked) {\n        // Non-interactive on purpose: there is no button and no onClick, so the\n        // check cannot be re-run. Wins over the \"Valid\"/\"Accepted\" labels below\n        // because those describe a re-runnable check, and this one isn't.\n        return (\n            <Text type=\"success\" strong className=\"v1-verify-field-wrap\">\n                {field.verifyLockedLabel || 'Verified'}\n            </Text>\n        );\n    }\n\n    if (resultValue === true) {\n        // Accepted, but the mailbox itself was never proven (catch-all domain).\n        // Labelling that \"Valid\" would overstate what the check established, so\n        // it gets its own state. The address still passes the submit gate — the\n        // account email that follows is what ultimately proves delivery.\n        // Only positive evidence of \"unconfirmed\" downgrades the label. A\n        // response that simply doesn't carry the field (older backend, or a\n        // check that never reached the mailbox stage) keeps the plain success\n        // state rather than casting doubt the check never actually raised.\n        if (verdict && !verdict.mailboxConfirmed && (verdict.catchAll || verdict.result === 'risky')) {\n            return (\n                <Tooltip title={verdict.reason || 'This domain accepts every address, so the mailbox could not be confirmed. Delivery is proven only once the account email is actually sent.'}>\n                    <Text type=\"warning\" strong className=\"v1-verify-field-wrap\">\n                        {field.verifyUnconfirmedLabel || 'Accepted'}\n                    </Text>\n                </Tooltip>\n            );\n        }\n        return <Text type=\"success\" strong className=\"v1-verify-field-wrap\">{field.verifySuccessLabel || 'Valid'}</Text>;\n    }\n\n    return (\n        <Button size=\"small\" loading={checking} onClick={runVerify} className=\"v1-verify-field-wrap\">\n            {resultValue === false ? (field.verifyRetryLabel || 'Re Verify') : (field.verifyIdleLabel || 'Verify Email')}\n        </Button>\n    );\n}\n\nfunction ConfiguredFieldLabel({ form, field, siblingPrefix, locked, combined = false }) {\n    const watchedValue = Form.useWatch(conditionFieldPath(field?.labelWhen, siblingPrefix), form);\n    const label = configuredFieldLabel(field, watchedValue, combined);\n    return combined ? label : <FieldLabel field={field} label={label} locked={locked} />;\n}\n\nfunction ValidationGatedSubmitButton({ form, groups, disabled, loading, onClick, children }) {\n    const unvalidated = Form.useWatch(\n        (values) => groups.some((group) => {\n            if (!group.addRow || !group.requireValidatedField) return false;\n            const rows = values?.[group.name] ?? [];\n            return rows.length === 0 || rows.some((row) => !row?.[group.requireValidatedField]);\n        }),\n        { form, preserve: true },\n    );\n    const isDisabled = disabled || unvalidated;\n    // Config-driven disabled-reason tooltip (mirrors AddFormV1): admin-set\n    // group.submitDisabledMessage, or a row-validation-specific default.\n    const groupMsg = groups.find((g) => g.submitDisabledMessage)?.submitDisabledMessage;\n    const validatedMsg = groups.find((g) => g.requireValidatedField)?.requireValidatedFieldMessage;\n    const reason = unvalidated\n        ? (validatedMsg || groupMsg || 'Verify every required row before submitting.')\n        : (groupMsg || 'Complete all mandatory fields before submitting.');\n    const button = (\n        <Button type=\"primary\" onClick={onClick} disabled={isDisabled} loading={loading}>\n            {children}\n        </Button>\n    );\n    return isDisabled && !loading\n        ? <Tooltip title={reason}><span style={{ display: 'inline-flex', cursor: 'not-allowed' }}>{button}</span></Tooltip>\n        : button;\n}\n\n// PrefillWhenWatcher — mirrors AddFormV1.jsx's identical component: sets this\n// field's own value when a referenced field's value matches a configured rule,\n// clears it when a rule is marked `clearValue`, and (resetOnNoMatch, admin\n// config `prefillWhenReset`, default on) clears it back out when the watched\n// value stops matching ANY rule — but only when the field still holds exactly\n// what a previous match set, never a value the user/record genuinely carries.\n//\n// Both forms delegate every decision to form/prefillWhenRules.js, so edit and\n// add can never drift. It IS safe to run the clear paths on edit: a clear only\n// ever fires after the user changes the watched field themselves (the pure\n// resolver suppresses clears on the first evaluation precisely so opening a\n// record whose stored contractType already matches a clear rule cannot delete\n// the stored employer), and the mismatch clear is additionally gated on the\n// field still holding the exact value a rule wrote in this session.\nfunction PrefillWhenWatcher({ form, rules, watchPaths, targetPath, resetOnNoMatch = true }) {\n    const watchedKey = Form.useWatch(\n        (values) => JSON.stringify(\n            watchPaths.map(({ path }) => path.reduce((acc, key) => (acc == null ? acc : acc[key]), values) ?? null),\n        ),\n        { form, preserve: true },\n    );\n    const lastAppliedRef = useRef(undefined);\n    const initialRef = useRef(true);\n    useEffect(() => {\n        const values = watchedKey ? JSON.parse(watchedKey) : [];\n        const watched = {};\n        watchPaths.forEach(({ field }, i) => { watched[field] = values[i]; });\n        const initial = initialRef.current;\n        initialRef.current = false;\n        const outcome = resolvePrefillWhen({\n            rules,\n            watched,\n            current: form.getFieldValue(targetPath),\n            lastApplied: lastAppliedRef.current,\n            clearOnMismatch: resetOnNoMatch,\n            initial,\n        });\n        if (outcome.action === 'set') {\n            form.setFieldValue(targetPath, outcome.value);\n            lastAppliedRef.current = outcome.value;\n        } else if (outcome.action === 'clear') {\n            form.setFieldValue(targetPath, undefined);\n            lastAppliedRef.current = undefined;\n        }\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [watchedKey]);\n    return null;\n}\n\n\nconst sectionIcons = [\n    <UserOutlined />,\n    <EnvironmentOutlined />,\n    <SolutionOutlined />,\n    <InfoCircleOutlined />,\n    <FileTextOutlined />,\n];\n\nconst fieldIcons = {\n    email: <MailOutlined className=\"v1-input-icon\" />,\n    contactNumber: <PhoneOutlined className=\"v1-input-icon\" />,\n    phone: <PhoneOutlined className=\"v1-input-icon\" />,\n    currentLocation: <EnvironmentOutlined className=\"v1-input-icon\" />,\n    preferredLocation: <EnvironmentOutlined className=\"v1-input-icon\" />,\n    designation: <SolutionOutlined className=\"v1-input-icon\" />,\n    skills: <TagsOutlined className=\"v1-input-icon\" />,\n    firstName: <UserOutlined className=\"v1-input-icon\" />,\n    lastName: <UserOutlined className=\"v1-input-icon\" />,\n    jobTitle: <SolutionOutlined className=\"v1-input-icon\" />,\n    jobLocation: <EnvironmentOutlined className=\"v1-input-icon\" />,\n    vendorEmail: <MailOutlined className=\"v1-input-icon\" />,\n};\n\n// ─── Pure helpers ────────────────────────────────────────────────────────────\n\nconst truthy = (v) => v === true || v === 1 || v === '1';\nconst editable = (field, moduleName) => (field?.edit === undefined || truthy(field.edit))\n    && (!field?.editablePermission || roleAllowsAction(field.editablePermission, moduleName));\nconst empty = (v) => v === undefined || v === null || v === '';\n\nfunction hasMeaningfulValue(value) {\n    if (value === undefined || value === null || value === '') return false;\n    if (Array.isArray(value)) return value.length > 0 && value.some(hasMeaningfulValue);\n    if (typeof value === 'object') return Object.values(value).some(hasMeaningfulValue);\n    return true;\n}\n\nfunction normalizeModule(name = '') {\n    const n = String(name).toLowerCase();\n    if (n === 'job') return 'jobs';\n    if (n === 'candidate') return 'candidates';\n    if (n === 'submissions') return 'submission';\n    return n;\n}\n\nfunction normalizeOptions(options = []) {\n    return options.map((o) => {\n        if (typeof o === 'string') return { label: o, value: o };\n        return {\n            label: o.label ?? o.name ?? o.value ?? o.userName ?? o.email,\n            value: o.value ?? o.id ?? o.userId ?? o._id ?? o.name ?? o.label,\n        };\n    });\n}\n\n// Group-level showIf — mirrors AddFormV1.jsx so both forms evaluate a group's\n// visibility condition identically (same operators as field-level showIf).\nfunction groupShowIfMatches(showIf, value) {\n    if (!showIf?.field) return true;\n    const actual = String(value ?? '');\n    const expected = String(showIf.value ?? '');\n    const list = () => expected.split(',').map((v) => v.trim());\n    switch (showIf.operator) {\n        case 'eq': return actual === expected;\n        case 'neq': return actual !== expected;\n        case 'in': return list().includes(actual);\n        case 'notIn': return !list().includes(actual);\n        case 'truthy': return truthy(value);\n        case 'falsy': return !truthy(value);\n        case 'empty':\n        case 'isEmpty':\n            return value === undefined || value === null || actual.trim() === '' || (Array.isArray(value) && value.length === 0);\n        case 'notEmpty':\n            return !(value === undefined || value === null || actual.trim() === '' || (Array.isArray(value) && value.length === 0));\n        default: return true;\n    }\n}\n\n// Group-level disable (mirrors AddFormV1): the whole card goes read-only when\n// the group's `disabled` flag is set or its `disabledIf` condition matches.\n// Provided via context so every FieldControl in the group inherits it; nested/\n// merged groups inherit the parent's disabled state.\nconst GroupDisabledContext = React.createContext(false);\n\nfunction GroupDisabledProvider({ form, group, children, inheritParent = true }) {\n    const parentDisabled = React.useContext(GroupDisabledContext);\n    const path = group?.disabledIf?.field ? namePathFromString(group.disabledIf.field) : ['__noop_group_disabled__'];\n    const watched = Form.useWatch(path, form);\n    const conditionDisabled = group?.disabledIf?.field\n        ? groupShowIfMatches(group.disabledIf, watched)\n        : false;\n    // `inheritParent: false` is used for a MERGED child (group.mergeInto).\n    // mergeInto is presentation only — the child borrows the host's card and\n    // nothing else — so inheriting the host's disabled state would give a\n    // display relationship real behaviour.\n    //\n    // It is also the difference between working and deadlocked: the Employer\n    // section is disabled until a Contract Type is chosen, and Contract Type is\n    // rendered INSIDE that section. Inheriting would disable the very control\n    // that enables the card, with no way out.\n    const disabled = (inheritParent && parentDisabled)\n        || Boolean(group?.disabled)\n        || conditionDisabled;\n    return <GroupDisabledContext.Provider value={disabled}>{children}</GroupDisabledContext.Provider>;\n}\n\nfunction GroupShowIfGate({ form, showIf, render }) {\n    const watched = Form.useWatch(showIf.field, form);\n    if (!groupShowIfMatches(showIf, watched)) return null;\n    return render();\n}\n\nfunction getNestedProp(obj, dotPath) {\n    return String(dotPath ?? '').split('.').reduce((cur, k) => cur?.[k], obj);\n}\n\nfunction FieldLabel({ field, label, locked }) {\n    if (!label) return label;\n    // field.tooltip (admin config) OR the older infoEnabled/infoText pair —\n    // resolved by the same helper AddFormV1 uses, so a field configured once\n    // shows the same help text on the add form and the edit form.\n    const infoText = fieldTooltipText(field);\n    const showInfo = Boolean(infoText);\n    if (!showInfo && !locked) return label;\n    return (\n        <span className=\"v1-field-label-with-info\">\n            <span>{label}</span>\n            {showInfo && (\n                <Tooltip title={infoText}>\n                    <InfoCircleOutlined className=\"v1-field-info-icon\" />\n                </Tooltip>\n            )}\n            {locked && (\n                <Tooltip title=\"You don't have permission to edit this field\">\n                    <LockOutlined className=\"v1-field-info-icon\" />\n                </Tooltip>\n            )}\n        </span>\n    );\n}\n\nfunction GroupInfoMessage({ group }) {\n    if (!truthy(group?.infoEnabled) || empty(group?.infoText)) return null;\n    return <Text type=\"secondary\" className=\"v1-group-info-message\">{group.infoText}</Text>;\n}\n\nfunction GroupToggleControl({ group }) {\n    if (!truthy(group?.toggleEnabled) || empty(group?.toggleField)) return null;\n    return (\n        <Space size={6} align=\"center\" onClick={(event) => event.stopPropagation()}>\n            <Text type=\"secondary\" className=\"v1-combine-toggle-label\">{group.toggleLabel || 'Toggle'}</Text>\n            <Form.Item name={group.toggleField} valuePropName=\"checked\" initialValue={Boolean(group.toggleValue)} noStyle>\n                <Switch size=\"small\" />\n            </Form.Item>\n        </Space>\n    );\n}\n\nfunction normalizeGroups(groups = [], moduleName, rolePerms, defaultFieldSet) {\n    const dset = defaultFieldSet ?? new Set();\n    return [...groups]\n        // hideGroup hides everywhere; hideGroupInForm is the form-only mirror of\n        // DetailViewV1's hideGroupInDetail — for server-owned groups that must be\n        // read on the detail view but never typed here.\n        .filter((g) => !truthy(g.hideGroup) && !truthy(g.hideGroupInForm)\n            && groupAllowedByRole(rolePerms, g.name))\n        .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n        .map((g) => ({\n            ...g,\n            fields: [...(g.fields ?? [])]\n                // Default Fields (Form Groups → Default Fields): always shown +\n                // required, so force show/req before the hidden-field filter.\n                .map((f) => (dset.has(f.field) ? { ...f, show: 1, req: 1 } : f))\n                // A field with a blank key can't render or submit — drop it so\n                // one stray admin-config row can't break the whole group. Also\n                // drop any field this role's Form Configuration (Role Configure\n                // → Form, derived from this same Form Groups config) turned off.\n                //\n                // A field with show:0 (\"hidden\") is intentionally KEPT here even\n                // though it must never render — this same fields array also feeds\n                // buildPayload/buildRowObject (the payload engine has no other way\n                // to know a hidden carrier field like isValid/isAccountCreate\n                // exists). Dropping it here silently threw away every hidden\n                // field's value at submit time. See renderFields, which is what\n                // actually keeps hidden fields off the screen.\n                .filter((f) => String(f.field ?? '').trim() !== ''\n                    && (!f.visiblePermission || roleAllowsAction(f.visiblePermission, moduleName))\n                    && fieldAllowedByRole(rolePerms, g.name, f.field))\n                // Role \"disable\": a non-editable group/field renders read-only.\n                .map((f) => (\n                    fieldEditableByRole(rolePerms, g.name, f.field)\n                        ? f\n                        : { ...f, disabled: true }\n                ))\n                .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0)),\n        }))\n        .filter((g) => g.fields.length);\n}\n\nfunction stripHtml(html) {\n    return String(html ?? '')\n        .replace(/<[^>]*>/g, '')\n        .replace(/&nbsp;/g, ' ')\n        .replace(/&amp;/g, '&')\n        .replace(/&lt;/g, '<')\n        .replace(/&gt;/g, '>')\n        .trim();\n}\n\nfunction getValidationValue(field, type) {\n    const rules = field.validations ?? field.validation ?? field.rules ?? [];\n    const rule = rules.find((r) => (typeof r === 'string' ? r : r?.type) === type);\n    if (!rule || typeof rule === 'string') return undefined;\n    return rule.value ?? rule.length ?? rule[type];\n}\n\nconst numberRangeRule = ({ label, message: msg, value, compare, text }) => ({\n    validator: (_, input) => {\n        if (empty(input)) return Promise.resolve();\n        return compare(Number(input), Number(value))\n            ? Promise.resolve()\n            : Promise.reject(new Error(msg ?? `${label} ${text} ${value}`));\n    },\n});\n\n// Shared with AddFormV1 (form/maxCeiling.js): a DOTTED reference is absolute\n// (reaches out of the validated field's container), a bare one is a sibling.\nfunction getSiblingFieldName(currentName, compareField) {\n    return resolveCompareFieldName(currentName, compareField);\n}\n\n// Date comparison + picker-constraint helpers now live in ONE place\n// (components/form/dateRules.js) and are imported at the top of this file.\n// They used to be duplicated verbatim between AddFormV1 and EditFormV1, which\n// is how a fix lands on Add and silently misses Edit.\n\nconst crossFieldNumberRule = ({ label, message, value, rule, form, name, compare, text }) => ({\n    validator: async (_, input) => {\n        const compareField = value ?? rule.compareField ?? rule.field;\n        if (!compareField || empty(input)) return Promise.resolve();\n        const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n        if (empty(compareValue)) return Promise.resolve();\n        const inputNumber = Number(input);\n        const compareNumber = Number(compareValue);\n        if (Number.isNaN(inputNumber) || Number.isNaN(compareNumber)) return Promise.resolve();\n        return compare(inputNumber, compareNumber)\n            ? Promise.resolve()\n            : Promise.reject(new Error(message ?? `${label} ${text} ${compareField}`));\n    },\n});\n\nconst validationRulesByType = {\n    // The pre-existing minLength3 / minLength5 pair baked the threshold into the\n    // TYPE NAME, and existed only in AddFormV1 — configuring one on a field did\n    // nothing at all on the Edit form. Both now delegate to the generic `min`\n    // rule (admin: \"Min length/value\"), which already implements exactly this\n    // for non-number fields and is present in BOTH forms.\n    minLength3: (args) => validationRulesByType.min({ ...args, value: 3 }),\n    minLength5: (args) => validationRulesByType.min({ ...args, value: 5 }),\n    noPastDate: ({ label, message: msg }) => ({\n        validator: (_, value) => {\n            if (empty(value)) return Promise.resolve();\n            const today = new Date();\n            today.setHours(0, 0, 0, 0);\n            return getComparableDateTime(value) < today.getTime()\n                ? Promise.reject(new Error(msg ?? `${label} cannot be a past date`))\n                : Promise.resolve();\n        },\n    }),\n    noFutureDate: ({ label, message: msg }) => ({\n        validator: (_, value) => {\n            if (empty(value)) return Promise.resolve();\n            const endOfDay = new Date();\n            endOfDay.setHours(23, 59, 59, 999);\n            return getComparableDateTime(value) > endOfDay.getTime()\n                ? Promise.reject(new Error(msg ?? `${label} cannot be a future date`))\n                : Promise.resolve();\n        },\n    }),\n    minAge: ({ message: msg, value }) => ({\n        validator: (_, input) => {\n            if (empty(input)) return Promise.resolve();\n            const years = Number(value ?? 18);\n            const cutoff = new Date();\n            cutoff.setFullYear(cutoff.getFullYear() - years);\n            cutoff.setHours(23, 59, 59, 999);\n            return getComparableDateTime(input) > cutoff.getTime()\n                ? Promise.reject(new Error(msg ?? `Must be at least ${years} years old`))\n                : Promise.resolve();\n        },\n    }),\n    // Both date-pair rules delegate to the shared engine, so `strict` (reject an\n    // equal date — the 7-July bug) and `minGap`/`minGapFrom` (the duration\n    // dropdown) behave identically on Add and Edit, and the SAME rule object\n    // also drives the picker's disabledDate below.\n    dateAfterField: ({ label, message: msg, value, rule, form, name }) => buildPairValidator({\n        type: 'dateAfterField',\n        label,\n        rule: { ...rule, value: value ?? rule?.compareField ?? rule?.field, message: msg },\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n    }),\n    dateBeforeField: ({ label, message: msg, value, rule, form, name }) => buildPairValidator({\n        type: 'dateBeforeField',\n        label,\n        rule: { ...rule, value: value ?? rule?.compareField ?? rule?.field, message: msg },\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n    }),\n    timeAfterField: ({ label, message: msg, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const compareField = value ?? rule.compareField ?? rule.field;\n            if (!compareField || empty(input)) return Promise.resolve();\n            const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n            if (empty(compareValue)) return Promise.resolve();\n            const inputTime = getComparableTimeOfDay(input);\n            const compareTime = getComparableTimeOfDay(compareValue);\n            if (inputTime === null || compareTime === null || inputTime > compareTime) return Promise.resolve();\n            return Promise.reject(new Error(msg ?? `${label} must be after ${compareField}`));\n        },\n    }),\n    timeBeforeField: ({ label, message: msg, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const compareField = value ?? rule.compareField ?? rule.field;\n            if (!compareField || empty(input)) return Promise.resolve();\n            const compareValue = form.getFieldValue(getSiblingFieldName(name, compareField));\n            if (empty(compareValue)) return Promise.resolve();\n            const inputTime = getComparableTimeOfDay(input);\n            const compareTime = getComparableTimeOfDay(compareValue);\n            if (inputTime === null || compareTime === null || inputTime < compareTime) return Promise.resolve();\n            return Promise.reject(new Error(msg ?? `${label} must be before ${compareField}`));\n        },\n    }),\n    greaterThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input >= other, text: 'must be greater than or equal to' }),\n    strictGreaterThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input > other, text: 'must be greater than' }),\n    strictLessThanField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input < other, text: 'must be less than' }),\n    lessThanOrEqualField: (args) => crossFieldNumberRule({ ...args, compare: (input, other) => input <= other, text: 'must be less than or equal to' }),\n    // maxFromField — { type:'maxFromField', field:'<otherKey>', message }. Same\n    // rule object AddFormV1 uses (form/crossFieldRules.js): the referenced field\n    // is resolved through renderField's `prefixFor`, i.e. with the scoping a\n    // Show Condition uses, so a rule inside an addRow row can cap itself against\n    // a TOP-LEVEL field. Which field caps which is Form Groups config.\n    maxFromField: (args) => maxFromFieldRule(args),\n    // Identical to AddFormV1's — the shared decision core (incl. the \"a 0\n    // ceiling means no ceiling\" rule) lives in form/maxCeiling.js.\n    maxFieldWithFallback: ({ label, message: msg, value, rule, form, name }) => ({\n        validator: async (_, input) => {\n            const result = checkMaxWithFallback({\n                input,\n                compareFields: parseCompareFields(value ?? rule.compareFields),\n                readValue: (fieldName) => readCompareValue(form, name, fieldName),\n            });\n            if (result.ok) return Promise.resolve();\n            return Promise.reject(new Error(msg ?? `${label} must not exceed ${result.field}`));\n        },\n    }),\n    required: ({ field, message: msg, form, name }) => ({\n        validator: (_, value) => {\n            // A field disabled via disabledByField (e.g. endDate while\n            // currentlyPursuing is checked) must not block submit with a\n            // \"required\" error the user has no way to satisfy.\n            if (field?.disabledByField && form && name) {\n                const disabledNow = truthy(form.getFieldValue(getSiblingFieldPath(name, field.disabledByField)));\n                if (disabledNow) return Promise.resolve();\n            }\n            // requiredIfField — e.g. an alternate phone's country code becomes\n            // mandatory only once the phone number itself has a value. Mirrors\n            // AddFormV1 (they used to diverge: this half existed only there).\n            if (field?.requiredIfField && form) {\n                const triggerValue = form.getFieldValue(getSiblingFieldPath(name, field.requiredIfField));\n                if (!truthy(triggerValue)) return Promise.resolve();\n            }\n            let isEmpty =\n                value === undefined || value === null || value === '' ||\n                (Array.isArray(value) && value.length === 0);\n            if (!isEmpty && field?.type === 'text-editor') isEmpty = stripHtml(value) === '';\n            return isEmpty\n                ? Promise.reject(new Error(msg ?? 'Mandatory Field'))\n                : Promise.resolve();\n        },\n    }),\n    email: ({ label, message: msg }) => configuredEmailRule(label, msg),\n    // Admin-configured \"already present\" check — same shared implementation\n    // AddFormV1 uses; the only difference is the recordId the edit context adds.\n    unique: ({ field, rule, uniqueContext }) => buildUniqueValidationRule({\n        field, validation: rule, context: uniqueContext,\n    }),\n    url: ({ label, message: msg }) => ({ type: 'url', message: msg ?? `Enter valid ${label}` }),\n    number: ({ label, message: msg }) => ({ pattern: /^[0-9]+$/, message: msg ?? `${label} must be a number` }),\n    phone: ({ message: msg }) => ({\n        validator: (_, value) => {\n            if (value === undefined || value === null || value === '') return Promise.resolve();\n            const { total } = parsePhoneFormat();\n            return phoneDigits(value).length === total\n                ? Promise.resolve()\n                : Promise.reject(new Error(msg ?? `Phone number must contain exactly ${total} digits`));\n        },\n    }),\n    len: ({ label, message: msg, value }) => ({ len: Number(value), message: msg ?? `${label} must be ${value} characters` }),\n    pattern: ({ label, message: msg, rule }) => ({\n        pattern: new RegExp(rule.pattern ?? rule.value, rule.flags),\n        message: msg ?? `Enter valid ${label}`,\n    }),\n    min: ({ field, label, message: msg, value }) =>\n        field.type === 'number'\n            ? numberRangeRule({ label, message: msg, value, compare: (i, m) => i >= m, text: 'must be at least' })\n            : {\n                validator: (_, input) => {\n                    if (input == null || input === '') return Promise.resolve();\n                    const content = field.type === 'text-editor' ? stripHtml(input) : String(input);\n                    if (content === '') return Promise.resolve();\n                    return content.length >= Number(value)\n                        ? Promise.resolve()\n                        : Promise.reject(new Error(msg ?? `${label} must be at least ${value} characters`));\n                },\n            },\n    max: ({ field, label, message: msg, value }) =>\n        field.type === 'number'\n            ? numberRangeRule({ label, message: msg, value, compare: (i, m) => i <= m, text: 'must not exceed' })\n            : {\n                validator: (_, input) => {\n                    if (input == null || input === '') return Promise.resolve();\n                    const content = field.type === 'text-editor' ? stripHtml(input) : String(input);\n                    if (content === '') return Promise.resolve();\n                    return content.length <= Number(value)\n                        ? Promise.resolve()\n                        : Promise.reject(new Error(msg ?? `${label} must not exceed ${value} characters`));\n                },\n            },\n};\n\n// `prefixFor` is renderField's showIf prefix resolver, forwarded so a rule that\n// references another field resolves it with the same row-vs-top-level scoping\n// the Show Conditions use (undefined at call sites with no row context).\nfunction validationToRule(validation, field, form, name, prefixFor, uniqueContext) {\n    const rule = typeof validation === 'string' ? { type: validation } : validation;\n    const type = rule.type ?? rule.rule ?? rule.name;\n    const value = rule.value ?? rule.length ?? rule.min ?? rule.max;\n    const label = field.label ?? field.field ?? 'Field';\n    const factory = validationRulesByType[type];\n    return factory ? factory({ field, label, message: rule.message, rule, value, form, name, prefixFor, uniqueContext }) : rule;\n}\n\nfunction getSiblingFieldPath(name, siblingField) {\n    return Array.isArray(name) && name.length > 1\n        ? [...name.slice(0, -1), siblingField]\n        : [siblingField];\n}\n\n// A field is required either via the simple \"req\" toggle or via a \"required\"\n// entry in the admin-configured validations list — the Form.Item asterisk and\n// the addRow \"at least one row\" check must honour both, not just field.req.\nfunction isFieldRequired(field) {\n    if (truthy(field?.req)) return true;\n    const apiRules = field?.validations ?? field?.validation ?? field?.rules ?? [];\n    return apiRules.some((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'required');\n}\n\n// `uniqueContext` ({ checker, module, recordId, clientId, region }) turns a\n// configured `unique` validation into a live preflight check. On EDIT it always\n// carries the recordId so the record never collides with its own stored value.\n// Call sites with no context leave the unique rule a no-op (the server-side\n// check at submit stays authoritative either way).\nfunction getRules(field, form, name, skipRequired = false, prefixFor = undefined, uniqueContext = undefined,\n    extraRules = undefined) {\n    const label = field.label ?? field.field ?? 'Field';\n    const apiRules = field.validations ?? field.validation ?? field.rules ?? [];\n    const hasApiRequired = apiRules.some((r) => (typeof r === 'string' ? r : r?.type) === 'required');\n    const hasApiEmail = apiRules.some((r) => (typeof r === 'string' ? r : r?.type) === 'email');\n    const rules = [];\n\n    // Rules the CALLER resolved because they need the group, which this\n    // function never sees — today, a region that refuses an in-progress entry.\n    // They go first so a blocked row reports that before anything else.\n    if (extraRules?.length) rules.push(...extraRules);\n\n    // Cross-row hierarchy: a newest-first list constrains each row against its\n    // NEIGHBOURS. The picker already greys the impossible dates out; this\n    // catches one that arrived another way — typed, pasted, prefilled from a\n    // résumé, or entered before the neighbouring row was filled in.\n    if (field.rowHierarchy) {\n        const ctx = rowContext(form, name);\n        if (ctx.rows) rules.push(buildRowHierarchyValidator({ field, ...ctx }));\n    }\n\n    if (!skipRequired && !hasApiRequired && (truthy(field.req) || field.requiredIfField)) {\n        rules.push(validationRulesByType.required({ field, message: 'Mandatory Field', form, name }));\n    }\n    if ((field.type === 'email' || field.formatter === 'email') && !hasApiEmail) {\n        rules.push(configuredEmailRule(label));\n    }\n    // Number fields are whole-number-only unless the admin marks them decimal\n    // (e.g. a commission of 5.5). Both patterns still reject any non-numeric\n    // character, so \"float only\" stays enforced either way.\n    if (field.type === 'number') {\n        rules.push(truthy(field.decimal)\n            ? { pattern: /^\\d+(\\.\\d+)?$/, message: `${label} must be a number` }\n            : { pattern: /^[0-9]+$/, message: `${label} must be a number` });\n    }\n    // attachUniqueSyncGuards re-wraps any `unique` rule so it only calls the\n    // server once every synchronous rule in this same list has passed.\n    // Admin override checkbox (field.overrideCheckbox) — suspends the validation\n    // TYPES it names while ticked. Same mechanism as AddFormV1, so a field\n    // configured once behaves identically on add and on edit.\n    const buildRule = (r) => validationToRule(r, field, form, name, prefixFor, uniqueContext);\n    const mapRule = overrideRuleMapper(field, name, prefixFor, buildRule);\n\n    return attachUniqueSyncGuards([...rules, ...apiRules.map(mapRule), securityValidationRule(field)]);\n}\n\nfunction getFieldDependencies(field, currentName, prefixFor) {\n    const supportedTypes = new Set([\n        'greaterThanField', 'strictGreaterThanField', 'strictLessThanField',\n        'lessThanOrEqualField', 'maxFieldWithFallback', 'dateAfterField', 'dateBeforeField',\n        'timeAfterField', 'timeBeforeField',\n    ]);\n    // maxFromField is handled apart from the sibling-based list below because the\n    // field it references may live outside this row — its dependency path has to\n    // be built with the rule's own (showIf) scoping.\n    const scoped = (field.validations ?? field.validation ?? field.rules ?? [])\n        .filter((rule) => (typeof rule === 'string' ? rule : rule?.type) === 'maxFromField')\n        .map((rule) => maxFromFieldDependency(rule, currentName, prefixFor))\n        .filter(Boolean);\n    return [...scoped, ...(field.validations ?? field.validation ?? field.rules ?? [])\n        .filter((rule) => supportedTypes.has(typeof rule === 'string' ? rule : rule?.type))\n        .flatMap((rule) => String(rule.value ?? rule.compareField ?? rule.field ?? '')\n            .split(',').map((item) => item.trim()).filter(Boolean)\n            .map((compareField) => getSiblingFieldName(currentName, compareField)))];\n}\n\nfunction getInputLimits(field) {\n    const len = field.len ?? getValidationValue(field, 'len');\n    const min = field.min ?? getValidationValue(field, 'min');\n    const max = field.max ?? getValidationValue(field, 'max');\n    if (field.type === 'number') return { min: min ?? undefined, max: max ?? undefined };\n    return { minLength: min ?? undefined, maxLength: field.maxLength ?? len ?? max ?? undefined };\n}\n\n// Thin adapters over the shared engine (components/form/dateRules.js). The\n// bodies used to live here AND in EditFormV1; the picker's greyed-out range and\n// the submit-time error are now generated from the same rule object, so a\n// calendar that disagrees with its own error message is structurally impossible.\n// rowContext — the sibling ROWS of the repeatable group this field sits in,\n// plus this field's row index.\n//\n// A per-row `readSibling` can only see the row it is in, but a newest-first\n// list constrains a row against its NEIGHBOURS. Inside a Form.List the field\n// path is [listName, rowIndex, fieldKey], which is exactly what is needed to\n// read the whole list and locate this row within it.\n//\n// Returns {} outside a repeatable group, so the hierarchy simply never applies.\nfunction rowContext(form, name) {\n    if (!Array.isArray(name) || name.length < 3 || typeof name[1] !== 'number') return {};\n    const rows = form.getFieldValue(name[0]);\n    if (!Array.isArray(rows)) return {};\n    return { rows, rowIndex: name[1] };\n}\n\nfunction getDisabledDate(field, form, name) {\n    return buildDisabledDate({\n        field,\n        readSibling: (key) => form.getFieldValue(getSiblingFieldName(name, key)),\n        ...rowContext(form, name),\n    });\n}\n\nfunction getDefaultPickerValue(field) {\n    return defaultPickerValue(field);\n}\n\nfunction cleanValue(value, formatter) {\n    if (!formatter) return value;\n    if (formatter === 'phone') return formatPhone(value);\n    if (formatter === 'digits') return value.replace(/\\D/g, '').slice(0, 10);\n    if (formatter === 'email' || formatter === 'noSpaces') return value.replace(/\\s/g, '');\n    if (formatter === 'name') return value.replace(/\\s+/g, ' ').trimStart().replace(/\\b\\w/g, (c) => c.toUpperCase());\n    return value;\n}\n\n// ─── FieldControl ─────────────────────────────────────────────────────────────\n\nfunction FieldControl({ field, form, name, value, checked, fileList, moduleName, recordId, initialValue, scopeValues = {}, onAiUpload, onRegionBlocked, onRowOrderChange, formDisabled, rowFieldKeys }) {\n    const type = field.type ?? 'text';\n    const baseDisabled = !editable(field, moduleName);\n\n    // ALL hooks at the top — before any conditional returns\n    const [dynamicOptions, setDynamicOptions] = useState(null);\n    const [optionsLoading, setOptionsLoading] = useState(false);\n    const [locationSearch, setLocationSearch] = useState('');\n    const [lookupSearch, setLookupSearch] = useState('');\n    const [masterSearch, setMasterSearch] = useState('');\n    const [viewer, setViewer] = useState({ open: false, docs: [], index: 0 });\n    const [inputError, setInputError] = useState(null);\n    // Bumped after a quick create/edit (\"Add More\") to refetch dropdown options.\n    const [refetchNonce, setRefetchNonce] = useState(0);\n    const rawLookupRef = useRef([]);\n    // Row-aware lookupFilterValueFrom — mirrors AddFormV1.jsx: same-row sibling\n    // wins when non-empty, top-level path is the fallback for old configs.\n    const insideListRow = Array.isArray(name) && name.length >= 3 && typeof name[1] === 'number';\n    const topFilterPath = field.lookupFilterValueFrom ? namePathFromString(field.lookupFilterValueFrom) : [`__lookup_filter_${field.field}`];\n    const rowFilterPath = (field.lookupFilterValueFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.lookupFilterValueFrom)]\n        : ['__noop_row_filter__'];\n    const topFilterValue = Form.useWatch(topFilterPath, form);\n    const rowFilterValue = Form.useWatch(rowFilterPath, form);\n    const formFilterValue = !empty(rowFilterValue) ? rowFilterValue : topFilterValue;\n    // scopeValues (e.g. AddFormV1's client-gate id) only wins when it actually\n    // carries a value — a key present but undefined/empty (e.g. EditFormV1's\n    // `{ clientId }` when no clientId prop was passed, as on the Jobs edit\n    // page) must fall back to the field's own live form value, or the lookup\n    // filter is permanently starved and the dropdown never resolves a name.\n    const scopeFilterValue = field.lookupFilterValueFrom\n        ? scopeValues[field.lookupFilterValueFrom]\n        : undefined;\n    const lookupFilterValue = !empty(scopeFilterValue) ? scopeFilterValue : formFilterValue;\n\n    // ---- Dependent-lookup staleness guard (generic; mirrors AddFormV1) ----\n    // A lookup scoped by `lookupFilterValueFrom` must not keep a value chosen\n    // under a DIFFERENT parent. Changing the parent refetches the OPTIONS but\n    // used to leave this field's value untouched, so client A's contact id\n    // survived a switch to client B. A nested reference id is only unique\n    // WITHIN its parent (clientContact.clientContactId is a per-client 1,2,3\n    // sequence), so the orphaned id still resolved - to a DIFFERENT person -\n    // and saved looking valid. A wrong name that looks right beats a blank one.\n    //\n    // Only a genuine CHANGE clears: the first observed value is recorded\n    // silently, so EDIT PREFILL (which sets parent and child together) is\n    // untouched, and empty -> known never clears.\n    const parentFilterRef = useRef(PARENT_FILTER_UNSEEN);\n    useEffect(() => {\n        if (!field.lookupFilterField || !field.lookupFilterValueFrom) return;\n        const previous = parentFilterRef.current;\n        parentFilterRef.current = lookupFilterValue;\n        if (!shouldClearDependentValue({\n            previous,\n            next: lookupFilterValue,\n            currentValue: form.getFieldValue(name),\n        })) return;\n        form.setFields([{ name, value: undefined, errors: [] }]);\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [lookupFilterValue]);\n    const disabledBySiblingPath = field.disabledByField\n        ? (Array.isArray(name) && name.length > 1 ? [...name.slice(0, -1), field.disabledByField] : [field.disabledByField])\n        : ['__noop_disabled_watch__'];\n    const disabledByValue = Form.useWatch(disabledBySiblingPath, form);\n    // disabledIf — conditional read-only, same operator set as showIf (eq/neq/\n    // truthy/falsy/in/notIn), e.g. lock the Employer to the configured default\n    // when Contract Type is W2. The row value wins when the condition field\n    // lives in this row; otherwise the top-level field drives it.\n    const disabledIfTopPath = field.disabledIf?.field ? namePathFromString(field.disabledIf.field) : ['__noop_disabled_if__'];\n    const disabledIfRowPath = (field.disabledIf?.field && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.disabledIf.field)]\n        : ['__noop_disabled_if_row__'];\n    const disabledIfTop = Form.useWatch(disabledIfTopPath, form);\n    const disabledIfRow = Form.useWatch(disabledIfRowPath, form);\n    const conditionallyDisabled = field.disabledIf?.field\n        ? labelConditionMatches(field.disabledIf, !empty(disabledIfRow) ? disabledIfRow : disabledIfTop)\n        : false;\n    // optionsFromField (admin config) — narrow this control's options to the live\n    // value of ANOTHER field (see the identical block in AddFormV1). Resolved\n    // with the scoping a Show Condition uses: the row's own field when the key\n    // belongs to this row (rowFieldKeys), top level otherwise; row-first when\n    // membership is unknown. Both paths are always watched — hooks cannot be\n    // conditional — so the list re-narrows as soon as the source changes.\n    const constraintKey = field.optionsFromField || '';\n    const constraintTopPath = constraintKey ? namePathFromString(constraintKey) : ['__noop_options_from__'];\n    const constraintRowPath = (constraintKey && insideListRow && (!rowFieldKeys || rowFieldKeys.has(constraintKey)))\n        ? [...name.slice(0, 2), ...namePathFromString(constraintKey)]\n        : ['__noop_options_from_row__'];\n    const constraintTopValue = Form.useWatch(constraintTopPath, form);\n    const constraintRowValue = Form.useWatch(constraintRowPath, form);\n    const constraintValue = !empty(constraintRowValue) ? constraintRowValue : constraintTopValue;\n    // prefillWhenExclusive (admin config) — a value a Conditional Default rule\n    // would SET is EXCLUSIVE to that rule's condition: offered while the rule\n    // matches, REMOVED from the list while it does not. Mirrors AddFormV1\n    // exactly, so a field configured once behaves the same on add and on edit.\n    //\n    // HOOK SAFETY: the rule list is admin data and must never decide hook\n    // count — ONE selector-form useWatch reads every referenced field out of\n    // the whole store and reduces them to a string. Row-vs-top-level scoping is\n    // the same one optionsFromField uses above.\n    const exclusivePrefillRules = (truthy(field.prefillWhenExclusive) && field.prefillWhen?.length)\n        ? field.prefillWhen\n        : null;\n    const exclusivePrefillKey = Form.useWatch(\n        (values) => (exclusivePrefillRules\n            ? JSON.stringify(prefillWhenWatchFields(exclusivePrefillRules).map((key) => {\n                const read = (path) => path.reduce((acc, k) => (acc == null ? acc : acc[k]), values);\n                const rowValue = (insideListRow && (!rowFieldKeys || rowFieldKeys.has(key)))\n                    ? read([...name.slice(0, 2), ...namePathFromString(key)])\n                    : undefined;\n                return (!empty(rowValue) ? rowValue : read(namePathFromString(key))) ?? null;\n            }))\n            : ''),\n        { form, preserve: true },\n    );\n    const exclusivePrefillWatched = useMemo(() => {\n        if (!exclusivePrefillRules || !exclusivePrefillKey) return null;\n        const values = JSON.parse(exclusivePrefillKey);\n        const watched = {};\n        prefillWhenWatchFields(exclusivePrefillRules).forEach((key, i) => { watched[key] = values[i]; });\n        return watched;\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [exclusivePrefillKey]);\n    const groupDisabled = React.useContext(GroupDisabledContext);\n    // exclusiveInGroup — only ONE row of a repeatable group may hold this flag.\n    // See the matching comment in AddFormV1; watching the whole Form.List is\n    // what makes this react to a change in a DIFFERENT row.\n    const exclusiveListPath = (field.exclusiveInGroup && insideListRow)\n        ? [name[0]]\n        : ['__noop_exclusive_watch__'];\n    const exclusiveRows = Form.useWatch(exclusiveListPath, form);\n    const claimedByAnotherRow = useMemo(() => {\n        if (!field.exclusiveInGroup || !insideListRow || !Array.isArray(exclusiveRows)) return false;\n        const myIndex = name[1];\n        const leaf = name[name.length - 1];\n        return exclusiveRows.some((row, index) => index !== myIndex && truthy(row?.[leaf]));\n    }, [field.exclusiveInGroup, insideListRow, exclusiveRows, name]);\n    // locationMaster cascade (Country → State → City, sourced from the\n    // locationMasters collection). See the identical block in AddFormV1.\n    const locCountryTopPath = field.locationCountryFrom ? namePathFromString(field.locationCountryFrom) : ['__noop_loc_country__'];\n    const locCountryRowPath = (field.locationCountryFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.locationCountryFrom)]\n        : ['__noop_loc_country_row__'];\n    const locCountryTop = Form.useWatch(locCountryTopPath, form);\n    const locCountryRow = Form.useWatch(locCountryRowPath, form);\n    const locCountryValue = !empty(locCountryRow) ? locCountryRow : locCountryTop;\n    const locStateTopPath = field.locationStateFrom ? namePathFromString(field.locationStateFrom) : ['__noop_loc_state__'];\n    const locStateRowPath = (field.locationStateFrom && insideListRow)\n        ? [...name.slice(0, 2), ...namePathFromString(field.locationStateFrom)]\n        : ['__noop_loc_state_row__'];\n    const locStateTop = Form.useWatch(locStateTopPath, form);\n    const locStateRow = Form.useWatch(locStateRowPath, form);\n    const locStateValue = !empty(locStateRow) ? locStateRow : locStateTop;\n    const locationLocked = field.dataSource === 'locationMaster' && (\n        (field.locationLevel === 'state' && empty(locCountryValue))\n        || (field.locationLevel === 'city' && (empty(locCountryValue) || empty(locStateValue)))\n    );\n    const disabled = baseDisabled || Boolean(field.disabled) || conditionallyDisabled || (field.disabledByField ? truthy(disabledByValue) : false) || Boolean(formDisabled) || groupDisabled || claimedByAnotherRow || locationLocked;\n\n    useEffect(() => {\n        if (type === 'location') {\n            let cancelled = false;\n\n            async function fetchLocations() {\n                try {\n                    setOptionsLoading(true);\n                    const params = new URLSearchParams({\n                        search: locationSearch,\n                        limit: String(field.limit ?? 50),\n                        offset: '0',\n                    });\n                    const json = await fetchJsonWithAuth(AUTH_URL, `/admin/location-dropdown-values?${params}`);\n                    const raw = json?.data ?? json ?? [];\n                    if (!cancelled) setDynamicOptions(normalizeOptions(Array.isArray(raw) ? raw : []));\n                } catch (err) {\n                    console.error(`[EditFormV1] Failed to fetch locations for \"${field.field}\":`, err);\n                    if (!cancelled) setDynamicOptions([]);\n                } finally {\n                    if (!cancelled) setOptionsLoading(false);\n                }\n            }\n\n            fetchLocations();\n            return () => { cancelled = true; };\n        }\n        const ds = field.dataSource;\n        if (!['select', 'radio', 'checkbox'].includes(type)) return undefined;\n        if (!ds || ds === 'static') return undefined;\n        if (ds === 'lookup' && field.lookupFilterField && empty(lookupFilterValue)) {\n            setDynamicOptions([]);\n            setOptionsLoading(false);\n            return undefined;\n        }\n\n        let cancelled = false;\n\n        async function fetchOptions() {\n            try {\n                setOptionsLoading(true);\n                let raw = [];\n\n                if (ds === 'master' || ds === 'module') {\n                    raw = await getDropdownValues(\n                        moduleName,\n                        field.field,\n                        ds === 'master' ? masterSearch : '',\n                        field.limit ?? 50,\n                        0,\n                        {\n                            dataSource: ds,\n                            masterName: field.masterName,\n                            groupName: field.groupName,\n                        },\n                    );\n                } else if (ds === 'lookup') {\n                    const params = new URLSearchParams({\n                        collection: field.lookupCollection ?? '',\n                        displayField: field.displayField ?? '',\n                        valueField: field.valueField ?? '_id',\n                    });\n                    if (field.displayField2) params.set('displayField2', field.displayField2);\n                    if (lookupSearch) params.set('search', lookupSearch);\n                    if (field.lookupFilterField && !empty(lookupFilterValue)) {\n                        params.set('filterField', field.lookupFilterField);\n                        params.set('filterValue', String(lookupFilterValue));\n                    }\n                    // See AddFormV1 — rebuilt from the individual keys so this\n                    // effect does not depend on the whole `field` object.\n                    const rowFilterConfig = {\n                        field: field.field,\n                        extraFields: field.extraFields,\n                        optionsRequireExtraField: field.optionsRequireExtraField,\n                        optionsRequireExtraValue: field.optionsRequireExtraValue,\n                        optionsHierarchyParentField: field.optionsHierarchyParentField,\n                        optionsHierarchySelfFrom: field.optionsHierarchySelfFrom,\n                    };\n                    // The filter keys are added to extraFields automatically so\n                    // config cannot be half-applied.\n                    const extraKeys = lookupExtraFieldKeys(rowFilterConfig);\n                    if (extraKeys.length) params.set('extraFields', extraKeys.join(','));\n                    const json = await fetchJsonWithAuth(AUTH_URL, `/admin/lookup-dropdown-values?${params}`);\n                    raw = json?.data ?? json ?? [];\n                    raw = filterLookupOptionRows(raw, rowFilterConfig, { source: 'EditFormV1' });\n                } else if (ds === 'locationMaster') {\n                    const level = field.locationLevel || 'country';\n                    if (level === 'state' && empty(locCountryValue)) {\n                        raw = [];\n                    } else if (level === 'city' && (empty(locCountryValue) || empty(locStateValue))) {\n                        raw = [];\n                    } else {\n                        const params = new URLSearchParams({ level, limit: String(field.limit ?? 250), offset: '0' });\n                        if (!empty(locCountryValue)) params.set('country', String(locCountryValue));\n                        if (!empty(locStateValue)) params.set('state', String(locStateValue));\n                        if (lookupSearch) params.set('search', lookupSearch);\n                        const json = await fetchJsonWithAuth(AUTH_URL, `/admin/location-dropdown-values?${params}`);\n                        raw = json?.data ?? json ?? [];\n                    }\n                } else if (ds === 'group') {\n                    const groupName = String(field.groupName ?? '').toLowerCase().trim();\n                    if (groupName === 'users' || groupName === 'user') {\n                        const json = await fetchJsonWithAuth(AUTH_URL, '/get-all-users?limit=500&offset=0');\n                        const users = json?.data?.users ?? json?.users ?? json?.data ?? [];\n                        // groupRoleContains — see the identical block in AddFormV1.\n                        const roleContains = String(field.groupRoleContains ?? '').trim().toLowerCase();\n                        const filteredUsers = roleContains\n                            ? (Array.isArray(users) ? users.filter((u) => String(u.roleName ?? '').toLowerCase().includes(roleContains)) : [])\n                            : users;\n                        raw = Array.isArray(filteredUsers)\n                            ? filteredUsers.map((u) => ({\n                                label: [u.firstName, u.lastName].filter(Boolean).join(' ').trim()\n                                    || u.userName || u.email || String(u.userId ?? u.id),\n                                value: u.userId ?? u.id,\n                            }))\n                            : [];\n                    }\n                }\n\n                if (!cancelled) {\n                    rawLookupRef.current = Array.isArray(raw) ? raw : [];\n                    setDynamicOptions(normalizeOptions(rawLookupRef.current));\n                }\n            } catch (err) {\n                console.error(`[EditFormV1] Failed to fetch options for \"${field.field}\":`, err);\n                if (!cancelled) setDynamicOptions([]);\n            } finally {\n                if (!cancelled) setOptionsLoading(false);\n            }\n        }\n\n        fetchOptions();\n        return () => { cancelled = true; };\n    }, [type, field.dataSource, field.field, field.lookupCollection,\n        field.displayField, field.displayField2, field.valueField, field.lookupFilterField, lookupFilterValue, field.groupName, field.groupRoleContains, field.masterName, field.limit, locationSearch, lookupSearch, masterSearch, moduleName, field.extraFields, field.optionsRequireExtraField, field.optionsRequireExtraValue, field.optionsHierarchyParentField, field.optionsHierarchySelfFrom, refetchNonce, field.locationLevel, field.locationCountryFrom, field.locationStateFrom, locCountryValue, locStateValue]);\n\n    // ── Derived values ──\n    // The edit-form option fallback is a safety net for SELECT/RADIO fields\n    // whose options didn't survive a legacy save. It must NOT touch a checkbox:\n    // a boolean checkbox with options becomes a Checkbox.Group (Yes/No), so it\n    // would render completely differently from the single checkbox the Add form\n    // shows for the same field (e.g. \"Willing to Relocate\").\n    const configuredOptions = [field.options, field.values]\n        .find((items) => Array.isArray(items) && items.length > 0)\n        ?? (type === 'checkbox' ? [] : getEditFormFallbackOptions(field));\n    const staticOptions = normalizeOptions(configuredOptions);\n    const baseOptions = dynamicOptions ?? staticOptions;\n\n    // ── Stored values outside the filtered option list ──────────────────────\n    // `lookupFilters` decide what may be PICKED. They must not decide what an\n    // already-assigned value is allowed to SHOW — a job assigned to somebody\n    // outside the current user's reporting chain rendered its raw id (\"149\")\n    // instead of a name. Resolved separately, unfiltered, and appended.\n    const [resolvedOptions, setResolvedOptions] = useState([]);\n    const missingValues = missingOptionValues(value, baseOptions);\n    // Joined into a string: the array identity changes every render, and a raw\n    // array dependency would refetch forever.\n    const missingKey = missingValues.join(',');\n    useEffect(() => {\n        if (!missingKey || field.dataSource !== 'lookup' || optionsLoading) return undefined;\n        let cancelled = false;\n        fetchLookupLabels(field, missingKey.split(','))\n            .then((rows) => { if (!cancelled) setResolvedOptions(rows); })\n            // Best effort. Failing to resolve a label must never break the\n            // field — the value is still there and still submits.\n            .catch(() => { if (!cancelled) setResolvedOptions([]); });\n        return () => { cancelled = true; };\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [missingKey, field.dataSource, field.lookupCollection, field.displayField,\n        field.displayField2, field.valueField, optionsLoading]);\n    // optionsFromField constraint applied once, here, so EVERY option-driven\n    // control (select, radio, checkbox group, location…) narrows the same way.\n    // Fails open — see narrowOptionsByConstraint. prefillWhenExclusive then\n    // COMPOSES on top of that narrowing (it removes, it never restores).\n    const optionsWithStored = mergeResolvedOptions(baseOptions, resolvedOptions);\n    const constrainedOptions = constraintKey ? narrowOptionsByConstraint(optionsWithStored, constraintValue) : optionsWithStored;\n    const options = exclusivePrefillRules\n        ? stripExclusivePrefillOptions(constrainedOptions, exclusivePrefillRules, exclusivePrefillWatched ?? {})\n        : constrainedOptions;\n\n    const selectMode = field.multiSelect\n        ? 'multiple'\n        : field.mode ?? (truthy(field.multiple) ? 'multiple' : undefined);\n    const inferredSelectMode = selectMode ?? (effectiveDataType(field) === 'array' ? 'multiple' : undefined);\n    // allowCustomValues (admin config) — keep a value the user TYPED even when it\n    // is not in the list. Mirrors AddFormV1 exactly, so a field configured once\n    // behaves the same on add and on edit. antd's \"tags\" mode always emits an\n    // ARRAY, so a single-valued field is wrapped for display and unwrapped again\n    // on change — the stored shape never changes.\n    const allowCustomValues = truthy(field.allowCustomValues);\n    const effectiveSelectMode = allowCustomValues ? 'tags' : inferredSelectMode;\n    const isArrayValued = Boolean(field.multiSelect) || truthy(field.multiple)\n        || effectiveDataType(field) === 'array' || inferredSelectMode === 'multiple';\n    const tokenSeparators = allowCustomValues\n        ? (typeof field.tokenSeparators === 'string' && field.tokenSeparators\n            ? field.tokenSeparators.split('')\n            : [','])\n        : undefined;\n\n    const isSelectLike = ['select', 'location'].includes(type);\n    const placeholder = field.hidePlaceholder\n        ? undefined\n        : (field.placeholder ?? `${isSelectLike ? 'Select' : 'Enter'} ${String(field.label ?? '').toLowerCase()}`);\n    const inputLimits = getInputLimits(field);\n\n    const validateField = () => {\n        setTimeout(() => { form.validateFields([name]).catch(() => { }); });\n    };\n\n    const updateAndValidate = (nextValue) => {\n        form.setFieldValue(name, nextValue);\n        validateField();\n    };\n\n    // Config-driven \"Add More\"/\"Edit\" quick actions inside a select dropdown.\n    // Called unconditionally (rules of hooks); no-op unless the field opts in.\n    const quick = useQuickField({\n        field, form, name, moduleName, scopeValues, ownValue: value,\n        onDone: (kind, newId) => {\n            setRefetchNonce((n) => n + 1);\n            const single = effectiveDataType(field) !== 'array' && !field.multiSelect && !field.multiple;\n            if (kind === 'create' && newId != null && single) {\n                // Same clearing the ordinary onChange does. Creating an employer\n                // from inside the dropdown IS changing the employer, so the rest\n                // of the group — recruiter, email, contact, VMS — still describes\n                // the PREVIOUS one and must go. This path set the new value and\n                // skipped the clear, so a brand-new employer kept the old\n                // employer's recruiter beside it, which reads as a real pairing.\n                //\n                // Cleared BEFORE the value is written, so anything the new\n                // selection autofills is preserved rather than wiped after.\n                if (field.clearGroupOnChange || field.linkedClearField) {\n                    applyGroupClear(form, field, name, rowFieldKeys);\n                }\n                updateAndValidate(usesLabeledSelectValue(field) ? { value: newId } : newId);\n            }\n        },\n    });\n\n    // Build validator config once (null when not set)\n    const validatorCfg = field.validator?.type\n        ? { ...field.validator, title: field.validator.title || field.label || 'Field' }\n        : null;\n\n    const inputProps = {\n        ...inputLimits,\n        value,\n        disabled,\n        placeholder,\n        prefix: field.icon ? null : fieldIcons[field.field],\n        onChange: (e) => {\n            let next = field.formatter\n                ? cleanValue(e.target.value, field.formatter)\n                : e.target.value;\n\n            if (validatorCfg) {\n                const { cleaned, error } = applyInputValidator(next, validatorCfg, 'change');\n                setInputError(error);\n                next = cleaned;\n            }\n\n            updateAndValidate(next);\n        },\n        ...(validatorCfg && {\n            onBlur: (e) => {\n                const { cleaned, error } = applyInputValidator(e.target.value, validatorCfg, 'blur');\n                setInputError(error);\n                if (cleaned !== e.target.value) updateAndValidate(cleaned);\n            },\n            onKeyPress: (e) => {\n                const pattern = getKeyPattern(validatorCfg.type);\n                if (!pattern) return;\n                if (e.which === 0 || e.keyCode === 8 || e.keyCode === 13) return;\n                const char = String.fromCharCode(e.which ?? e.keyCode);\n                if (!pattern.test(char)) {\n                    e.preventDefault();\n                    const hint = `${validatorCfg.title} — invalid character.`;\n                    setInputError(hint);\n                    setTimeout(() => setInputError((prev) => (prev === hint ? null : prev)), 1800);\n                }\n            },\n            maxLength: validatorCfg.maxLength ?? inputLimits.maxLength,\n        }),\n    };\n\n    // ── Renders ──\n\n    if (type === 'tagify') {\n        return (\n            <Select value={value} allowClear disabled={disabled} mode=\"tags\"\n                placeholder={placeholder} onChange={updateAndValidate} />\n        );\n    }\n\n    if (type === 'location') {\n        return (\n            <Select\n                value={value}\n                allowClear\n                showSearch\n                filterOption={false}\n                disabled={disabled}\n                loading={optionsLoading}\n                // Single or multi is admin config (Form Groups → the field's\n                // \"Location selection\"). inferredSelectMode is the SAME resolver\n                // an ordinary select uses, so multiSelect / multiple / an array\n                // dataType all mean the same thing on a location field as they\n                // do everywhere else — and effectiveDataType already types a\n                // multiSelect field's payload as an array, so nothing extra is\n                // needed to store several locations.\n                mode={inferredSelectMode}\n                options={options}\n                placeholder={placeholder}\n                notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n                onSearch={setLocationSearch}\n                onFocus={() => setLocationSearch((current) => current)}\n                onChange={updateAndValidate}\n            />\n        );\n    }\n\n    if (type === 'select') {\n        const remoteLookup = field.dataSource === 'lookup';\n        const remoteMaster = field.dataSource === 'master';\n        const remoteSearch = remoteLookup || remoteMaster;\n        const keepLabel = usesLabeledSelectValue(field);\n        const rawControlValue = toSelectControlValue(field, value, options);\n        const controlValue = (allowCustomValues && !isArrayValued)\n            ? (rawControlValue === undefined || rawControlValue === null || rawControlValue === ''\n                ? undefined\n                : (Array.isArray(rawControlValue) ? rawControlValue : [rawControlValue]))\n            : rawControlValue;\n        const handleSelectChange = (raw) => {\n            // Unwrap \"tags\" mode's array back to the last entry for a\n            // single-valued field, so free entry never changes what is stored.\n            const val = (allowCustomValues && !isArrayValued && Array.isArray(raw))\n                ? (raw.length ? raw[raw.length - 1] : undefined)\n                : raw;\n            updateAndValidate(val);\n            // Same rule as the Add form (see components/form/clearGroupOnChange.js):\n            // changing this field invalidates the rest of its group, so those\n            // values are cleared before autofill writes the new selection's own.\n            if (field.clearGroupOnChange || field.linkedClearField) {\n                applyGroupClear(form, field, name, rowFieldKeys);\n            }\n            if (field.autofillFrom?.length) {\n                const selectedValue = val && !Array.isArray(val) && typeof val === 'object' ? val.value : val;\n                const isInsideList = Array.isArray(name) && name.length >= 3 && typeof name[1] === 'number';\n                if (val == null) {\n                    field.autofillFrom.forEach(({ targetField: tf }) => {\n                        const tp = isInsideList\n                            ? [...name.slice(0, 2), ...namePathFromString(tf)]\n                            : namePathFromString(tf);\n                        form.setFieldValue(tp, null);\n                    });\n                } else if (rawLookupRef.current.length > 0) {\n                    const vField = field.valueField ?? '_id';\n                    const rawItem = rawLookupRef.current.find(item =>\n                        getNestedProp(item, vField) === selectedValue || item._id === selectedValue || item.id === selectedValue || item.value === selectedValue\n                    );\n                    if (rawItem) {\n                        field.autofillFrom.forEach(({ optionKey, targetField: tf }) => {\n                            const v = getNestedProp(rawItem, optionKey) ?? rawItem.extraData?.[optionKey] ?? null;\n                            const tp = isInsideList\n                                ? [...name.slice(0, 2), ...namePathFromString(tf)]\n                                : namePathFromString(tf);\n                            form.setFieldValue(tp, v);\n                        });\n                    }\n                }\n            }\n        };\n        return (\n            <>\n                <Select value={controlValue} allowClear disabled={disabled} loading={optionsLoading}\n                    labelInValue={keepLabel || undefined}\n                    // Every select is type-to-search — see the matching comment\n                    // in AddFormV1. `field.showSearch: false` opts a field out.\n                    showSearch={field.showSearch !== false}\n                    optionFilterProp=\"label\"\n                    filterOption={remoteSearch ? false : undefined}\n                    mode={effectiveSelectMode} tokenSeparators={tokenSeparators}\n                    options={options} placeholder={placeholder}\n                    notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n                    onSearch={remoteLookup ? setLookupSearch : remoteMaster ? setMasterSearch : undefined}\n                    onChange={handleSelectChange}\n                    dropdownRender={quick.footer ? (menu) => (<>{menu}{quick.footer}</>) : undefined} />\n                {quick.modal}\n            </>\n        );\n    }\n\n    if (type === 'radio') {\n        return (\n            <Radio.Group value={value} disabled={disabled} options={options}\n                onChange={(e) => updateAndValidate(e.target.value)} />\n        );\n    }\n\n    if (type === 'checkbox') {\n        if (options.length > 0) {\n            return (\n                <Checkbox.Group value={value} disabled={disabled} options={options}\n                    onChange={updateAndValidate} />\n            );\n        }\n        return (\n            <Checkbox\n                checked={checked}\n                disabled={disabled}\n                onChange={(e) => {\n                    const next = e.target.checked;\n                    // Region gate — see AddFormV1. The tick is REVERSED rather\n                    // than left standing with an error underneath.\n                    if (next && onRegionBlocked?.(field)) return;\n                    updateAndValidate(next);\n                    // Ticking \"still ongoing\" makes this the most recent entry,\n                    // so it may now belong at the top of a newest-first list.\n                    if (next) onRowOrderChange?.(field, name);\n                    if (field.linkedClearField && next) {\n                        const clearPath = Array.isArray(name) && name.length > 1\n                            ? [...name.slice(0, -1), field.linkedClearField]\n                            : [field.linkedClearField];\n                        form.setFieldValue(clearPath, null);\n                    }\n                }}\n            >\n                {field.checkboxLabel ?? field.label}\n            </Checkbox>\n        );\n    }\n\n    if (type === 'text-editor') {\n        return (\n            <>\n                <TipTapEditor\n                    value={value ?? initialValue ?? ''}\n                    disabled={disabled}\n                    placeholder={placeholder}\n                    onChange={(html) => {\n                        if (validatorCfg) {\n                            const { error } = applyInputValidator(html, validatorCfg, 'change');\n                            setInputError(error);\n                        }\n                        updateAndValidate(html);\n                    }}\n                />\n                {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n            </>\n        );\n    }\n\n    if (type === 'textarea') {\n        return (\n            <>\n                <TextArea {...inputProps} rows={field.rows ?? 3} className=\"v1-scroll-textarea\" />\n                {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n            </>\n        );\n    }\n\n    if (type === 'date') {\n        return (\n            <DatePicker value={value} disabled={disabled} placeholder={placeholder}\n                style={{ width: '100%' }} suffixIcon={<CalendarOutlined />}\n                disabledDate={getDisabledDate(field, form, name)}\n                defaultPickerValue={getDefaultPickerValue(field)}\n                onChange={(date) => {\n                    updateAndValidate(date);\n                    // Dates are the other way a row becomes the most recent\n                    // one — the tick-box is not the only trigger.\n                    onRowOrderChange?.(field, name);\n                }} />\n        );\n    }\n\n    if (type === 'time') {\n        return (\n            <TimePicker value={value} disabled={disabled} placeholder={placeholder}\n                style={{ width: '100%' }} onChange={(time) => updateAndValidate(time)} />\n        );\n    }\n\n    if (type === 'file') {\n        const fileRules = field.validations ?? field.validation ?? field.rules ?? [];\n        const fileTypeRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'fileType');\n        const fileSizeRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'fileSize');\n        const maxFilesRule = fileRules.find((r) => (typeof r === 'string' ? r : r?.type) === 'maxFiles');\n\n        // Admin \"Allowed Content\" category (field.accept) takes priority over the\n        // fine-grained fileType rule; 'any'/unset falls through to the rule.\n        const acceptCategory = uploadAcceptCategory(field);\n        const acceptTypes = acceptCategory\n            ? acceptCategory.exts.map((e) => `.${e}`).join(',')\n            : (fileTypeRule?.value\n                ? fileTypeRule.value.split(',').map((e) => `.${e.trim().replace(/^\\./, '')}`).join(',')\n                : undefined);\n        const maxSizeMB = fileSizeRule ? Number(fileSizeRule?.value ?? 5) : undefined;\n        // maxFiles validation rule takes top priority; otherwise use field.multiple/maxCount\n        // (set via admin panel toggle), falling back to single-file mode.\n        const maxFiles = maxFilesRule\n            ? Number(maxFilesRule?.value ?? 1)\n            : (truthy(field.multiple) ? (field.maxCount ?? 5) : 1);\n\n        const fileList = Array.isArray(value) ? value : [];\n        const canAddMore = fileList.length < maxFiles;\n\n        const formatFileSize = (bytes) => {\n            if (!bytes) return '';\n            if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n            return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n        };\n\n        const getFileIcon = (fileName) => {\n            const ext = String(fileName ?? '').split('.').pop()?.toLowerCase();\n            if (ext === 'pdf') return <FilePdfOutlined className=\"v1-file-type-icon v1-file-icon-pdf\" />;\n            if (['doc', 'docx'].includes(ext)) return <FileWordOutlined className=\"v1-file-type-icon v1-file-icon-word\" />;\n            if (['xls', 'xlsx', 'csv'].includes(ext)) return <FileExcelOutlined className=\"v1-file-type-icon v1-file-icon-excel\" />;\n            if (['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'].includes(ext)) return <FileImageOutlined className=\"v1-file-type-icon v1-file-icon-image\" />;\n            return <FileOutlined className=\"v1-file-type-icon v1-file-icon-default\" />;\n        };\n\n        const handleFileDelete = (index) => {\n            updateAndValidate(fileList.filter((_, i) => i !== index));\n        };\n\n        const handleFileView = async (file, fileIdx) => {\n            // Newly selected (not-yet-saved) files are local browser Files and\n            // can be previewed with a blob URL. Existing files are stored in a\n            // private S3 bucket; rebuilding the raw bucket URL from\n            // resumeLocation/file location returns 403. Resolve those files\n            // through the common documents API first because it returns a\n            // temporary presigned `fileUrl`.\n            let registryDocuments = [];\n\n            const hasExistingFiles = fileList.some((f) => !(f?.originFileObj instanceof File));\n            if (hasExistingFiles && moduleName && recordId && field?.field) {\n                try {\n                    const response = await getModuleDocuments(moduleName, recordId, field.field);\n                    registryDocuments = Array.isArray(response?.data) ? response.data : [];\n                } catch (error) {\n                    // Keep the legacy URL as a fallback. This still allows public\n                    // files and locally-created blob URLs to preview normally.\n                    console.warn('Unable to resolve presigned document URL:', error);\n                }\n            }\n\n            const normalizedName = (value) => String(value ?? '')\n                .split('?')[0]\n                .split('#')[0]\n                .split('/')\n                .pop()\n                ?.toLowerCase() ?? '';\n\n            const docs = fileList.map((f, index) => {\n                const localFile = f?.originFileObj instanceof File;\n                if (localFile) {\n                    return {\n                        url: URL.createObjectURL(f.originFileObj),\n                        name: f.name ?? f.originFileObj.name ?? 'file',\n                        type: f.originFileObj.type || undefined,\n                    };\n                }\n\n                const currentName = normalizedName(\n                    f?.name ?? f?.fileName ?? f?.originalName ?? f?.url ?? f?.location,\n                );\n\n                // Prefer a filename match. For older document rows where the\n                // filename metadata differs/missing, fall back to the same index\n                // and finally to the first registry document for single-file\n                // fields such as Resume.\n                const signedDocument = registryDocuments.find((document) => {\n                    const registryName = normalizedName(\n                        document?.fileName\n                        ?? document?.name\n                        ?? document?.uploadedFileName\n                        ?? document?.originalName\n                        ?? document?.fileUrl\n                        ?? document?.url,\n                    );\n                    return currentName && registryName && currentName === registryName;\n                })\n                    ?? registryDocuments[index]\n                    ?? (fileList.length === 1 ? registryDocuments[0] : null);\n\n                let url = signedDocument?.fileUrl\n                    ?? signedDocument?.downloadUrl\n                    ?? signedDocument?.signedUrl\n                    ?? signedDocument?.url\n                    ?? f?.fileUrl\n                    ?? f?.downloadUrl\n                    ?? f?.signedUrl\n                    ?? f?.url\n                    ?? f?.thumbUrl\n                    ?? '';\n\n                // Only rebuild a storage path when no presigned URL exists. For\n                // private S3 this fallback may be forbidden, but keeping it here\n                // preserves support for installations whose bucket is public.\n                if (url && !url.startsWith('http') && !url.startsWith('blob:')) {\n                    url = buildFileUrl(url);\n                }\n\n                return {\n                    url,\n                    name: signedDocument?.fileName\n                        ?? signedDocument?.name\n                        ?? f?.name\n                        ?? 'file',\n                    type: signedDocument?.mimeType\n                        ?? signedDocument?.contentType\n                        ?? f?.type\n                        ?? undefined,\n                };\n            }).filter((document) => document.url);\n\n            if (!docs.length) {\n                message.error('Unable to resolve a preview URL for this document.');\n                return;\n            }\n\n            // If some invalid entries were filtered out, point at the selected\n            // document when possible without exceeding the resolved list.\n            const nextIndex = Math.min(fileIdx ?? 0, docs.length - 1);\n            setViewer({ open: true, docs, index: nextIndex });\n        };\n\n        const isMulti = maxFiles > 1;\n        const remaining = maxFiles - fileList.length;\n\n        const typeHint = acceptCategory\n            ? acceptCategory.hint\n            : (acceptTypes\n                ? acceptTypes.split(',').map((t) => t.replace('.', '').toUpperCase()).join(', ')\n                : null);\n        const sizeHint = maxSizeMB ? `up to ${maxSizeMB} MB` : null;\n        const baseHint = [typeHint, sizeHint].filter(Boolean).join(' ');\n        const dropHint = isMulti && fileList.length > 0\n            ? [baseHint, `${remaining} of ${maxFiles} remaining`].filter(Boolean).join(' • ')\n            : baseHint;\n        const dropTitle = fileList.length > 0\n            ? `Add ${isMulti ? 'more files' : 'file'}`\n            : (field.buttonLabel ?? `Upload ${field.label ?? 'File'}`);\n\n        const beforeUploadHandler = (file) => {\n            if (fileList.length >= maxFiles) return Upload.LIST_IGNORE;\n            if (acceptTypes) {\n                const ext = (file.name.split('.').pop() ?? '').toLowerCase();\n                const allowed = acceptTypes.split(',').map((t) => t.replace(/^\\./, '').toLowerCase());\n                if (!allowed.includes(ext)) {\n                    message.error(acceptCategory\n                        ? acceptCategory.error\n                        : (fileTypeRule?.message ?? `Only ${fileTypeRule.value} files are allowed`));\n                    return Upload.LIST_IGNORE;\n                }\n            }\n            if (maxSizeMB !== undefined && file.size / 1024 / 1024 > maxSizeMB) {\n                message.error(fileSizeRule?.message ?? `File must be smaller than ${maxSizeMB} MB`);\n                return Upload.LIST_IGNORE;\n            }\n            return false;\n        };\n\n        // antd calls onChange once per file even in multi-select, each time with the\n        // full accumulated newList. Slicing to maxFiles guards against racing additions.\n        const handleUploadChange = ({ fileList: newList }) => {\n            const sliced = newList.slice(0, maxFiles);\n            updateAndValidate(sliced);\n            // An \"upload\"-trigger AI action (e.g. auto-parse a resume) fires once\n            // per newly-added file, using the raw browser File object.\n            if (onAiUpload && sliced.length > fileList.length) {\n                const added = sliced[sliced.length - 1];\n                if (added?.originFileObj) onAiUpload(added.originFileObj);\n            }\n        };\n\n        const multiUploadProps = {\n            accept: acceptTypes,\n            fileList,\n            showUploadList: false,\n            multiple: true,\n            maxCount: maxFiles,\n            beforeUpload: beforeUploadHandler,\n            onChange: handleUploadChange,\n            disabled,\n        };\n\n        const fileRows = fileList.map((file, index) => (\n            <div key={file.uid ?? index} className=\"v1-file-item\">\n                <div className=\"v1-file-item-icon\">{getFileIcon(file.name)}</div>\n                <div className=\"v1-file-item-info\">\n                    <span className=\"v1-file-item-name\" title={file.name}>{file.name}</span>\n                    <span className=\"v1-file-item-meta\">\n                        {file.existing\n                            ? 'Previously uploaded'\n                            : `${formatFileSize(file.size)}${file.size ? ' • ' : ''}Uploaded just now`}\n                    </span>\n                </div>\n                <Space size={6} className=\"v1-file-item-actions\">\n                    <Button\n                        size=\"small\"\n                        icon={<EyeOutlined />}\n                        onClick={() => handleFileView(file, index)}\n                        className=\"v1-file-view-btn\"\n                    >\n                        View\n                    </Button>\n                    <Button\n                        size=\"small\"\n                        danger\n                        icon={<DeleteOutlined />}\n                        onClick={() => handleFileDelete(index)}\n                        className=\"v1-file-delete-btn\"\n                    />\n                </Space>\n            </div>\n        ));\n\n        const viewerEl = (\n            <DocumentViewer\n                documents={viewer.docs}\n                open={viewer.open}\n                onClose={() => setViewer(v => ({ ...v, open: false }))}\n                initialIndex={viewer.index}\n            />\n        );\n\n        if (isMulti) {\n            const multiTitle = fileList.length > 0\n                ? `Upload more ${field.label ?? 'files'}`\n                : (field.buttonLabel ?? `Upload ${field.label ?? 'File'}`);\n\n            return (\n                <>\n                    <div className=\"v1-file-upload-wrapper\">\n                        {/* Centered dropzone — always at top in multiple mode */}\n                        {canAddMore && (\n                            <Upload {...multiUploadProps} style={{ width: '100%', display: 'block' }}>\n                                <div className={`v1-upload-dropzone v1-upload-dropzone-center${disabled ? ' v1-upload-dropzone-disabled' : ''}`}>\n                                    <div className=\"v1-upload-dropzone-title-row\">\n                                        <CloudUploadOutlined className=\"v1-upload-cloud-icon v1-upload-cloud-icon-sm\" />\n                                        <span className=\"v1-upload-dropzone-title v1-upload-dropzone-title-blue\">{multiTitle}</span>\n                                    </div>\n                                    <span className=\"v1-upload-dropzone-sub\">Drag & drop or click to upload</span>\n                                    {baseHint && <span className=\"v1-upload-dropzone-sub\">{baseHint}</span>}\n                                </div>\n                            </Upload>\n                        )}\n\n                        {/* Uploaded file rows — 2-column grid */}\n                        {fileList.length > 0 && (\n                            <div className=\"v1-file-grid\">\n                                {fileRows}\n                            </div>\n                        )}\n\n                        {/* \"+ Add more files\" text link at the bottom */}\n                        {canAddMore && fileList.length > 0 && (\n                            <Upload {...multiUploadProps} style={{ display: 'inline-block' }}>\n                                <Button type=\"link\" size=\"small\" icon={<PlusOutlined />} className=\"v1-add-more-files-btn\">\n                                    Add more files\n                                </Button>\n                            </Upload>\n                        )}\n                    </div>\n                    {viewerEl}\n                </>\n            );\n        }\n\n        return (\n            <>\n                <div className=\"v1-file-upload-wrapper\">\n                    {/* Single mode: compact file row at field height */}\n                    {fileList.length > 0 && <div className=\"v1-file-rows-single\">{fileRows}</div>}\n\n                    {canAddMore && (\n                        <Upload\n                            accept={acceptTypes}\n                            fileList={fileList}\n                            showUploadList={false}\n                            multiple={false}\n                            maxCount={1}\n                            beforeUpload={beforeUploadHandler}\n                            onChange={handleUploadChange}\n                            disabled={disabled}\n                            style={{ width: '100%', display: 'block' }}\n                        >\n                            <div className={`v1-upload-dropzone v1-upload-dropzone-single${disabled ? ' v1-upload-dropzone-disabled' : ''}`}>\n                                <CloudUploadOutlined className=\"v1-upload-cloud-icon\" />\n                                <span className=\"v1-upload-dropzone-title\">{dropTitle}</span>\n                                {dropHint && <span className=\"v1-upload-dropzone-sub\">— {dropHint}</span>}\n                            </div>\n                        </Upload>\n                    )}\n                </div>\n                {viewerEl}\n            </>\n        );\n    }\n\n    return (\n        <>\n            <Input\n                {...inputProps}\n                type={type === 'number' ? 'number' : type}\n                // step=\"any\" so the browser's own number input accepts a\n                // fractional value on a field the admin marked decimal.\n                {...(type === 'number' && truthy(field.decimal) ? { step: 'any' } : {})}\n                // Admin-configured unit shown inside the input (e.g. \"%\").\n                {...(field.suffix ? { suffix: field.suffix } : {})}\n            />\n            {inputError && <div className=\"v1-input-validator-hint\">{inputError}</div>}\n        </>\n    );\n}\n\n// ─── SectionTitle ─────────────────────────────────────────────────────────────\n\nfunction SectionTitle({ icon, title }) {\n    return (\n        <Space size={10} align=\"center\">\n            <div className=\"v1-section-icon-box\">{icon}</div>\n            <Text strong className=\"v1-section-label\">{title}</Text>\n        </Space>\n    );\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\n\n// renderFieldHelp — the guidance under a field.\n//\n// `helpText` accepts a STRING or an ARRAY of strings. An array renders as\n// stacked lines, which is what lets one field carry two different KINDS of\n// help without them running together: the mechanical constraint (\"Supports\n// .pdf, .doc, .docx up to 2MB\") and the reason to bother (\"Upload the résumé\n// first — we can read the details straight out of it\"). Jammed into one\n// paragraph they read as a wall and the second half is skipped.\n//\n// A plain string keeps rendering exactly as before, so nothing existing moves.\nfunction renderFieldHelp(field) {\n    const raw = field?.helpText;\n    const lines = (Array.isArray(raw) ? raw : [raw])\n        .map((line) => (line == null ? '' : String(line).trim()))\n        .filter(Boolean);\n    if (!lines.length) return undefined;\n    return (\n        <span className=\"v1-field-help-text\">\n            {lines.map((line, i) => (\n                <Text key={i} type=\"secondary\" className=\"v1-field-help-line\">{line}</Text>\n            ))}\n        </span>\n    );\n}\n\nexport default function EditFormV1({\n    moduleName,\n    groupName,\n    recordId,\n    authToken,\n    clientId,\n    region,\n    breadcrumbItems = [],\n    submitText = 'Update',\n    cancelPath,\n    onSuccess,\n    // fieldNameMap: rename keys before sending to API\n    // e.g. { mspReqId: 'mspreqId' }\n    // Once backend standardises field names this prop can be removed\n    fieldNameMap = {},\n    // onFileUpload: (fieldName, file, recordId) => Promise\n    // Handle multipart file uploads per module outside this component\n    onFileUpload = null,\n    // onBeforeSubmit: async (values) => boolean — called after validation but\n    // BEFORE anything is saved. Return false (or resolve false) to abort the\n    // save silently — e.g. a page that shows a preview/confirmation modal and\n    // resumes the save only when the user confirms (Submission resubmit flow).\n    onBeforeSubmit = null,\n    // extraPayload — extra keys merged into the update payload on top of the\n    // form values (mirrors AddFormV1's prop). Dotted keys become partial Mongo\n    // updates — e.g. the resubmit page stamps the new internal status without\n    // wiping the rest of the status object.\n    extraPayload = null,\n    // embedded / onCancel — render inside a quick \"Add More\"/\"Edit\" modal. When\n    // embedded, onSuccess(recordId, values) is called after a successful save and\n    // no navigation happens; the Cancel button calls onCancel. Page path unchanged.\n    embedded = false,\n    onCancel = null,\n}) {\n    const navigate = useNavigate();\n    const location = useLocation();\n\n    const [form] = Form.useForm();\n    useEffect(() => {\n        if (authToken) setAuthTokenOverride(authToken);\n        return () => {\n            if (authToken) clearAuthTokenOverride();\n        };\n    }, [authToken]);\n\n    const [collapsed, setCollapsed] = useState({});\n    const [formGroups, setFormGroups] = useState([]);\n    // ── Central documents (the shared `documents` collection) ────────────────\n    // A file is stored in TWO places, and for some modules only ONE of them.\n    // The record may carry an inline container (passport.passportCopyLocation,\n    // …), but an upload is ALSO registered in the shared documents collection —\n    // and for jobs it is registered ONLY there: every job in the database holds\n    // `jobAttachments: []` while its real files sit in `documents` keyed by\n    // module + moduleRefId.\n    //\n    // The DETAIL view has always merged both (see DetailViewV1's centralDocs).\n    // The edit form never read the registry at all, so a document that lives\n    // only there was invisible here — the field rendered empty on a record that\n    // demonstrably has files, which is the \"job document does not show in the\n    // edit form\" report. Worse than cosmetic: saving from that state looks like\n    // the user removed a file they were never shown.\n    //\n    // Fetched with the SAME call the detail view makes, so the two can never\n    // disagree about what a record has.\n    const [centralDocs, setCentralDocs] = useState([]);\n    useEffect(() => {\n        if (!moduleName || !recordId) { setCentralDocs([]); return undefined; }\n        let cancelled = false;\n        getModuleDocuments(moduleName, recordId)\n            .then((docs) => {\n                if (cancelled) return;\n                setCentralDocs(Array.isArray(docs) ? docs : (docs?.data ?? []));\n            })\n            // Best effort: a registry that will not load must not stop the record\n            // being edited — the inline values still render.\n            .catch(() => { if (!cancelled) setCentralDocs([]); });\n        return () => { cancelled = true; };\n    }, [moduleName, recordId]);\n    const [loading, setLoading] = useState(false);\n    const [error, setError] = useState('');\n    const [submitting, setSubmitting] = useState(false);\n    const [submitError, setSubmitError] = useState('');\n    // Role Configure → Form permissions for the CURRENT user's role, derived\n    // server-side from this module's Form Groups config. null until loaded /\n    // when unavailable, in which case normalizeGroups' rolePerms checks fail\n    // open — no behavior change for a role/module that hasn't been configured.\n    const [rolePerms, setRolePerms] = useState(null);\n    const [defaultFieldSet, setDefaultFieldSet] = useState(() => new Set());\n\n    // ── Client-scoped edit render ────────────────────────────────────────────\n    // The counterpart of AddFormV1's job→client resolution: a record created\n    // under a client's Form Groups variant must be EDITED with that same\n    // variant. The record's own client is discovered from the first fetch\n    // (getFormGroups rides `recordMeta` — { clientId, jobId } — along on the\n    // groups array), then the config is refetched under that client scope.\n    // Self-stabilising: the second pass resolves the same client and stops.\n    const [resolvedClientId, setResolvedClientId] = useState('');\n    const effectiveClientId = clientId || resolvedClientId;\n    // The record's own linkage ids (recordMeta), used by the cross-module\n    // carrier prefill below.\n    const [recordMeta, setRecordMeta] = useState({});\n\n    // Load common display defaults (phone/date format) once so phone fields\n    // re-format to the admin-configured mask on edit too.\n    useEffect(() => { loadDetailDefaults(); }, []);\n\n    useEffect(() => {\n        let cancelled = false;\n        queueMicrotask(() => {\n            if (cancelled) return;\n            if (!moduleName) { setRolePerms(null); return; }\n            // Same client/region scope the form's own structure is fetched\n            // with (getFormGroups above) — a client-scoped Form Groups\n            // override must gate the SAME scoped structure, not the\n            // tenant-wide default.\n            getRoleFormPermissions({ roleId: localStorage.getItem('roleId') }, moduleName, { clientId: effectiveClientId, region })\n                .then((data) => { if (!cancelled) setRolePerms(Array.isArray(data) && data.length ? data : null); })\n                .catch(() => { if (!cancelled) setRolePerms(null); });\n        });\n        return () => { cancelled = true; };\n    }, [moduleName, effectiveClientId, region]);\n\n    useEffect(() => {\n        let cancelled = false;\n        queueMicrotask(() => {\n            if (cancelled) return;\n            if (!moduleName) { setDefaultFieldSet(new Set()); return; }\n            getModuleDefaultFields(moduleName)\n                .then((keys) => { if (!cancelled) setDefaultFieldSet(new Set(Array.isArray(keys) ? keys : [])); })\n                .catch(() => { if (!cancelled) setDefaultFieldSet(new Set()); });\n        });\n        return () => { cancelled = true; };\n    }, [moduleName]);\n\n    const groups = useMemo(() => normalizeGroups(formGroups, moduleName, rolePerms, defaultFieldSet), [formGroups, moduleName, rolePerms, defaultFieldSet]);\n\n\n    // ── Newest-first row ordering ───────────────────────────────────────────\n    // After the user changes a row's dates or ticks \"still ongoing\", check\n    // whether that row now belongs somewhere else and ASK. Nothing is ever\n    // reordered silently — a list that rearranges itself while you are typing\n    // in it is disorienting, and the user may have a reason for the order.\n    const handleRowOrder = useCallback(async (field, name) => {\n        // Only meaningful inside a repeatable group: [listName, rowIndex, key].\n        if (!Array.isArray(name) || name.length < 3 || typeof name[1] !== 'number') return;\n        const groupName = name[0];\n        const rowIndex = name[1];\n\n        const group = groups.find((g) => g.name === groupName);\n        if (!group) return;\n        // Region-resolved, so a market that reorders differently is honoured.\n        const effective = resolveRegionRules(group, getDefaults().region);\n        if (!effective.orderBy) return;\n\n        // Read AFTER the change has landed in the store, so the row being\n        // judged carries the value the user just set rather than the previous\n        // one — the whole decision turns on that value.\n        await Promise.resolve();\n        const rows = form.getFieldValue(groupName);\n        if (!Array.isArray(rows)) return;\n\n        await promptRowMove({\n            group: effective,\n            rows,\n            rowIndex,\n            move: listControlsRef.current[groupName]?.move,\n            confirm: ({ title, body, okText, cancelText, from, to }) => openFormDecision({\n                tone: 'suggestion',\n                title,\n                facts: [\n                    { label: 'This entry is at', value: `Row ${from + 1}` },\n                    { label: 'It belongs at', value: `Row ${to + 1}` },\n                ],\n                body,\n                okText,\n                cancelText,\n            }),\n        });\n    }, [groups, form]);\n\n    // ── Region gate ─────────────────────────────────────────────────────────\n    // Identical rule to the Add form: some markets do not accept an entry that\n    // is still in progress, and the region (Admin → Display Defaults) selects\n    // which `regionRules` block the group applies. Reversing the tick beats\n    // leaving it standing with an error underneath — the latter invites the\n    // user to submit and be refused twice.\n    const handleRegionBlocked = useCallback((field) => {\n        const region = getDefaults().region;\n        const group = groups.find((g) => (g.fields ?? []).some((f) => f.field === field.field));\n        if (!group) return false;\n\n        const effective = resolveRegionRules(group, region);\n        const ongoingField = effective.orderBy?.inProgressField ?? 'currentStudyingHere';\n        if (field.field !== ongoingField) return false;\n        if (inProgressAllowed(effective)) return false;\n\n        // Warn vs block. A warning explains the consequence and lets the tick\n        // stand — recording a real person mid-degree is worth doing even where\n        // they could not be put forward today. A block reverses the tick, and\n        // the submit-time validator below refuses the row however it arrived.\n        const blocking = inProgressBlocks(effective);\n        openFormNotice({\n            tone: blocking ? 'duplicate' : 'overwrite',\n            title: blocking\n                ? 'This has to be completed first'\n                // States the CONSEQUENCE, not a vague heading. The user's next\n                // action depends on knowing that saving this is fine but\n                // submitting them later will not be.\n                : 'You can add this, but they cannot be submitted',\n            facts: [\n                { label: 'Region', value: region || 'Common' },\n                { label: 'Entry', value: group.label ?? group.name },\n            ],\n            body: inProgressError(effective),\n            okText: blocking ? 'Got it' : 'Keep it anyway',\n        });\n        return blocking;\n    }, [groups]);\n\n    // ── The submit-time half of the same rule ───────────────────────────────\n    // Reversing the tick-box only catches a row somebody ticked BY HAND. A\n    // submission prefills its rows from the candidate, and the candidate is\n    // allowed to hold an in-progress entry — so on a blocking region the row\n    // arrives already ticked and nobody ever touched the box. Without a rule on\n    // the field the form would happily submit it, and the restriction would\n    // apply to exactly the users who did not need stopping.\n    //\n    // Resolved here rather than inside getRules because it depends on the\n    // GROUP, which getRules never sees.\n    const inProgressRulesFor = useCallback((field, groupName) => {\n        const group = groups.find((g) => g.name === groupName);\n        if (!group) return undefined;\n        const effective = resolveRegionRules(group, getDefaults().region);\n        const ongoingField = effective.orderBy?.inProgressField ?? 'currentStudyingHere';\n        if (field.field !== ongoingField) return undefined;\n        const rule = buildInProgressValidator(effective);\n        return rule ? [rule] : undefined;\n    }, [groups]);\n\n    // ── Config-driven field uniqueness ──────────────────────────────────────\n    // One checker per form session owns the request sequence, the\n    // normalized-value cache and the pending count (see\n    // form/uniqueFieldValidation.js). While a check is in flight the Update\n    // button is disabled so a save can never race an unanswered check.\n    const [uniquePending, setUniquePending] = useState(0);\n    const uniqueChecker = useMemo(\n        () => createUniqueChecker({ checkFieldUnique, onPendingChange: setUniquePending }),\n        [],\n    );\n    // recordId is what makes the edit semantics work: the server excludes this\n    // record, so re-saving an unchanged value (or one that differs only in case\n    // or surrounding whitespace) is not a duplicate of itself.\n    const uniqueContext = useMemo(() => ({\n        checker: uniqueChecker,\n        module: moduleName,\n        recordId,\n        clientId: effectiveClientId || undefined,\n        region: region || undefined,\n    }), [uniqueChecker, moduleName, recordId, effectiveClientId, region]);\n    // Every unique-configured field in this form, used to map a submit-time\n    // duplicate back onto its field when the response body was flattened.\n    const uniqueRuleIndex = useMemo(() => collectUniqueRules(groups), [groups]);\n    // group.linkGroup — addRow groups sharing the same value stay row-synced\n    // (see form/linkedAddRowGroups.js). Empty for every group with no\n    // linkGroup, i.e. every group that predates this feature.\n    const linkedGroupSets = useMemo(() => computeLinkedSets(groups), [groups]);\n    // Registry of each addRow group's live Form.List {add, remove}, written on\n    // every render from inside the Form.List's own render-prop (synchronous\n    // within the same commit, so it's fully populated before a user can click\n    // anything). A linked group's \"Add Row\" / row-delete calls every member's\n    // add()/remove() through this registry; unlinked groups just call their own.\n    const listControlsRef = useRef({});\n    const aiActions = useAiActions({ form, groups, module: moduleName });\n\n    // Per-addRow-group Form.List initialValue (one row object per backend-embedded\n    // stored row). Computed from the same groups the form renders, so it is ready\n    // the moment each Form.List mounts. Linked groups are then padded to equal\n    // length (see padLinkedInitialValues) — a no-op for every unlinked group.\n    const addRowInitials = useMemo(() => {\n        const out = {};\n        groups.forEach((group) => {\n            if (group.addRow) out[group.name] = buildAddRowInitial(group);\n        });\n        return padLinkedInitialValues(linkedGroupSets, out);\n    }, [groups, linkedGroupSets]);\n\n    const MODULE_LABELS = {\n        jobs: { list: 'Jobs', path: '/jobs', edit: 'Edit Job' },\n        candidates: { list: 'Candidates', path: '/candidates', edit: 'Edit Candidate' },\n        submissions: { list: 'Submissions', path: '/submissions', edit: 'Edit Submission' },\n    };\n\n    const resolvedBreadcrumbs = embedded\n        ? []\n        : breadcrumbItems.length > 0\n        ? breadcrumbItems\n        : (() => {\n            const config = MODULE_LABELS[normalizeModule(moduleName)];\n            if (!config) return [];\n            return [\n                { label: 'Home', href: '/' },\n                { label: config.list, href: config.path },\n                { label: config.edit },\n            ];\n        })();\n\n\n    // ── Fetch form config + record ──────────────────────────────────────────\n\n    useEffect(() => {\n        if (!moduleName || !recordId) return undefined;\n\n        let cancelled = false;\n\n        async function fetchData() {\n            try {\n                setLoading(true);\n                setError('');\n                setSubmitError('');\n\n                // Single source of truth: the form-groups config with `id` embeds\n                // each field's current value (field.value). No separate detail-view\n                // fetch — prefill reads field.value only.\n                const groupsResponse = await getFormGroups({ module: moduleName, id: recordId, clientId: effectiveClientId, region, group: groupName });\n\n                if (cancelled) return;\n\n                setFormGroups(Array.isArray(groupsResponse) ? groupsResponse : []);\n                // recordMeta = every top-level \"*Id\" of the record (jobId,\n                // applicantId, clientId, …). It is the edit-side counterpart of\n                // AddFormV1's URL linkage, and it is what lets a cross-module\n                // carrier field find its source record here (see below).\n                setRecordMeta(groupsResponse?.recordMeta ?? {});\n\n                // Resolve this record's client and, if it differs from the scope\n                // we just fetched under, refetch so the edit form matches the\n                // client variant the add form rendered. Only when the caller did\n                // not pin a client explicitly.\n                if (!clientId) {\n                    const meta = groupsResponse?.recordMeta ?? {};\n                    const idOf = (v) => (v && typeof v === 'object' ? (v.id ?? v.value ?? '') : (v ?? ''));\n                    let recClient = String(idOf(meta.clientId) || '');\n                    // Submissions denormalize clientId, but fall back to the job.\n                    const jobId = String(idOf(meta.jobId) || '');\n                    if (!recClient && jobId) {\n                        try {\n                            const jobGroups = await getFormGroups({ module: 'jobs', id: jobId });\n                            recClient = String(idOf(jobGroups?.recordMeta?.clientId) || '');\n                        } catch { /* keep the default scope */ }\n                    }\n                    if (!cancelled && recClient && recClient !== resolvedClientId) {\n                        setResolvedClientId(recClient);\n                    }\n                }\n            } catch (err) {\n                console.error(`Failed to fetch ${moduleName} edit data:`, err);\n                if (!cancelled) setError(err?.message || 'Failed to load record');\n            } finally {\n                if (!cancelled) setLoading(false);\n            }\n        }\n\n        fetchData();\n        return () => { cancelled = true; };\n    }, [moduleName, groupName, recordId, clientId, effectiveClientId, resolvedClientId, region]);\n\n    // ── Prefill form ────────────────────────────────────────────────────────\n    //\n    // Single source of truth: each field's `field.value`, embedded by getFormGroups\n    // when an `id` is passed. Shaped and applied via the shared applyGroupValues\n    // module, the same code an AI Action's response is applied through.\n\n    useEffect(() => {\n        if (loading || groups.length === 0) return;\n        applyScalarFieldValues(form, groups);\n    }, [loading, groups, form]);\n\n    // Seed file fields from the central documents registry — see the centralDocs\n    // fetch above for WHY (for jobs the registry is the only place the file\n    // exists). Runs AFTER applyScalarFieldValues so the record's own inline\n    // value always wins: a field that already shows its file must not be\n    // rewritten from the registry, or a freshly re-uploaded document could be\n    // replaced by an older registry row.\n    //\n    // Matching mirrors the detail view exactly: a document is filed under the\n    // field's own key OR its fileKey (uploads register under the multipart part\n    // name, so a `jobAttachments` field's document is stored as \"file\").\n    useEffect(() => {\n        if (loading || groups.length === 0 || centralDocs.length === 0) return;\n\n        const byField = new Map();\n        centralDocs.forEach((doc) => {\n            const key = doc?.fieldName || doc?.field;\n            if (!key) return;\n            if (!byField.has(key)) byField.set(key, []);\n            byField.get(key).push(doc);\n        });\n\n        const values = {};\n        let wrote = false;\n        groups.forEach((group) => {\n            if (truthy(group.addRow)) return;\n            (group.fields ?? []).forEach((field) => {\n                if (!field?.field || !isUploadField(field)) return;\n                const existing = form.getFieldValue(namePathFromString(field.field));\n                if (Array.isArray(existing) ? existing.length > 0 : !empty(existing)) return;\n                const docs = byField.get(field.field) ?? (field.fileKey ? byField.get(field.fileKey) : null);\n                if (!docs?.length) return;\n                // Newest first — the API already sorts that way; a single-file\n                // field shows the current document, not its whole history.\n                const capacity = truthy(field.multiple) ? Number(field.maxCount ?? 5) : 1;\n                writeFormValue(values, field.field, docs.slice(0, capacity).map((doc) => ({\n                    uid: String(doc._id ?? doc.s3Key ?? doc.fileName),\n                    name: doc.fileName ?? doc.uniqueName ?? 'file',\n                    status: 'done',\n                    url: doc.fileUrl ?? doc.s3Key ?? '',\n                    existing: true,\n                    // The untouched registry row, so a save that does not\n                    // re-upload can write the same reference straight back\n                    // instead of guessing at the stored shape.\n                    stored: doc,\n                })));\n                wrote = true;\n            });\n        });\n        if (wrote) form.setFieldsValue(values);\n    }, [loading, groups, centralDocs, form]);\n\n    // ── Files carried in from another form ──────────────────────────────────\n    //\n    // Someone starts adding a candidate, uploads a résumé, and we tell them the\n    // person is already on file and send them here. The file has to come WITH\n    // them: they picked that résumé for that person, and adding it to the\n    // existing record is the entire reason they accepted the redirect. Dropping\n    // it would make them find and attach it again.\n    //\n    // Runs AFTER the record's own values are applied, so the carried file wins\n    // over whatever is currently stored — that is the newer document, and file\n    // versioning keeps the previous one rather than replacing it.\n    const carriedFiles = location.state?.carryFiles;\n    useEffect(() => {\n        if (loading || !carriedFiles) return;\n        const entries = Object.entries(carriedFiles)\n            .filter(([, list]) => Array.isArray(list) && list.length > 0);\n        if (!entries.length) return;\n        form.setFieldsValue(Object.fromEntries(entries));\n        message.info('The résumé you uploaded has been attached here — save to keep it.');\n        // Consumed once: a refresh or a Back must not silently re-attach a file\n        // the user has since removed.\n        navigate(location.pathname + location.search, {\n            replace: true,\n            state: { ...(location.state ?? {}), carryFiles: null },\n        });\n    }, [loading, carriedFiles, form, navigate, location.pathname, location.search, location.state]);\n\n    // ── Cross-module CARRIER prefill (field.prefillFromModule) ───────────────\n    //\n    // AddFormV1 fills prefillFromModule fields from the URL linkage (?jobId=).\n    // On edit there is no such linkage — but the record itself stores its ids,\n    // and getFormGroups surfaces them as recordMeta. So the SAME config pair\n    // (prefillFromModule + prefillFrom) resolves here too.\n    //\n    // Scope: only NON-PERSISTENT carriers (payloadMode \"skip\", see\n    // form/contextPrefill.js). A carrier is never written to the record, so a\n    // validation that leans on it (e.g. \"rate must not exceed the job's client\n    // rate\") would be silently INERT on edit unless it is re-derived here.\n    // Stored fields are deliberately left alone: re-pulling the source module's\n    // current value on edit would overwrite what the user saved.\n    const carrierModules = useMemo(\n        () => contextPrefillModules(\n            groups.map((g) => ({ ...g, fields: (g.fields ?? []).filter(isNonPersistentCarrier) })),\n            normalizeModule,\n        ),\n        [groups],\n    );\n\n    const [carrierRecords, setCarrierRecords] = useState({});\n    useEffect(() => {\n        if (carrierModules.length === 0) return undefined;\n        let cancelled = false;\n        carrierModules.forEach(async (mod) => {\n            const id = contextRecordId(mod, recordMeta);\n            if (!id) return;\n            try {\n                const data = await getFormGroups({ module: mod, id });\n                const record = flattenContextRecord(extractContextGroups(data));\n                if (!cancelled && Object.keys(record).length > 0) {\n                    setCarrierRecords((prev) => ({ ...prev, [mod]: record }));\n                }\n            } catch (err) {\n                // Fail open: a carrier that can't be resolved simply leaves its\n                // rule without a ceiling, exactly like a form with no linkage.\n                console.error(`Carrier prefill fetch failed for ${mod}:`, err);\n            }\n        });\n        return () => { cancelled = true; };\n    }, [carrierModules, recordMeta]);\n\n    useEffect(() => {\n        if (loading || groups.length === 0 || Object.keys(carrierRecords).length === 0) return;\n        const values = {};\n        let wrote = false;\n        groups.forEach((group) => (group.fields ?? []).forEach((field) => {\n            if (!field.field || !field.prefillFromModule || !isNonPersistentCarrier(field)) return;\n            const source = carrierRecords[normalizeModule(field.prefillFromModule)];\n            const stored = pickContextValue(source, field);\n            if (stored === undefined || stored === null) return;\n            // writeFormValue, not values[field.field]: a dotted key registers as\n            // an ARRAY name path, so a flat dotted object key is a name nothing\n            // listens on (the bug that made prefillFromModule silently do\n            // nothing for nested fields on the add form).\n            writeFormValue(values, field.field, stored);\n            wrote = true;\n        }));\n        if (wrote) form.setFieldsValue(values);\n    }, [carrierRecords, loading, groups, form]);\n\n    // ── Collapse toggle ─────────────────────────────────────────────────────\n\n    const toggle = (key) => {\n        setCollapsed((prev) => ({ ...prev, [key]: !prev[key] }));\n    };\n\n\n    // ── Collapsible sections (group.allowCollapse / group.defaultCollapsed) ──\n    // Collapsing is OPT-IN. A group that does not ask for it renders with no\n    // chevron and can never be collapsed — which is the behaviour every form\n    // had before this existed, so nothing already configured changes.\n    //\n    // `defaultCollapsed` only means anything for a group that allows collapsing\n    // at all: a section that starts closed but cannot be opened would be a\n    // section the user simply cannot fill in.\n    //\n    // Seeded once per group set rather than on every render, so a user who\n    // opens a default-closed section does not have it slam shut again on the\n    // next state change. `collapsedSeeded` tracks WHICH group set has been\n    // applied, so a module switch (or a config reload) re-seeds exactly once.\n    const collapsedSeedKey = useMemo(\n        () => groups.map((g) => `${g.name}:${truthy(g.allowCollapse) ? 1 : 0}${truthy(g.defaultCollapsed) ? 1 : 0}`).join('|'),\n        [groups],\n    );\n    const collapsedSeeded = useRef(null);\n    useEffect(() => {\n        if (!groups.length || collapsedSeeded.current === collapsedSeedKey) return;\n        collapsedSeeded.current = collapsedSeedKey;\n        const seeded = {};\n        groups.forEach((group, index) => {\n            const key = group.name ?? group.id ?? String(index);\n            if (truthy(group.allowCollapse) && truthy(group.defaultCollapsed)) seeded[key] = true;\n        });\n        setCollapsed(seeded);\n    }, [collapsedSeedKey, groups]);\n\n    // ── Payload builder — the SAME config-driven engine AddFormV1 uses ──────────\n    //\n    // No field-name / module-specific logic. The engine:\n    //   • starts from the untouched record (base) so unedited fields are preserved\n    //   • applies each field's payloadKey / dataType / payloadMode / template\n    //   • skips file fields (uploaded separately via onFileUpload)\n    //\n    // fieldNameMap is an optional caller-provided rename map kept for backward\n    // compatibility; new renames should use the field's payloadKey config instead.\n    function buildPayload(values) {\n        // No base record: every editable value comes from the form (prefilled from\n        // getFormGroups field.value). The payload carries only the configured fields.\n        const payload = buildConfigPayload(values, groups, { module: moduleName });\n\n        Object.entries(fieldNameMap).forEach(([from, to]) => {\n            if (payload[from] !== undefined) {\n                payload[to] = payload[from];\n                delete payload[from];\n            }\n        });\n\n        return payload;\n    }\n\n    // ── Submit ──────────────────────────────────────────────────────────────\n\n    async function submit(values) {\n        // Pre-submit gate (see onBeforeSubmit prop). Runs before the spinner so\n        // an aborted save leaves the form fully interactive.\n        if (onBeforeSubmit) {\n            const proceed = await Promise.resolve()\n                .then(() => onBeforeSubmit(values))\n                .catch(() => false);\n            if (proceed === false) return;\n        }\n        try {\n            setSubmitting(true);\n            setSubmitError('');\n\n            // New files ride along in the SAME module/update multipart, exactly\n            // like create — config-driven fileKey (jobs → \"file\", candidates →\n            // resume/passport/documents/…). The downstream update handler stores\n            // them and returns name/location. This replaces the old per-module\n            // onFileUpload endpoints (which pointed candidate edits at the jobs\n            // attachment URL). onFileUpload is still honoured as an optional\n            // override when a module needs bespoke upload handling.\n            // Indexed keys (documents[0], documents[1], …) so the update handler\n            // can align each new file to its metadata row by position. Create uses\n            // flat keys; only update needs indexing.\n            const fileParts = collectFileParts(values, groups, { indexed: true, module: moduleName });\n\n            if (onFileUpload && onFileUpload.useLegacyUpload) {\n                const fileFieldDefs = groups\n                    .flatMap((g) => g.fields ?? [])\n                    .filter(isUploadField);\n                for (const field of fileFieldDefs) {\n                    const list = values[field.field];\n                    if (!Array.isArray(list)) continue;\n                    const newFiles = list.filter((f) => f.originFileObj instanceof File);\n                    try {\n                        await Promise.all(\n                            newFiles.map((f) => onFileUpload(field.field, f.originFileObj, recordId)),\n                        );\n                    } catch (uploadErr) {\n                        console.warn('File upload failed — continuing with save:', uploadErr);\n                    }\n                }\n            }\n\n            // Save JSON payload + new files together through the gateway.\n            await updateRecord(moduleName, recordId, { ...buildPayload(values), ...(extraPayload ?? {}) },\n                onFileUpload?.useLegacyUpload ? [] : fileParts);\n\n            // Mirror AddFormV1's common document registry write so fresh uploads\n            // added during edit are also discoverable via the shared documents\n            // collection. Best-effort only: the record update already succeeded.\n            const allFileParts = collectFileParts(values, groups, { module: moduleName });\n            if (!onFileUpload?.useLegacyUpload && allFileParts.length > 0) {\n                try {\n                    await uploadModuleDocuments(moduleName, recordId, allFileParts);\n                } catch (docErr) {\n                    console.error('Document registry upload failed during edit:', docErr);\n                    message.warning('Changes saved, but saving document records failed.');\n                }\n            }\n\n            // Admin-configurable success toast (group.submitMessages); defaults to\n            // \"<Module> has Updated successfully\" for every module, new ones included.\n            const successText = submitSuccessMessage(groups, moduleName, 'edit');\n            if (successText) message.success(successText);\n\n            if (onSuccess) {\n                onSuccess(recordId, values);\n            } else {\n                const afterSubmit = resolveAfterSubmit(groups);\n                if (!afterSubmit) {\n                    // No admin-configured behavior: go back to wherever the user\n                    // opened this form FROM (usually the detail view), falling\n                    // back to cancelPath only on a cold deep-link.\n                    goBackOrTo(navigate, { cancelPath });\n                } else if (afterSubmit.mode === 'back') {\n                    goBackOrTo(navigate, { cancelPath });\n                } else if (afterSubmit.mode === 'route' || afterSubmit.mode === 'detail') {\n                    const target = safeNavTarget(afterSubmit.target, recordId, values);\n                    if (target) navigate(target);\n                    else goBackOrTo(navigate, { cancelPath });\n                }\n                // afterSubmit.mode === 'stay': no navigation.\n            }\n        } catch (err) {\n            console.error(`Failed to update ${moduleName}:`, err);\n            // Duplicate value rejected by the server: mark the field, keep the\n            // form and everything typed into it, do not navigate, no success\n            // toast, no page-level error banner.\n            if (applyDuplicateFieldErrors(err)) return;\n            const errorText = submitErrorMessage(groups, moduleName, 'edit', err?.message);\n            setSubmitError(errorText);\n            message.error(errorText);\n        } finally {\n            setSubmitting(false);\n        }\n    }\n\n    // Submit-time duplicate (\"already present\") coming back from the\n    // authoritative server-side check. The record was NOT saved, so the form\n    // behaves exactly like a failed client-side validation: values kept, form\n    // open, collapsed sections expanded, error under the offending field and\n    // that field scrolled to + focused (shared utils/scrollToFirstFormError).\n    //\n    // The name used is the one the SERVER returned — the frontend field key,\n    // which is not necessarily the stored field it maps to.\n    function applyDuplicateFieldErrors(source) {\n        const duplicates = extractDuplicateFieldErrors(source, { uniqueRules: uniqueRuleIndex });\n        if (duplicates.length === 0) return false;\n\n        // item.name is the FULL antd path: a plain key for an ordinary field, and\n        // [group, rowIndex, key] for a field inside a repeatable (addRow) group,\n        // so the error lands on the row the user actually typed into.\n        form.setFields(duplicates.map((item) => ({ name: item.name ?? item.field, errors: [item.message] })));\n        setCollapsed({});\n        scrollToFirstFormError({\n            errorFields: duplicates.map((item) => {\n                const name = item.name ?? item.field;\n                return { name: Array.isArray(name) ? name : [name], errors: [item.message] };\n            }),\n        }, form);\n        return true;\n    }\n\n    // ── Scroll to first error on validation fail ────────────────────────────\n    // Shared with AddFormV1 (utils/scrollToFirstFormError). Collapsed sections\n    // are expanded FIRST — an error inside a display:none section can be\n    // neither scrolled to nor focused, which made error navigation appear\n    // broken on the edit form.\n    const handleSubmitFailed = (info) => {\n        setCollapsed({});\n        scrollToFirstFormError(info, form);\n    };\n\n    // ── Render ──────────────────────────────────────────────────────────────\n\n    const [combineToggles, setCombineToggles] = useState({});\n    const fieldKey = (field) => String(field?.field ?? '');\n\n    // See AddFormV1's identical helpers: a Show Condition may be a single leaf\n    // ({field,operator,value}) or a `conditions` array combined by `logic`\n    // (\"and\" default | \"or\") — the multi-condition \"add more\" form. `prefixFor`\n    // resolves each referenced field's sibling prefix (a function), or a\n    // precomputed prefix for legacy callers.\n    const resolvePrefix = (prefixFor, key) => (typeof prefixFor === 'function' ? prefixFor(key) : prefixFor);\n    const evalShowIfLeaf = (cond, getFieldValue, prefixFor) => {\n        if (!cond?.field) return true;\n        const prefix = resolvePrefix(prefixFor, cond.field);\n        const path = prefix != null\n            ? [...(Array.isArray(prefix) ? prefix : [prefix]), cond.field]\n            : [cond.field];\n        const val = getFieldValue(path);\n        switch (cond.operator) {\n            case 'eq': return String(val ?? '') === String(cond.value ?? '');\n            case 'neq': return String(val ?? '') !== String(cond.value ?? '');\n            case 'truthy': return val !== undefined && val !== null && val !== '' && val !== false;\n            case 'falsy': return val === undefined || val === null || val === '' || val === false;\n            // notEmpty targets an addRow GROUP's own Form.List name — true once\n            // that group has at least one row. See AddFormV1.jsx's identical case.\n            case 'notEmpty': return Array.isArray(val) ? val.length > 0 : Boolean(val);\n            case 'in': return String(cond.value ?? '').split(',').map((v) => v.trim()).includes(String(val ?? ''));\n            case 'notIn': return !String(cond.value ?? '').split(',').map((v) => v.trim()).includes(String(val ?? ''));\n            default: return true;\n        }\n    };\n    const evaluateShowIf = (showIf, getFieldValue, prefixFor) => {\n        if (!showIf) return true;\n        const conditions = Array.isArray(showIf.conditions) ? showIf.conditions.filter((c) => c?.field) : [];\n        if (conditions.length) {\n            const results = conditions.map((c) => evalShowIfLeaf(c, getFieldValue, prefixFor));\n            const orLogic = String(showIf.logic ?? 'and').toLowerCase() === 'or';\n            let combined = orLogic ? results.some(Boolean) : results.every(Boolean);\n            if (showIf.field) {\n                const leaf = evalShowIfLeaf(showIf, getFieldValue, prefixFor);\n                combined = orLogic ? (combined || leaf) : (combined && leaf);\n            }\n            return combined;\n        }\n        return evalShowIfLeaf(showIf, getFieldValue, prefixFor);\n    };\n    const hasShowIf = (showIf) => Boolean(showIf?.field || showIf?.conditions?.some?.((c) => c?.field));\n\n    const renderField = (field, namePrefix, listName, opts = {}) => {\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : null;\n        const parsedField = fieldParts ?? field.field;\n        const name = namePrefix !== undefined\n            ? [namePrefix, ...(fieldParts ?? [field.field])]\n            : parsedField;\n        // listName is normally a single Form.List name (string), but a DOUBLY-nested\n        // list (a repeat field's subFields rendered inside an addRow group row) passes\n        // the full absolute path array of its own list — spread it instead of wrapping.\n        const absoluteName = (listName !== undefined && namePrefix !== undefined)\n            ? [...(Array.isArray(listName) ? listName : [listName]), ...(Array.isArray(name) ? name : [name])]\n            : name;\n        const isCheckboxGroup =\n            field.type === 'checkbox' &&\n            ((field.options && field.options.length > 0) ||\n                (field.dataSource && field.dataSource !== 'static'));\n\n        const valuePropName = !isCheckboxGroup && field.type === 'checkbox'\n            ? 'checked'\n            : 'value';\n\n        // Inline (combined) fields show no per-box label — the combined card prints a\n        // single label and the boxes sit side by side (e.g. From / To / Currency).\n        // hideLabel: the group renders one shared header row above all addRow rows\n        // instead of repeating each field's label on every row (e.g. Languages Known).\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        const showIfPrefix = (listName !== undefined && namePrefix !== undefined)\n            ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix]\n            : null;\n        // A condition may reference a sibling IN this row, or any top-level\n        // field (e.g. contractType). Row prefix only applies when the referenced\n        // key is one of this group's own fields; unknown membership (no\n        // rowFieldKeys passed) keeps the historical row-first behavior.\n        const prefixFor = (conditionKey) => (\n            showIfPrefix && (!opts.rowFieldKeys || opts.rowFieldKeys.has(conditionKey))\n                ? showIfPrefix\n                : null\n        );\n        // Override checkbox rides the LABEL — see form/validationOverride.js.\n        const overrideCfg = overrideConfig(field);\n        const overrideFlag = overrideCfg ? overrideFlagPath(field, absoluteName, prefixFor) : null;\n        const baseFieldLabel = (opts.inline || opts.hideLabel)\n            ? ''\n            : !isCheckboxGroup && field.type === 'checkbox'\n            ? ''\n            : <ConfiguredFieldLabel form={form} field={field} siblingPrefix={field.labelWhen?.field ? prefixFor(field.labelWhen.field) : showIfPrefix} locked={permissionLocked} />;\n        const fieldLabel = (overrideCfg && baseFieldLabel) ? (\n            <span className=\"v1-label-with-override\">\n                {baseFieldLabel}\n                <ValidationOverrideCheckbox\n                    form={form}\n                    field={field}\n                    flagPath={overrideFlag}\n                    fieldPath={absoluteName}\n                    disabled={permissionLocked}\n                />\n            </span>\n        ) : baseFieldLabel;\n\n        const mdSpan = opts.inline\n            ? 24\n            : field.type === 'text-editor' || (field.type === 'file' && truthy(field.multiple))\n            ? 24\n            : (field.col ?? 12);\n        const dependencies = getFieldDependencies(field, absoluteName, prefixFor);\n        // Admin-set help text (field.tooltip / infoEnabled+infoText). Rides the\n        // label when there is one; a label-less field gets it on the whole item\n        // (see tooltippedItem below) so every control type can carry one.\n        const tooltipText = fieldTooltipText(field);\n\n        // Inside a combined block, each box's width follows its combineWidth weight\n        // (flex-grow), so the pack can be sized by ratio (e.g. 2:1, 1:2:3). Unset → 1.\n        const inlineStyle = opts.inline\n            ? { flex: `${Number(field.combineWidth) > 0 ? Number(field.combineWidth) : 1} 1 0`, maxWidth: 'none' }\n            : undefined;\n\n        // AI Actions: admin-configured buttons (Generate/Parse-style) attached to\n        // this field. \"click\" actions render as buttons beside the field; an\n        // \"upload\" action (on a file field) fires automatically when a new file\n        // is accepted, via the onAiUpload callback passed into FieldControl.\n        const clickAiActions = (field.aiActions || []).filter((a) => a.trigger === 'click');\n        const uploadAiAction = (field.aiActions || []).find((a) => a.trigger === 'upload');\n\n        const fieldItem = (\n            <Form.Item\n                label={fieldLabel}\n                name={name}\n                extra={renderFieldHelp(field)}\n                required={isFieldRequired(field)}\n                rules={getRules(field, form, absoluteName, false, prefixFor, uniqueContext,\n                    inProgressRulesFor(field, opts.groupNameForActions))}\n                dependencies={dependencies}\n                valuePropName={valuePropName}\n                getValueFromEvent={field.type === 'file' ? (e) => Array.isArray(e) ? e : e?.fileList : undefined}\n                validateTrigger={['onBlur', 'onChange']}\n            >\n                <FieldControl\n                    field={field}\n                    form={form}\n                    name={absoluteName}\n                    rowFieldKeys={opts.rowFieldKeys}\n                    moduleName={moduleName}\n                    recordId={recordId}\n                    initialValue={field.value}\n                    scopeValues={{ clientId }}\n                    onAiUpload={uploadAiAction\n                        ? (file) => aiActions.runAction(opts.groupNameForActions, field, uploadAiAction, file)\n                        : undefined}\n                    formDisabled={aiActions.busy}\n                    onRegionBlocked={handleRegionBlocked}\n                    onRowOrderChange={handleRowOrder}\n                />\n            </Form.Item>\n        );\n\n        // A label-less field (inline/combined box, or a group printing one shared\n        // header row) has nowhere to hang the label's info icon, so the whole\n        // item becomes the tooltip target. The wrapping <span> is what Tooltip\n        // attaches to — handing it the Form.Item directly would make antd clone\n        // that element for the ref, and Form.Item's clone is reserved for\n        // injecting value/onChange into its control.\n        const tooltippedItem = (tooltipText && !fieldLabel)\n            ? <Tooltip title={tooltipText}><span className=\"v1-field-tooltip-wrap\">{fieldItem}</span></Tooltip>\n            : fieldItem;\n\n        const fieldItemWithActions = clickAiActions.length > 0 ? (() => {\n            const positioned = groupActionsByPosition(clickAiActions);\n            const group = (position) => (\n                <AiActionButtonGroup\n                    key={position}\n                    position={position}\n                    actions={positioned[position]}\n                    aiActions={aiActions}\n                    groupName={opts.groupNameForActions}\n                    field={field}\n                />\n            );\n            return (\n                <div className=\"v1-ai-action-wrap\">\n                    {group('top-left')}\n                    {group('top-center')}\n                    {group('top-right')}\n                    {tooltippedItem}\n                    {group('bottom-left')}\n                    {group('bottom-center')}\n                    {group('bottom-right')}\n                </div>\n            );\n        })() : tooltippedItem;\n\n        // Hidden Form.Items for the verify carrier fields (verifyResultField\n        // \"isValid\" / verifyTimestampField \"validatedAt\"), registered under the\n        // same relative (row-indexed) name. On EDIT this is what makes an\n        // already-verified email prefill as \"Verified\": the stored isValid=true\n        // (embedded in the addRow row) populates this registered field, and\n        // VerifyFieldButton renders the success label instead of the button.\n        // It also keeps a re-verify persisting on update. Mirrors AddFormV1.\n        const carrierName = (key) => (namePrefix !== undefined ? [namePrefix, key] : key);\n        const verifyCarriers = field.verifyAction ? (\n            <>\n                {field.verifyResultField && (\n                    <Form.Item name={carrierName(field.verifyResultField)} hidden noStyle>\n                        <Input />\n                    </Form.Item>\n                )}\n                {field.verifyTimestampField && (\n                    <Form.Item name={carrierName(field.verifyTimestampField)} hidden noStyle>\n                        <Input />\n                    </Form.Item>\n                )}\n            </>\n        ) : null;\n\n        const fieldItemWithVerify = field.verifyAction ? (\n            <div className=\"v1-verify-field-row\">\n                {fieldItemWithActions}\n                <VerifyFieldButton form={form} field={field} absoluteName={absoluteName} />\n                {verifyCarriers}\n            </div>\n        ) : fieldItemWithActions;\n\n        // Hidden registration so the flag survives submit and prefills on edit —\n        // same reason the verify carriers above are registered.\n        const fieldItemWithOverride = overrideCfg ? (\n            <>\n                {fieldItemWithVerify}\n                <Form.Item\n                    name={namePrefix !== undefined\n                        ? [namePrefix, overrideFlag[overrideFlag.length - 1]]\n                        : overrideFlag[overrideFlag.length - 1]}\n                    valuePropName=\"checked\"\n                    hidden\n                    noStyle\n                >\n                    <Checkbox />\n                </Form.Item>\n            </>\n        ) : fieldItemWithVerify;\n\n        const prefillWatcher = field.prefillWhen?.length ? (\n            <PrefillWhenWatcher\n                key={`${field.field}-prefillWhen`}\n                form={form}\n                rules={field.prefillWhen}\n                watchPaths={prefillWhenWatchPaths(field.prefillWhen, absoluteName, resolveScopedFieldPath, prefixFor)}\n                targetPath={absoluteName}\n                resetOnNoMatch={field.prefillWhenReset !== false}\n            />\n        ) : null;\n\n        // colWhen: live grid width, so a field can shrink when a condition\n        // reveals a sibling next to it (mirrors AddFormV1). Inline (combined)\n        // cells are flex-sized by combineWidth, so they keep their fixed span.\n        const hasColWhen = !opts.inline && colWhenRules(field).length > 0;\n        const spanFor = (getFieldValue) => (hasColWhen\n            ? resolveColSpan(field, mdSpan, (rule) => getFieldValue(conditionFieldPath(rule, prefixFor(rule.field))))\n            : mdSpan);\n\n        if (hasShowIf(field.showIf) || hasColWhen) {\n            return (\n                <React.Fragment key={field.field}>\n                    {prefillWatcher}\n                    <Form.Item shouldUpdate noStyle>\n                        {({ getFieldValue }) =>\n                            (!hasShowIf(field.showIf) || evaluateShowIf(field.showIf, getFieldValue, prefixFor))\n                                ? <Col xs={24} md={spanFor(getFieldValue)} style={inlineStyle} className={opts.inline ? 'v1-combine-cell' : undefined}>{fieldItemWithOverride}</Col>\n                                : null\n                        }\n                    </Form.Item>\n                </React.Fragment>\n            );\n        }\n\n        return (\n            <React.Fragment key={field.field}>\n                {prefillWatcher}\n                <Col xs={24} md={mdSpan} style={inlineStyle} className={opts.inline ? 'v1-combine-cell' : undefined}>\n                    {fieldItemWithOverride}\n                </Col>\n            </React.Fragment>\n        );\n    };\n\n    // renderAddRowField — field-level \"addRow\": repeats a SINGLE field's control\n    // with the same add/remove + min/initial/max config the group-level addRow\n    // uses (Form.List), but each list item IS the field's value directly (no\n    // sub-key row object). Config keys mirror the group ones: field.minRows /\n    // field.initialRows / field.maxRows / field.addLabel.\n    //   • minRows    — delete is disabled once the list reaches this count.\n    //   • initialRows— empty inputs when the record has no stored values.\n    //   • maxRows    — the \"Add\" button hides once the list reaches this count.\n    // Each stored value prefills its own item (buildRepeatFieldInitial reads the\n    // field's stored array), and each item renders through singleFieldOf(field)\n    // so a repeatable select shows a SINGLE control per item, not a multi-select.\n    // Only used for a top-level field (namePrefix === undefined) — a field with\n    // addRow=true inside an addRow GROUP renders as a normal single-value field\n    // (no nested repeats).\n    const renderAddRowField = (field) => {\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : [field.field];\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        const fieldLabel = <FieldLabel field={field} label={field.label} locked={permissionLocked} />;\n        const itemField = singleFieldOf(field);\n        // subFields → repeat a GROUP of fields per row (each row is an object of\n        // the sub-fields, e.g. question + answer) instead of a single scalar.\n        // Rows render through the same renderFields the group-level addRow uses.\n        const hasSubFields = Array.isArray(field.subFields) && field.subFields.length > 0;\n        // Sub-fields are always shown + editable (the admin exposes no show/edit\n        // toggle for them). Force both so a sub-field never renders disabled: the\n        // Go FormGroupField serializes show/edit as 0 when unset (no omitempty),\n        // which editable() would otherwise read as \"not editable\".\n        const subFieldsToRender = hasSubFields\n            ? field.subFields.map((sf) => ({ ...sf, show: 1, edit: 1 }))\n            : null;\n        const minRows = Math.max(0, Number(field.minRows ?? 0) || 0);\n        const maxRows = field.maxRows !== undefined && field.maxRows !== '' && Number(field.maxRows) > 0\n            ? Number(field.maxRows) : 0;\n        // field.value is the stored array (embedded by getFormGroups with an id).\n        // The Form.List mounts once groups are populated, so this is correct at mount.\n        const initialValue = buildRepeatFieldInitial(field, field.value);\n\n        return (\n            <Col key={field.field} xs={24} md={24}>\n                <Form.Item label={fieldLabel} required={isFieldRequired(field)} colon={false} className=\"v1-combine-field\">\n                    <Form.List\n                        name={fieldParts}\n                        initialValue={initialValue}\n                        rules={[{\n                            validator: async (_, items = []) => {\n                                if (isFieldRequired(field)) {\n                                    const filled = hasSubFields\n                                        ? items.some((v) => hasMeaningfulValue(v))\n                                        : items.some((v) => v !== undefined && v !== null && v !== '' && !(Array.isArray(v) && v.length === 0));\n                                    if (!filled) throw new Error('Mandatory Field');\n                                }\n                                if (minRows > 0 && items.length < minRows) {\n                                    throw new Error(`Keep at least ${minRows} ${hasSubFields ? 'row' : 'value'}${minRows > 1 ? 's' : ''}.`);\n                                }\n                            },\n                        }]}\n                    >\n                        {(items, { add, remove }, { errors }) => (\n                            <div className=\"v1-addrow-wrapper\">\n                                {items.map(({ key: itemKey, name: itemName }) => (\n                                    <div key={itemKey} className=\"v1-addrow-item\">\n                                        <Button\n                                            type=\"text\" danger icon={<DeleteOutlined />}\n                                            onClick={() => remove(itemName)}\n                                            disabled={items.length <= minRows}\n                                            className=\"v1-addrow-delete-btn\"\n                                        />\n                                        <div className=\"v1-addrow-fields\">\n                                            {hasSubFields ? (\n                                                <Row gutter={[24, 0]} align=\"top\">\n                                                    {renderFields(subFieldsToRender, itemName, fieldParts[0], false, field.field)}\n                                                </Row>\n                                            ) : (\n                                                <Form.Item\n                                                    name={[itemName]}\n                                                    noStyle\n                                                    valuePropName={field.type === 'checkbox' && !(field.options?.length) ? 'checked' : 'value'}\n                                                    getValueFromEvent={field.type === 'file' ? (e) => (Array.isArray(e) ? e : e?.fileList) : undefined}\n                                                    rules={getRules(itemField, form, [...fieldParts, itemName], false)}\n                                                >\n                                                    <FieldControl\n                                                        field={itemField}\n                                                        form={form}\n                                                        name={[...fieldParts, itemName]}\n                                                        moduleName={moduleName}\n                                                        recordId={recordId}\n                                                        scopeValues={{ clientId }}\n                                                        formDisabled={aiActions.busy}\n                    onRegionBlocked={handleRegionBlocked}\n                    onRowOrderChange={handleRowOrder}\n                                                    />\n                                                </Form.Item>\n                                            )}\n                                        </div>\n                                    </div>\n                                ))}\n                                {(!maxRows || items.length < maxRows) && (\n                                    <Button type=\"link\" icon={<PlusOutlined />} onClick={() => add()} className=\"v1-addrow-add-btn\">\n                                        {field.addLabel ?? `Add ${field.label ?? 'Value'}`}\n                                    </Button>\n                                )}\n                                <Form.ErrorList errors={errors} />\n                            </div>\n                        )}\n                    </Form.List>\n                </Form.Item>\n            </Col>\n        );\n    };\n\n    // renderNestedRepeatField — a repeat field (field.addRow) inside an addRow\n    // group row. Nests its own Form.List under the current row so every row owns\n    // independent repeat values (group[rowIndex].repeatField[repeatIndex]). Also\n    // handles field.subFields (repeat a GROUP of sub-fields together per row,\n    // e.g. question + answer) nested the same way — each item renders the\n    // sub-fields through the same renderFields the top-level subFields branch\n    // (renderAddRowField) uses, so a select/lookup sub-field gets identical\n    // config-driven dropdown loading. namePrefix = the row index (from the\n    // group Form.List); listName = the group's Form.List name (string), or a\n    // doubly-nested list's absolute path array. Mirrors AddFormV1.\n    const renderNestedRepeatField = (field, namePrefix, listName) => {\n        const fieldParts = typeof field.field === 'string' && field.field.includes('.')\n            ? field.field.split('.')\n            : [field.field];\n        const permissionLocked = Boolean(field.editablePermission)\n            && !roleAllowsAction(field.editablePermission, moduleName);\n        const fieldLabel = <FieldLabel field={field} label={field.label} locked={permissionLocked} />;\n        const itemField = singleFieldOf(field);\n        const hasSubFields = Array.isArray(field.subFields) && field.subFields.length > 0;\n        const subFieldsToRender = hasSubFields\n            ? field.subFields.map((sf) => ({ ...sf, show: 1, edit: 1 }))\n            : null;\n        const minRows = Math.max(0, Number(field.minRows ?? 0) || 0);\n        const maxRows = field.maxRows !== undefined && field.maxRows !== '' && Number(field.maxRows) > 0\n            ? Number(field.maxRows) : 0;\n        const listNameRel = [namePrefix, ...fieldParts];\n        const nestedAbsoluteListName = [...(Array.isArray(listName) ? listName : [listName]), namePrefix, ...fieldParts];\n        // Empty starter inputs for a freshly-added row; an edited row inherits its\n        // stored values from the parent row's initialValue (antd ignores this when\n        // the store already holds a value at this path).\n        const initialValue = buildRepeatFieldInitial(field, undefined);\n        return (\n            <Col key={`${listName}-${namePrefix}-${field.field}`} xs={24} md={hasSubFields ? 24 : (field.col ?? 24)}>\n                <Form.Item label={fieldLabel} required={isFieldRequired(field)} colon={false} className=\"v1-combine-field\">\n                    <Form.List\n                        name={listNameRel}\n                        initialValue={initialValue}\n                        rules={hasSubFields ? [{\n                            validator: async (_, items = []) => {\n                                if (isFieldRequired(field)) {\n                                    const filled = items.some((v) => hasMeaningfulValue(v));\n                                    if (!filled) throw new Error('Mandatory Field');\n                                }\n                                if (minRows > 0 && items.length < minRows) {\n                                    throw new Error(`Keep at least ${minRows} row${minRows > 1 ? 's' : ''}.`);\n                                }\n                            },\n                        }] : []}\n                    >\n                        {(items, { add, remove }, { errors }) => (\n                            <div className=\"v1-addrow-wrapper\">\n                                {items.map(({ key: itemKey, name: itemName }) => {\n                                    const absoluteName = [...nestedAbsoluteListName, itemName];\n                                    return (\n                                        <div key={itemKey} className=\"v1-addrow-item\">\n                                            <Button\n                                                type=\"text\" danger icon={<DeleteOutlined />}\n                                                onClick={() => remove(itemName)}\n                                                disabled={items.length <= minRows}\n                                                className=\"v1-addrow-delete-btn\"\n                                            />\n                                            <div className=\"v1-addrow-fields\">\n                                                {hasSubFields ? (\n                                                    <Row gutter={[24, 0]} align=\"top\">\n                                                        {renderFields(subFieldsToRender, itemName, nestedAbsoluteListName, false, field.field)}\n                                                    </Row>\n                                                ) : (\n                                                    <Form.Item\n                                                        name={[itemName]}\n                                                        noStyle\n                                                        valuePropName={field.type === 'checkbox' && !(field.options?.length) ? 'checked' : 'value'}\n                                                        getValueFromEvent={field.type === 'file' ? (e) => (Array.isArray(e) ? e : e?.fileList) : undefined}\n                                                        rules={getRules(itemField, form, absoluteName, false)}\n                                                    >\n                                                        <FieldControl\n                                                            field={itemField}\n                                                            form={form}\n                                                            name={absoluteName}\n                                                            moduleName={moduleName}\n                                                            recordId={recordId}\n                                                            scopeValues={{ clientId }}\n                                                            formDisabled={aiActions.busy}\n                    onRegionBlocked={handleRegionBlocked}\n                    onRowOrderChange={handleRowOrder}\n                                                        />\n                                                    </Form.Item>\n                                                )}\n                                            </div>\n                                        </div>\n                                    );\n                                })}\n                                {(!maxRows || items.length < maxRows) && (\n                                    <Button type=\"link\" icon={<PlusOutlined />} onClick={() => add()} className=\"v1-addrow-add-btn\">\n                                        {field.addLabel ?? `Add ${field.label ?? 'Value'}`}\n                                    </Button>\n                                )}\n                                <Form.ErrorList errors={errors} />\n                            </div>\n                        )}\n                    </Form.List>\n                </Form.Item>\n            </Col>\n        );\n    };\n\n\n// registerHiddenFields — a show:0 field still needs a Form.Item.\n//\n// A hidden field is not decoration: it is a CARRIER. The engine deliberately\n// keeps show:0 fields in the group (see normalizeGroups) precisely so their\n// values participate — the job's client rate rides onto a submission that way\n// (jobClientRate.*, filled by prefillFromModule), and a verify result rides on\n// isValid/validatedAt.\n//\n// But a value set with setFieldsValue on a path NOTHING has registered is not\n// reliably part of the form: onFinish drops it, and a cross-field rule reading\n// it through getFieldValue can come back empty. That is why the verify carriers\n// were already registered by hand at their own call site. Doing it here covers\n// EVERY config-declared hidden field instead of the two someone remembered,\n// which is what makes a rule like \"rate may not exceed the job's client rate\"\n// actually fire — before this it silently found no ceiling and passed anything.\n//\n// Rendered `hidden` (never visible), unstyled, and outside the layout grid, so\n// nothing about the form's appearance changes.\nconst renderHiddenCarriers = (fields, namePrefix) => fields\n    .filter((f) => f.field && f.show !== undefined && !truthy(f.show))\n    .map((f) => {\n        const parts = String(f.field).includes('.') ? String(f.field).split('.') : f.field;\n        const name = namePrefix !== undefined\n            ? [namePrefix, ...(Array.isArray(parts) ? parts : [parts])]\n            : parts;\n        return (\n            <Form.Item key={`hidden-${f.field}`} name={name} hidden noStyle>\n                <Input />\n            </Form.Item>\n        );\n    });\n\n    const renderFields = (fields, namePrefix, listName, hideLabel = false, groupNameForActions) => {\n        const used = new Set();\n        const out = [];\n        // Keys of THIS group's own fields — conditions (showIf/labelWhen/\n        // prefillWhen) referencing a field OUTSIDE the group (e.g. the top-level\n        // contractType from inside the addRow employer group) must resolve\n        // against the top-level form, not the row.\n        const rowFieldKeys = new Set(fields.map((f) => f.field).filter(Boolean));\n        // Hidden (show:0) fields stay in `fields` so buildPayload can see them\n        // (see normalizeGroups) — they just never get a Form.Item here.\n        const visibleFields = fields.filter((f) => f.show === undefined || truthy(f.show));\n        out.push(...renderHiddenCarriers(fields, namePrefix));\n        visibleFields.forEach((field) => {\n            if (truthy(field.addRow) && namePrefix === undefined) {\n                out.push(renderAddRowField(field));\n                return;\n            }\n            // A repeat field INSIDE an addRow group row (namePrefix defined) nests\n            // its own Form.List so each row keeps independent repeat values\n            // (educationDetails[rowIndex].subjects[]) — including a subFields\n            // repeat-GROUP (e.g. question+answer pairs per education row).\n            if (truthy(field.addRow) && namePrefix !== undefined) {\n                out.push(renderNestedRepeatField(field, namePrefix, listName));\n                return;\n            }\n            const combineKey = field.combineKey?.trim?.();\n            if (!combineKey) {\n                out.push(renderField(field, namePrefix, listName, { hideLabel, groupNameForActions, rowFieldKeys }));\n                return;\n            }\n            const packKey = `${listName ?? 'root'}:${namePrefix ?? 'root'}:${combineKey}`;\n            if (used.has(packKey)) return;\n            const pack = visibleFields.filter((f) => f.combineKey === combineKey);\n            pack.forEach((f) => used.add(`${listName ?? 'root'}:${namePrefix ?? 'root'}:${f.combineKey}`));\n\n            const labelField = pack.find((f) => f.combineLabel) ?? field;\n            const siblingPrefix = (listName !== undefined && namePrefix !== undefined)\n                ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix]\n                : null;\n            // A combined pack prints ONE shared label; an override checkbox on any\n            // member belongs beside it (inline members are label-less by design).\n            const packOverrideField = pack.find((f) => overrideConfig(f)) ?? null;\n            const packPrefixForOverride = (conditionKey) => (\n                siblingPrefix && (!rowFieldKeys || rowFieldKeys.has(conditionKey)) ? siblingPrefix : null\n            );\n            const packOverrideAbsName = packOverrideField\n                ? ((listName !== undefined && namePrefix !== undefined)\n                    ? [...(Array.isArray(listName) ? listName : [listName]), namePrefix,\n                        ...(String(packOverrideField.field).includes('.')\n                            ? String(packOverrideField.field).split('.')\n                            : [packOverrideField.field])]\n                    : (String(packOverrideField.field).includes('.')\n                        ? String(packOverrideField.field).split('.')\n                        : packOverrideField.field))\n                : null;\n            const baseCombinedLabel = <ConfiguredFieldLabel form={form} field={labelField} siblingPrefix={siblingPrefix} combined />;\n            const label = packOverrideField ? (\n                <span className=\"v1-label-with-override\">\n                    {baseCombinedLabel}\n                    <ValidationOverrideCheckbox\n                        form={form}\n                        field={packOverrideField}\n                        flagPath={overrideFlagPath(packOverrideField, packOverrideAbsName, packPrefixForOverride)}\n                        fieldPath={packOverrideAbsName}\n                    />\n                </span>\n            ) : baseCombinedLabel;\n            const toggleTarget = pack.find((f) => f.combineToggleTarget)?.combineToggleTarget;\n            const toggleLabel = pack.find((f) => f.combineToggleLabel)?.combineToggleLabel ?? 'Show range';\n            const wrapPack = pack.some((f) => truthy(f.combineWrap));\n            const configuredSpan = Number(pack.find((f) => [12, 24].includes(Number(f.combineSpan)))?.combineSpan);\n            const targetField = toggleTarget ? pack.find((f) => fieldKey(f) === toggleTarget) : null;\n            const targetParts = targetField?.field?.includes?.('.') ? targetField.field.split('.') : [targetField?.field].filter(Boolean);\n            const targetName = targetField\n                ? ((listName !== undefined && namePrefix !== undefined)\n                    ? [listName, namePrefix, ...targetParts]\n                    : (targetParts.length > 1 ? targetParts : targetField.field))\n                : null;\n\n            // One label, boxes inline on a single row, range toggle BELOW. Toggle off →\n            // only the primary (target hidden); on → the target box appears alongside.\n            const primaryReq = pack.some((f) => isFieldRequired(f));\n            const comboSpan = [12, 24].includes(configuredSpan)\n                ? configuredSpan\n                : (pack.length >= 3 ? 24 : 12);\n            // A combined pack prints ONE shared label above its boxes, outside the\n            // per-field showIf gates — so when every member is hidden the boxes\n            // vanish but the labelled shell stayed (e.g. an empty \"Contact Number\"\n            // on a W2 employer). Gate the pack on \"is any member still visible\".\n            const packPrefixFor = (conditionKey) => (\n                siblingPrefix && (!rowFieldKeys || rowFieldKeys.has(conditionKey)) ? siblingPrefix : null\n            );\n            const packHasShowIf = pack.some((f) => hasShowIf(f.showIf));\n            const anyPackMemberVisible = (getFieldValue) => pack.some(\n                (f) => !hasShowIf(f.showIf) || evaluateShowIf(f.showIf, getFieldValue, packPrefixFor),\n            );\n            const packCol = (\n                <Col key={packKey} xs={24} md={comboSpan}>\n                    <Form.Item label={label} required={primaryReq} colon={false} className=\"v1-combine-field\">\n                        <Form.Item noStyle shouldUpdate>\n                            {({ getFieldValue }) => {\n                                const hasTargetValue = targetName ? !empty(getFieldValue(targetName)) : false;\n                                const checked = combineToggles[packKey] ?? hasTargetValue;\n                                const visiblePack = toggleTarget && !checked\n                                    ? pack.filter((f) => fieldKey(f) !== toggleTarget)\n                                    : pack;\n                                return (\n                                    <>\n                                        <Row\n                                            gutter={[8, 0]}\n                                            align=\"top\"\n                                            wrap={wrapPack}\n                                            className={`v1-combine-row${wrapPack ? ' v1-combine-row-wrap' : ''}`}\n                                        >\n                                            {/* Combined-field mandatory cascade (mirrors AddFormV1):\n                                                any required field in a combined pack makes every\n                                                visible field in the pack required. */}\n                                            {visiblePack.map((f) => renderField(primaryReq ? { ...f, req: 1 } : f, namePrefix, listName, { inline: true }))}\n                                        </Row>\n                                        {toggleTarget && (\n                                            <div className=\"v1-combine-range\">\n                                                <Switch\n                                                    size=\"small\"\n                                                    checked={checked}\n                                                    onChange={(next) => {\n                                                        if (!next && targetName) {\n                                                            form.setFieldValue(targetName, undefined);\n                                                            form.validateFields([targetName]).catch(() => { });\n                                                        }\n                                                        setCombineToggles((prev) => ({ ...prev, [packKey]: next }));\n                                                    }}\n                                                />\n                                                <Text type=\"secondary\" className=\"v1-combine-toggle-label\">{toggleLabel}</Text>\n                                            </div>\n                                        )}\n                                    </>\n                                );\n                            }}\n                        </Form.Item>\n                    </Form.Item>\n                </Col>\n            );\n            out.push(packHasShowIf ? (\n                <Form.Item key={packKey} shouldUpdate noStyle>\n                    {({ getFieldValue }) => (anyPackMemberVisible(getFieldValue) ? packCol : null)}\n                </Form.Item>\n            ) : packCol);\n        });\n        return out;\n    };\n\n    // renderGroupBody — a group's inner controls without its Card chrome, so a\n    // `mergeInto` child group (e.g. Rate Details) can render inside another\n    // group's card. Mirrors AddFormV1: presentation only, payload untouched.\n    const renderGroupBody = (group) => {\n        const groupName = group.name ?? group.id ?? '';\n        // group.linkGroup: when this group is linked to others, the LEADER owns\n        // the Add button + minRows/requireOne validator for the whole set; every\n        // member (leader + followers) still gets its own Form.List/Card/rows, and\n        // add/remove always go through every member via listControlsRef so row\n        // counts stay equal by construction. Unlinked groups (linkedSet === null,\n        // i.e. every group that predates this feature) fall through leaderGroup\n        // === group, so minRows/rules/initialValue below compute exactly as before.\n        const linkedSet = findLinkedSet(linkedGroupSets, groupName);\n        const isFollower = Boolean(linkedSet) && linkedSet.leaderName !== groupName;\n        const leaderGroup = linkedSet\n            ? (groups.find((g) => g.name === linkedSet.leaderName) ?? group)\n            : group;\n        const minRows = Math.max(0, Number(leaderGroup.minRows ?? 0) || 0);\n        const maxRows = Math.max(0, Number(leaderGroup.maxRows ?? 0) || 0);\n        const linkedMemberNames = linkedSet ? linkedSet.memberNames : [groupName];\n        const addLinkedRow = () => {\n            // New rows start from the group's admin defaults (defaultOnEdit).\n            linkedMemberNames.forEach((name) => {\n                const member = groups.find((g) => g.name === name) ?? group;\n                listControlsRef.current[name]?.add(rowDefaultsFor(member, { editing: true }));\n            });\n        };\n        const removeLinkedRow = (rowName) => {\n            linkedMemberNames.forEach((name) => listControlsRef.current[name]?.remove(rowName));\n        };\n\n        const body = group.addRow ? (\n            <Form.List\n                name={groupName}\n                initialValue={addRowInitials[group.name] ?? []}\n                rules={isFollower ? [] : [\n                    {\n                        validator: async (_, rows = []) => {\n                            // A group switched OFF via its own toggle (e.g. \"Fresher\" hiding\n                            // Work Experience) is not rendered at all — don't force rows on it.\n                            const switchedOn = truthy(group.toggleEnabled) && group.toggleField\n                                && Boolean(form.getFieldValue(group.toggleField));\n                            if (switchedOn) return;\n                            if (minRows > 0 && rows.length < minRows) {\n                                throw new Error(`Keep at least ${minRows} row${minRows > 1 ? 's' : ''}.`);\n                            }\n                            if (truthy(group.requireOne)) {\n                                const invalid = rows.some((row) => !hasMeaningfulValue(row));\n                                if (invalid) throw new Error('Fill at least one field in each added row.');\n                            }\n                        },\n                    },\n                ]}\n            >\n                {(rows, { add, remove, move }, { errors }) => {\n                    // `move` joins the registry so the newest-first prompt can\n                    // reorder a row the user just marked as ongoing. Form.List's\n                    // own move preserves every row's values; rebuilding the\n                    // array by hand would not.\n                    listControlsRef.current[groupName] = { add, remove, move };\n                    return (\n                        <div className=\"v1-addrow-wrapper\">\n                            <div className=\"v1-addrow-topbar\">\n                                {!isFollower ? (\n                                    (!maxRows || rows.length < maxRows) && (\n                                        <Button\n                                            type=\"link\"\n                                            icon={<PlusOutlined />}\n                                            onClick={addLinkedRow}\n                                            className=\"v1-addrow-add-btn\"\n                                        >\n                                            {group.addLabel ?? `Add ${group.label ?? 'Row'}`}\n                                        </Button>\n                                    )\n                                ) : (\n                                    <Text type=\"secondary\" className=\"v1-addrow-linked-hint\">\n                                        Rows added via {leaderGroup.label ?? leaderGroup.name}\n                                    </Text>\n                                )}\n                            </div>\n\n                            {truthy(group.sharedRowLabels) && rows.length > 0 && (\n                                <Row gutter={[24, 0]} className=\"v1-addrow-header\">\n                                    {group.fields.filter((f) => f.show === undefined || truthy(f.show)).map((field) => (\n                                        <Col key={fieldKey(field)} md={field.col ?? 12} className=\"v1-addrow-header-label\">\n                                            {field.label}\n                                        </Col>\n                                    ))}\n                                </Row>\n                            )}\n\n                            {rows.map(({ key: rowKey, name }) => (\n                                <div key={rowKey} className=\"v1-addrow-item\">\n                                    <Button\n                                        type=\"text\"\n                                        danger\n                                        icon={<DeleteOutlined />}\n                                        disabled={rows.length <= minRows}\n                                        onClick={() => removeLinkedRow(name)}\n                                        className=\"v1-addrow-delete-btn\"\n                                    />\n                                    <div className=\"v1-addrow-fields\">\n                                        <Row gutter={[24, 0]} align=\"top\">\n                                            {renderFields(group.fields, name, groupName, truthy(group.sharedRowLabels), groupName)}\n                                        </Row>\n                                    </div>\n                                </div>\n                            ))}\n                            <Form.ErrorList errors={errors} />\n                        </div>\n                    );\n                }}\n            </Form.List>\n        ) : (\n            <Row gutter={[24, 0]}>{renderFields(group.fields, undefined, undefined, false, groupName)}</Row>\n        );\n\n        return body;\n    };\n\n    // Groups rendered INSIDE another group's card (group.mergeInto) — see\n    // AddFormV1 for the rationale; identical here so add and edit match.\n    const mergedChildrenOf = (group) => groups.filter(\n        (g) => g !== group && g.mergeInto && String(g.mergeInto) === String(group.name),\n    );\n    const isMergedChild = (group) => Boolean(\n        group.mergeInto && groups.some((g) => g !== group && String(g.name) === String(group.mergeInto)),\n    );\n\n    // A merged child renders BEFORE the host's own fields when it declares\n    // `mergePosition: \"top\"`. Needed whenever the child holds the field the\n    // host's fields are conditioned on — Contract Type gates every Employer\n    // field, so rendering it underneath them reads backwards and invites the\n    // user to fill a disabled card first.\n    const mergedAt = (group, position) => mergedChildrenOf(group).filter(\n        (child) => (String(child.mergePosition ?? 'bottom') === position),\n    );\n\n\n    const renderGroup = (group, index) => {\n        const key = group.name ?? group.id ?? String(index);\n        const body = renderGroupBody(group);\n        const mergedTop = mergedAt(group, 'top');\n        const mergedChildren = mergedAt(group, 'bottom');\n\n        // One renderer for both slots, so a merged child behaves identically\n        // whichever side of the host body it sits on.\n        const renderMergedChild = (child) => {\n            const section = (\n                <div key={child.name} className=\"v1-merged-group\">\n                    <div className=\"v1-merged-group-title\">{child.label ?? child.name}</div>\n                    {renderGroupBody(child)}\n                </div>\n            );\n            const gated = child.showIf?.field\n                ? <GroupShowIfGate key={child.name} form={form} showIf={child.showIf} render={() => section} />\n                : section;\n            // Its OWN disabled state, not the host's — see GroupDisabledProvider.\n            return (\n                <GroupDisabledProvider key={child.name} form={form} group={child} inheritParent={false}>\n                    {gated}\n                </GroupDisabledProvider>\n            );\n        };\n\n        return (\n            <Card\n                key={key}\n                className=\"v1-card v1-edit-card\"\n                title={\n                    <SectionTitle\n                        icon={sectionIcons[index % sectionIcons.length]}\n                        title={group.label ?? group.name ?? 'Details'}\n                    />\n                }\n                extra={\n                    <Space size={8} align=\"center\" className=\"v1-group-actions\">\n                        <GroupInfoMessage group={group} />\n                        <GroupToggleControl group={group} />\n                        {/* Opt-in only (group.allowCollapse) — see AddFormV1. */}\n                        {truthy(group.allowCollapse) && (\n                            <Button type=\"text\" size=\"small\"\n                                aria-expanded={!collapsed[key]}\n                                aria-label={collapsed[key] ? 'Expand section' : 'Collapse section'}\n                                icon={collapsed[key] ? <DownOutlined /> : <UpOutlined />}\n                                onClick={(e) => { e.stopPropagation(); toggle(key); }}\n                            />\n                        )}\n                    </Space>\n                }\n            >\n                <Form.Item noStyle shouldUpdate>\n                    {({ getFieldValue }) => {\n                        const switchedOn = truthy(group.toggleEnabled) && group.toggleField && Boolean(getFieldValue(group.toggleField));\n                        return (\n                            <div style={{ display: collapsed[key] || switchedOn ? 'none' : 'block' }}>\n                                {mergedTop.map(renderMergedChild)}\n                                {body}\n                                {mergedChildren.map(renderMergedChild)}\n                            </div>\n                        );\n                    }}\n                </Form.Item>\n            </Card>\n        );\n    };\n\n    return (\n        <main>\n            {resolvedBreadcrumbs.length > 0 && <AppBreadcrumb items={resolvedBreadcrumbs} />}\n\n            <div className=\"v1-edit-page\">\n                <div className=\"v1-page-inner\">\n                    {/* Same split as the Add form: async work gets a\n                        viewport-centred overlay, because a wrapping Spin\n                        centres inside the element it wraps and on a long form\n                        that is off screen after any scrolling — a frozen form\n                        with no sign anything is happening. */}\n                    <Spin\n                        fullscreen\n                        spinning={aiActions.busy}\n                        size=\"large\"\n                        tip={aiActions.loadingText || 'Reading the file…'}\n                    />\n                    <Spin spinning={loading} tip=\"Loading form fields…\">\n                        {error && (\n                            <Alert type=\"error\" showIcon message={error}\n                                style={{ marginBottom: 16 }} />\n                        )}\n                        {submitError && (\n                            <Alert type=\"error\" showIcon message={submitError}\n                                style={{ marginBottom: 16 }} />\n                        )}\n\n                        <Form\n                            form={form}\n                            layout=\"vertical\"\n                            colon={false}\n                            className=\"v1-form\"\n                            disabled={aiActions.busy}\n                            requiredMark={(label, { required }) => (\n                                <>\n                                    {label}\n                                    {required && <span className=\"v1-required-mark\"> *</span>}\n                                </>\n                            )}\n                            onFinish={submit}\n                            onFinishFailed={handleSubmitFailed}\n                        >\n                            {groups.filter((g) => !isMergedChild(g)).map((group, index) => (\n                                <GroupDisabledProvider key={group.name ?? `grp-${index}`} form={form} group={group}>\n                                    {group.showIf?.field\n                                        ? <GroupShowIfGate form={form} showIf={group.showIf} render={() => renderGroup(group, index)} />\n                                        : renderGroup(group, index)}\n                                </GroupDisabledProvider>\n                            ))}\n\n                            {!loading && !error && groups.length === 0 && (\n                                <Alert type=\"info\" showIcon message=\"No form fields are configured.\" />\n                            )}\n                        </Form>\n                    </Spin>\n                </div>\n\n                <div className={embedded ? 'v1-footer v1-footer--embedded' : 'v1-footer'}>\n                    <Text type=\"secondary\">\n                        All unsaved changes will be lost if you cancel and reload.\n                    </Text>\n                    <Space size={12}>\n                        <Button onClick={() => (embedded && onCancel\n                            ? onCancel()\n                            : goBackOrTo(navigate, { cancelPath }))}>\n                            Cancel\n                        </Button>\n                        <ValidationGatedSubmitButton\n                            form={form}\n                            groups={groups}\n                            onClick={() => form.submit()}\n                            disabled={loading || submitting || uniquePending > 0}\n                            loading={submitting}\n                        >\n                            {submitText}\n                        </ValidationGatedSubmitButton>\n                    </Space>\n                </div>\n            </div>\n        </main>\n    );\n}\n","import { useEffect, useState } from 'react';\nimport { getModuleActions } from '../services/detailedViewApi';\n\n// One fetch per module per page load — every row of a list shares the result.\nconst actionConfigCache = new Map();\n\nexport function useModuleActions(module) {\n  const [config, setConfig] = useState({ actions: [], actionRules: [] });\n\n  useEffect(() => {\n    if (!module) return undefined;\n    let cancelled = false;\n    if (!actionConfigCache.has(module)) {\n      actionConfigCache.set(\n        module,\n        getModuleActions(module).catch(() => {\n          actionConfigCache.delete(module);\n          return { actions: [], actionRules: [] };\n        }),\n      );\n    }\n    actionConfigCache.get(module).then((data) => {\n      if (!cancelled) setConfig(data);\n    });\n    return () => { cancelled = true; };\n  }, [module]);\n\n  return config;\n}\n","import { useLocation, useNavigate } from 'react-router-dom';\nimport { Button, Dropdown, Modal, message } from 'antd';\nimport {\n  DeleteOutlined,\n  EditOutlined,\n  MailOutlined,\n  MoreOutlined,\n  RightOutlined,\n  ShareAltOutlined,\n  ThunderboltOutlined,\n  UserAddOutlined,\n  UserSwitchOutlined,\n} from '@ant-design/icons';\n\nimport { useModuleActions } from '../../hooks/useModuleActions';\nimport { fetchJsonWithAuth } from '../../services/authApi';\nimport { AUTH_URL } from '../../services/apiConfig';\nimport { roleAllowsAction, isActionValueAllowed } from '../../utils/roleAllowsAction';\nimport { isRuleActionBlocked, ruleActionDisabledReason, actionDoneState } from '../../utils/actionRuleEngine';\n\n// Same icon vocabulary as ListView's action column, so an action configured\n// once in Admin renders identically on every surface that uses this component.\nconst ACTION_ICON_MAP = {\n  delete: <DeleteOutlined />,\n  edit: <EditOutlined />,\n  mail: <MailOutlined />,\n  shareAlt: <ShareAltOutlined />,\n  swap: <RightOutlined />,\n  thunderbolt: <ThunderboltOutlined />,\n  userAdd: <UserAddOutlined />,\n  userSwitch: <UserSwitchOutlined />,\n};\n\nfunction templatePart(value) {\n  if (value === null || value === undefined) return '';\n  if (Array.isArray(value)) return value.join(',');\n  if (typeof value === 'object') return String(value.id ?? value.value ?? '');\n  return String(value);\n}\n\nfunction fillRouteTemplate(template, record) {\n  return String(template)\n    .replace(/\\{([^}]+)\\}/g, (_, key) => encodeURIComponent(templatePart(record?.[key])))\n    .replace(/:([A-Za-z_][\\w]*)/g, (_, key) => encodeURIComponent(\n      templatePart(record?.[key] ?? (key === '_id' ? record?.id : key === 'id' ? record?._id : undefined)),\n    ));\n}\n\nfunction getNestedValue(record, path) {\n  return String(path || '').split('.').reduce((value, key) => value?.[key], record);\n}\n\nfunction toMenuItem(action, record, actionRules, scope) {\n  // Config-driven \"done\" terminus: once doneWhen matches (e.g. the submission's\n  // onboardingStatus is set), the action is no longer clickable and shows its\n  // doneLabel (\"Moved to Onboarded\") instead of the normal label.\n  const done = actionDoneState(action, record, scope);\n  // Rule-disabled (not blocked/hidden — see ruleActionDisabledReason): the\n  // item stays in the menu, just greyed out, with the rule's description as\n  // the reason shown on hover.\n  const disabledReason = ruleActionDisabledReason(action.key, record, actionRules, scope);\n  const item = {\n    key: action.key,\n    label: done ? done.label : (action.label || action.key),\n    icon: ACTION_ICON_MAP[action.icon] ?? undefined,\n    danger: action.danger || undefined,\n    disabled: !!done || !!disabledReason,\n    title: done ? done.label : (disabledReason || undefined),\n  };\n  if (action.children?.length) item.children = action.children.map((child) => toMenuItem(child, record, actionRules, scope));\n  return item;\n}\n\nfunction flattenActions(actions) {\n  const flat = [];\n  for (const action of actions) {\n    flat.push(action);\n    if (action.children?.length) flat.push(...flattenActions(action.children));\n  }\n  return flat;\n}\n\n/**\n * ModuleRowActions — admin-configured row actions for list pages that don't\n * use the generic ListView (e.g. the Onboarding movements list). Reads the\n * same /module-actions contract (rowActionConfig + module action rules) and\n * dispatches with the same semantics as ListView / DetailHeaderCard:\n * navigate (linkTarget \"_blank\" honored), modal → /popup/<popupKey> route\n * over the current page, api (danger actions get a confirm), copy.\n *\n * Props:\n *   module   — rowActionConfig module key (e.g. \"onboarding\")\n *   record   — the row's record, used for template filling + rule evaluation\n *   scope    — optional current tab/scope for allowedTabs + scope rules\n *   onDone   — called after an api action succeeds (e.g. to refresh the list)\n *   fallback — rendered when no configured action is visible for this row\n */\nexport default function ModuleRowActions({ module, record, scope, onDone, fallback = null }) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const { actions, actionRules } = useModuleActions(module);\n\n  const isVisible = (action) => {\n    if (action.showInList === false) return false;\n    if (!roleAllowsAction(action.permission, module)) return false;\n    if (action.permissionKey\n      && !isActionValueAllowed(getNestedValue(record, `actionPermission.${action.permissionKey}`))) return false;\n    if (isRuleActionBlocked(action.key, record, actionRules, scope)) return false;\n    if (action.allowedTabs?.length && scope\n      && !action.allowedTabs.some((tab) => String(tab).toLowerCase() === String(scope).toLowerCase())) return false;\n    return true;\n  };\n\n  const visibleActions = (actions ?? [])\n    .filter(isVisible)\n    .map((action) => (action.children?.length\n      ? { ...action, children: action.children.filter(isVisible) }\n      : action));\n\n  if (!visibleActions.length) return fallback;\n\n  const runAction = (action) => {\n    if (action.actionType === 'copy') {\n      const value = getNestedValue(record, action.copyField || 'id') ?? record?._id;\n      navigator.clipboard.writeText(templatePart(value))\n        .then(() => message.success('Copied to clipboard'))\n        .catch(() => message.error('Could not copy to clipboard'));\n      return;\n    }\n\n    if (action.actionType === 'api' && action.apiPath) {\n      const call = () => {\n        const apiPath = fillRouteTemplate(action.apiPath, record);\n        const method = String(action.apiMethod || 'POST').toUpperCase();\n        fetchJsonWithAuth(AUTH_URL, apiPath.startsWith('/') ? apiPath : `/${apiPath}`, {\n          method,\n          body: ['GET', 'DELETE'].includes(method)\n            ? undefined\n            : JSON.stringify({ ids: [record?._id ?? record?.id], records: [record] }),\n        })\n          .then(() => {\n            message.success(`${action.label} completed`);\n            onDone?.(action);\n          })\n          .catch((error) => message.error(error.message || `${action.label} failed`));\n      };\n      if (action.danger) {\n        Modal.confirm({\n          title: `${action.label}?`,\n          content: 'This cannot be undone.',\n          okText: action.label,\n          okButtonProps: { danger: true },\n          onOk: call,\n        });\n      } else {\n        call();\n      }\n      return;\n    }\n\n    if (action.actionType === 'modal') {\n      const popupKey = action.popupKey || action.key;\n      navigate(`/popup/${popupKey}`, {\n        state: {\n          background: location,\n          selectedIds: [record?._id ?? record?.id],\n          selectedRecords: [record],\n          moduleName: module,\n          popupContext: action.popupState ?? {},\n          popupAction: {\n            key: action.key,\n            apiMethod: action.apiMethod,\n            apiPath: action.apiPath,\n            defaultTemplateId: action.defaultTemplateId,\n            requireJobId: action.requireJobId,\n            popupFieldOverrides: action.popupFieldOverrides,\n          },\n          ...action.popupState,\n        },\n      });\n      return;\n    }\n\n    const route = action.routeTemplate || action.route;\n    if (route) {\n      const resolved = fillRouteTemplate(route, record);\n      const normalized = resolved.startsWith('/') ? resolved : `/${resolved}`;\n      if (action.linkTarget === '_blank') {\n        window.open(normalized, '_blank', 'noopener');\n        return;\n      }\n      navigate(normalized);\n    }\n  };\n\n  const byKey = new Map(flattenActions(visibleActions).map((a) => [String(a.key), a]));\n\n  return (\n    <Dropdown\n      trigger={['click']}\n      menu={{\n        items: visibleActions.map((action) => toMenuItem(action, record, actionRules, scope)),\n        onClick: ({ key, domEvent }) => {\n          domEvent?.stopPropagation?.();\n          const action = byKey.get(String(key));\n          // A \"done\" action (doneWhen matched) is a disabled success label, not\n          // a trigger — never dispatch it even if a click slips through.\n          if (action && action.actionType !== 'group' && !actionDoneState(action, record, scope)) runAction(action);\n        },\n      }}\n    >\n      <Button\n        type=\"text\"\n        icon={<MoreOutlined />}\n        onClick={(event) => event.stopPropagation()}\n        aria-label=\"Row actions\"\n      />\n    </Dropdown>\n  );\n}\n","import { useMemo, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport {\n  Button,\n  Card,\n  Checkbox,\n  Dropdown,\n  Flex,\n  Input,\n  Popover,\n  Spin,\n  Tag,\n  Tooltip,\n  Typography,\n} from 'antd';\nimport {\n  AppstoreOutlined,\n  DownOutlined,\n  EnvironmentOutlined,\n  EyeOutlined,\n  FileTextOutlined,\n  FilterOutlined,\n  MailOutlined,\n  PhoneOutlined,\n  SearchOutlined,\n  UnorderedListOutlined,\n} from '@ant-design/icons';\nimport CustomPagination from './CustomPagination';\nimport '../styles/ParamCardView.css';\n\nconst { Text } = Typography;\n\nfunction getFieldLabel(field) {\n  return field.label ?? field.fieldLabel ?? field.name ?? field.fieldName ?? field.value;\n}\n\nfunction getFieldValue(field) {\n  return field.value ?? field.fieldName ?? field.name ?? field.label;\n}\n\nfunction getRecordValue(record, fieldKey) {\n  const value = record?.[fieldKey];\n  if (value === null || value === undefined) return '-';\n  if (Array.isArray(value)) return value.join(', ');\n  if (typeof value === 'object') return Object.values(value).join(' ');\n  return value;\n}\n\nconst CANDIDATE_PREVIEW_FIELDS = [\n  { key: 'name',        label: 'Name' },\n  { key: 'designation', label: 'Designation' },\n  { key: 'locationExp', label: 'Location / Exp' },\n  { key: 'skills',      label: 'Skills' },\n  { key: 'createdOn',   label: 'Created On' },\n];\n\nfunction CandidateCard({ record, fields, selected, onSelect }) {\n  const navigate = useNavigate();\n  const location = useLocation();\n\n  const nameField     = fields.find((f) => f.cardRole === 'name');\n  const subtitleField = fields.find((f) => f.cardRole === 'subtitle');\n  const locationField = fields.find((f) => f.cardRole === 'location');\n  const skillsField   = fields.find((f) => f.cardRole === 'skills');\n  const expField      = fields.find((f) => f.cardRole === 'exp');\n  const dateField     = fields.find((f) => f.cardRole === 'date');\n  const actionField   = fields.find((f) => f.cardRole === 'action');\n\n  const nameValue     = nameField     ? getRecordValue(record, nameField.key)     : '-';\n  const subtitleValue = subtitleField ? getRecordValue(record, subtitleField.key) : '';\n  const locationValue = locationField ? getRecordValue(record, locationField.key) : '';\n  const expValue      = expField      ? getRecordValue(record, expField.key)      : '';\n  const dateValue     = dateField     ? getRecordValue(record, dateField.key)     : '';\n\n  const rawSkills      = skillsField ? record[skillsField.key] : [];\n  const skills         = Array.isArray(rawSkills) ? rawSkills : [];\n  const visibleSkills  = skills.slice(0, 3);\n  const overflowSkills = skills.slice(3);\n\n  const actionNode = actionField?.render\n    ? actionField.render(getRecordValue(record, actionField.key), record)\n    : null;\n\n  function handlePreviewOpen() {\n    navigate('/popup/preview', {\n      state: {\n        background: location,\n        moduleName: 'candidate',\n        record,\n        fields: CANDIDATE_PREVIEW_FIELDS,\n      },\n    });\n  }\n\n  function handleMailOpen() {\n    navigate('/popup/mail', {\n      state: { background: location },\n    });\n  }\n\n  return (\n    <div className={`param-card${selected ? ' param-card--selected' : ''}`}>\n\n      {/* ── Header ── */}\n      <div className=\"param-card__header\">\n        <div className=\"param-card__header-left\">\n          <div className=\"param-card__name-row\">\n            <Checkbox\n              checked={selected}\n              onChange={onSelect}\n              onClick={(e) => e.stopPropagation()}\n              className=\"param-card__checkbox\"\n            />\n            <EyeOutlined className=\"param-card__eye-icon\" onClick={handlePreviewOpen} />\n            <span className=\"param-card__name-block\">\n              <Text className=\"param-card__name\">{nameValue}</Text>\n              {subtitleValue && subtitleValue !== '-' && (\n                <>\n                  <span className=\"param-card__sep\">·</span>\n                  <Text className=\"param-card__subtitle\">{subtitleValue}</Text>\n                </>\n              )}\n            </span>\n          </div>\n          {locationValue && locationValue !== '-' && (\n            <div className=\"param-card__location\">\n              <EnvironmentOutlined className=\"param-card__location-icon\" />\n              <Text className=\"param-card__location-text\">{locationValue}</Text>\n            </div>\n          )}\n        </div>\n\n        <div className=\"param-card__header-right\">\n          <span className=\"param-card__exp-badge\">\n            Exp: {expValue && expValue !== '-' ? expValue : '-'}\n          </span>\n        </div>\n      </div>\n\n      {/* ── Body: Skills (left) + Created on (right) ── */}\n      <div className=\"param-card__body\">\n        <div className=\"param-card__body-left\">\n          <Text className=\"param-card__section-label\">Skills</Text>\n          <div className=\"param-card__skills-row\">\n            {visibleSkills.length > 0\n              ? visibleSkills.map((skill) => (\n                  <Tag key={skill} className=\"sourcing-skill-tag\">{skill}</Tag>\n                ))\n              : <Text className=\"param-card__empty\">-</Text>\n            }\n            {overflowSkills.length > 0 && (\n              <Popover\n                trigger=\"click\"\n                placement=\"bottomLeft\"\n                overlayClassName=\"sourcing-skills-popover\"\n                content={\n                  <div className=\"sourcing-skills-popup\">\n                    {overflowSkills.map((skill) => (\n                      <Tag key={skill} className=\"sourcing-skill-tag\">{skill}</Tag>\n                    ))}\n                  </div>\n                }\n              >\n                <span className=\"sourcing-more-skills\">+{overflowSkills.length}</span>\n              </Popover>\n            )}\n          </div>\n        </div>\n\n        {dateValue && dateValue !== '-' && (\n          <div className=\"param-card__body-right\">\n            <Text className=\"param-card__section-label param-card__section-label--right\">\n              Created on\n            </Text>\n            <Text className=\"param-card__date-value\">{dateValue}</Text>\n          </div>\n        )}\n      </div>\n\n      {/* ── Divider ── */}\n      <div className=\"param-card__divider\" />\n\n      {/* ── Footer ── */}\n      <div className=\"param-card__footer\">\n        <div className=\"param-card__footer-left\">\n          <Tooltip title=\"Resume\">\n            <button type=\"button\" className=\"param-card__icon-btn\" aria-label=\"Resume\">\n              <FileTextOutlined />\n            </button>\n          </Tooltip>\n          <Tooltip title=\"Call\">\n            <button type=\"button\" className=\"param-card__icon-btn\" aria-label=\"Call\">\n              <PhoneOutlined />\n            </button>\n          </Tooltip>\n          <Tooltip title=\"Email\">\n            <button type=\"button\" className=\"param-card__icon-btn\" aria-label=\"Email\" onClick={handleMailOpen}>\n              <MailOutlined />\n            </button>\n          </Tooltip>\n        </div>\n        <div className=\"param-card__footer-right\">\n          {actionNode}\n        </div>\n      </div>\n\n    </div>\n  );\n}\n\nexport default function ParamCardView({\n  listName = 'List',\n  moduleName = '',\n  actions = [],\n  fields = [],\n  dataSource = [],\n  loading = false,\n  total,\n  current,\n  pageSize,\n  onPageChange,\n  onPageSizeChange,\n  className = '',\n  activeView = 'card',\n  onViewChange,\n}) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const [search, setSearch] = useState('');\n  const [pagination, setPagination] = useState({ current: 1, pageSize: 12 });\n  const [selectedIds, setSelectedIds] = useState([]);\n  const [selectedRecords, setSelectedRecords] = useState([]);\n\n  const isControlledPagination = typeof current === 'number' && typeof pageSize === 'number';\n  const activePagination = isControlledPagination ? { current, pageSize } : pagination;\n\n  const toggleSelect = (record) => {\n    const id = record.id ?? record._id;\n    setSelectedIds((prev) =>\n      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]\n    );\n    setSelectedRecords((prev) =>\n      prev.some((r) => (r.id ?? r._id) === id)\n        ? prev.filter((r) => (r.id ?? r._id) !== id)\n        : [...prev, record]\n    );\n  };\n\n  const cardMenuItems = actions\n    .filter((action) => !action.maxSelect || selectedIds.length <= action.maxSelect)\n    .map((action) => ({\n      key: action.key ?? action.name,\n      label: action.label ?? action.name,\n      danger: action.danger ?? false,\n      disabled: selectedIds.length === 0,\n      onClick: () => {\n        if (selectedIds.length === 0) return;\n        // onSelect actions call straight through (e.g. Shortlist) — no modal,\n        // no navigation. The handler owns its own loading/success/error feedback.\n        if (typeof action.onSelect === 'function') {\n          action.onSelect({ selectedIds, selectedRecords });\n          return;\n        }\n        if (!action.route) return;\n        navigate(action.route, {\n          state: {\n            background: location,\n            selectedIds,\n            selectedRecords,\n            moduleName,\n            ...(action.popupState ?? {}),\n          },\n        });\n      },\n    }));\n\n  const normalizedFields = useMemo(() => (\n    fields\n      .map((field) => ({\n        ...field,\n        key: getFieldValue(field),\n        label: getFieldLabel(field),\n      }))\n      .filter((field) => field.key && field.label)\n  ), [fields]);\n\n  const displayTotal = typeof total === 'number' ? total : dataSource.length;\n\n  const filteredData = useMemo(() => {\n    const q = search.toLowerCase();\n    if (!q || q.length < 3) return dataSource;\n    return dataSource.filter((record) =>\n      normalizedFields.some((field) =>\n        String(getRecordValue(record, field.key)).toLowerCase().includes(q)\n      )\n    );\n  }, [dataSource, normalizedFields, search]);\n\n  const pagedData = useMemo(() => {\n    if (isControlledPagination) return filteredData;\n    const start = (activePagination.current - 1) * activePagination.pageSize;\n    return filteredData.slice(start, start + activePagination.pageSize);\n  }, [activePagination.current, activePagination.pageSize, filteredData, isControlledPagination]);\n\n  return (\n    <div className={`antd param-card-view ${className}`.trim()}>\n\n      {/* ── Toolbar ── */}\n      <Card>\n        <Flex align=\"center\" justify=\"space-between\">\n          <Flex align=\"center\" gap={6}>\n            <Text className=\"param-card-view__tab-label\">{listName}</Text>\n            <span className=\"param-card-view__count\">{displayTotal}</span>\n            {selectedIds.length > 0 && actions.length > 0 && (\n              <>\n                <Dropdown menu={{ items: cardMenuItems }} trigger={['click']}>\n                  <Button type=\"text\" size=\"small\" className=\"job-actions-button job-actions-menu-button\">\n                    Actions <DownOutlined className=\"job-actions-caret\" />\n                  </Button>\n                </Dropdown>\n                <Text className=\"job-selected-count\">Selected ({selectedIds.length})</Text>\n              </>\n            )}\n          </Flex>\n          <Flex align=\"center\" gap={8}>\n            <Input\n              prefix={<SearchOutlined className=\"job-search-icon\" />}\n              placeholder=\"Search by name, location, skills\"\n              value={search}\n              onChange={(e) => {\n                setSearch(e.target.value);\n                if (isControlledPagination) onPageChange?.(1);\n                else setPagination((p) => ({ ...p, current: 1 }));\n              }}\n              allowClear\n              className=\"job-search-input\"\n            />\n            <Tooltip title=\"Filter\">\n              <Button className=\"job-toolbar-icon-button\" icon={<FilterOutlined />} />\n            </Tooltip>\n            <Tooltip title=\"Card view\">\n              <Button\n                className={`job-toolbar-icon-button param-view-toggle-btn${activeView === 'card' ? ' param-view-toggle-btn--active' : ''}`}\n                icon={<AppstoreOutlined />}\n                onClick={() => onViewChange?.('card')}\n              />\n            </Tooltip>\n            <Tooltip title=\"List view\">\n              <Button\n                className={`job-toolbar-icon-button param-view-toggle-btn${activeView === 'list' ? ' param-view-toggle-btn--active' : ''}`}\n                icon={<UnorderedListOutlined />}\n                onClick={() => onViewChange?.('list')}\n              />\n            </Tooltip>\n          </Flex>\n        </Flex>\n      </Card>\n\n      {/* ── Card Grid ── */}\n      <Spin spinning={loading}>\n        {pagedData.length > 0 ? (\n          <div className=\"param-card-view__grid\">\n            {pagedData.map((record, index) => (\n              <CandidateCard\n                key={record.id ?? record.key ?? index}\n                record={record}\n                fields={normalizedFields}\n                selected={selectedIds.includes(record.id ?? record._id)}\n                onSelect={() => toggleSelect(record)}\n              />\n            ))}\n          </div>\n        ) : (\n          !loading && (\n            <div className=\"param-card-view__empty\">No results found</div>\n          )\n        )}\n      </Spin>\n\n      <CustomPagination\n        current={activePagination.current}\n        pageSize={activePagination.pageSize}\n        total={displayTotal}\n        onChange={(page) => {\n          if (isControlledPagination) onPageChange?.(page);\n          else setPagination((p) => ({ ...p, current: page }));\n        }}\n        onPageSizeChange={(size) => {\n          if (isControlledPagination) onPageSizeChange?.(size);\n          else setPagination({ current: 1, pageSize: size });\n        }}\n      />\n    </div>\n  );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Button,\n  Card,\n  Checkbox,\n  Dropdown,\n  Flex,\n  Input,\n  Spin,\n  Space,\n  Table,\n  Tabs,\n  Tooltip,\n  Typography,\n} from 'antd';\nimport {\n  AppstoreOutlined,\n  DownOutlined,\n  FilterOutlined,\n  EyeOutlined,\n  FileTextOutlined,\n  MailOutlined,\n  PhoneOutlined,\n  SearchOutlined,\n  UnorderedListOutlined,\n} from '@ant-design/icons';\nimport CustomPagination from './CustomPagination';\nimport frameIcon from './images/common/frame.svg';\nimport unorderedListOutlinedIcon from './images/common/unorderedlistoutlined.svg';\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nconst { Text } = Typography;\n\nfunction getFieldLabel(field) {\n  return field.label ?? field.fieldLabel ?? field.name ?? field.fieldName ?? field.value;\n}\n\nfunction getFieldValue(field) {\n  return field.value ?? field.fieldName ?? field.name ?? field.label;\n}\n\nfunction getRecordValue(record, fieldKey) {\n  const value = record?.[fieldKey];\n\n  if (value === null || value === undefined) return '-';\n  if (Array.isArray(value)) return value.join(', ');\n  if (typeof value === 'object') return Object.values(value).join(' ');\n\n  return value;\n}\n\nfunction tabLabel(label, count) {\n  return (\n    <Space size={6}>\n      <span>{label}</span>\n      <Badge count={count} overflowCount={9999} />\n    </Space>\n  );\n}\n\nexport default function ParamListView({\n  listName = 'List',\n  fields = [],\n  actions = [],\n  dataSource = [],\n  loading = false,\n  total,\n  current,\n  pageSize,\n  onPageChange,\n  onPageSizeChange,\n  onSearch,\n  rowSelection = true,\n  className = '',\n  tableClassName = 'job-list-table',\n  activeView = 'list',\n  onViewChange,\n}) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const [activeTab, setActiveTab] = useState('all');\n  const [search, setSearch] = useState('');\n  const [selectedRowKeys, setSelectedRowKeys] = useState([]);\n  const [selectedRows, setSelectedRows] = useState([]);\n  const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });\n  const [visibleColumnKeys, setVisibleColumnKeys] = useState([]);\n  const [columnMenuOpen, setColumnMenuOpen] = useState(false);\n  const searchTimerRef = useRef(null);\n\n  const menuItems = actions\n    .filter((action) => !action.maxSelect || selectedRowKeys.length <= action.maxSelect)\n    .map((action) => ({\n      key: action.key ?? action.name,\n      label: action.label ?? action.name,\n      danger: action.danger ?? false,\n      disabled: selectedRowKeys.length === 0,\n      onClick: () => {\n        if (selectedRowKeys.length === 0) return;\n        // onSelect actions call straight through (e.g. Shortlist) — no modal,\n        // no navigation. The handler owns its own loading/success/error feedback.\n        if (typeof action.onSelect === 'function') {\n          action.onSelect({ selectedIds: selectedRowKeys, selectedRecords: selectedRows });\n          return;\n        }\n        if (!action.route) return;\n        navigate(action.route, {\n          state: {\n            background: location,\n            selectedIds: selectedRowKeys,\n            selectedRecords: selectedRows,\n            ...(action.popupState ?? {}),\n          },\n        });\n      },\n    }));\n  const isControlledPagination = typeof current === 'number' && typeof pageSize === 'number';\n  const activePagination = isControlledPagination ? { current, pageSize } : pagination;\n\n  const normalizedFields = useMemo(() => (\n    fields\n      .map((field) => ({\n        ...field,\n        key: getFieldValue(field),\n        label: getFieldLabel(field),\n      }))\n      .filter((field) => field.key && field.label && !field.tableHidden)\n  ), [fields]);\n\n  const visibleKeys = visibleColumnKeys.length\n    ? visibleColumnKeys\n    : normalizedFields.map((field) => field.key);\n\n  const filteredData = useMemo(() => {\n    if (onSearch) return dataSource;\n    const q = search.toLowerCase();\n    if (!q || q.length < 3) return dataSource;\n\n    return dataSource.filter((record) => (\n      normalizedFields.some((field) => (\n        String(getRecordValue(record, field.key)).toLowerCase().includes(q)\n      ))\n    ));\n  }, [dataSource, normalizedFields, onSearch, search]);\n\n  const displayTotal = typeof total === 'number'\n    ? total\n    : search.trim() ? filteredData.length : dataSource.length;\n\n  const pagedData = useMemo(() => {\n    if (isControlledPagination) return filteredData;\n\n    const start = (activePagination.current - 1) * activePagination.pageSize;\n    return filteredData.slice(start, start + activePagination.pageSize);\n  }, [activePagination.current, activePagination.pageSize, filteredData, isControlledPagination]);\n\n  const columns = useMemo(() => (\n    normalizedFields\n      .filter((field) => visibleKeys.includes(field.key))\n      .map((field) => ({\n        title: field.label,\n        dataIndex: field.key,\n        key: field.key,\n        sorter: field.sorter === false\n          ? false\n          : field.sorter ?? ((a, b) => String(getRecordValue(a, field.key)).localeCompare(String(getRecordValue(b, field.key)))),\n        width: field.width ?? 180,\n        fixed: field.fixed,\n        ellipsis: field.ellipsis ?? true,\n        className: field.className,\n        render: (value, record, index) => (\n          field.render\n            ? field.render(value, record, index)\n            : <Text className=\"job-cell-primary\">{getRecordValue(record, field.key)}</Text>\n        ),\n      }))\n  ), [normalizedFields, visibleKeys]);\n\n  const allColumnsVisible = visibleKeys.length === normalizedFields.length;\n  const someColumnsVisible = visibleKeys.length > 0 && !allColumnsVisible;\n\n  const toggleColumn = (key, checked) => {\n    setVisibleColumnKeys((current) => {\n      const currentKeys = current.length ? current : normalizedFields.map((field) => field.key);\n      if (checked) return currentKeys.includes(key) ? currentKeys : [...currentKeys, key];\n      return currentKeys.filter((columnKey) => columnKey !== key);\n    });\n  };\n\n  const columnVisibilityContent = (\n    <div className=\"column-visibility-menu\" onClick={(event) => event.stopPropagation()}>\n      <Checkbox\n        checked={allColumnsVisible}\n        indeterminate={someColumnsVisible}\n        onChange={(event) => {\n          setVisibleColumnKeys(event.target.checked ? normalizedFields.map((field) => field.key) : []);\n        }}\n      >\n        Select All\n      </Checkbox>\n      {normalizedFields.map((field) => (\n        <Checkbox\n          key={field.key}\n          checked={visibleKeys.includes(field.key)}\n          onChange={(event) => toggleColumn(field.key, event.target.checked)}\n        >\n          {field.label}\n        </Checkbox>\n      ))}\n    </div>\n  );\n\n  return (\n    <div className={`antd dynamic-list-view ${className}`.trim()}>\n      <Card>\n        <Flex align=\"center\" justify=\"space-between\">\n          <Tabs\n            activeKey={activeTab}\n            items={[{ key: 'all', label: tabLabel(listName, displayTotal) }]}\n            onChange={(key) => {\n              setActiveTab(key);\n              setPagination({ ...pagination, current: 1 });\n            }}\n          />\n          <Flex align=\"center\" gap={8}>\n            <Input\n              prefix={<SearchOutlined className=\"job-search-icon\" />}\n              placeholder=\"Min 3 Chars to search\"\n              value={search}\n              onChange={(e) => {\n                const val = e.target.value;\n                setSearch(val);\n                if (onSearch) {\n                  clearTimeout(searchTimerRef.current);\n                  searchTimerRef.current = setTimeout(() => {\n                    onSearch(val);\n                    onPageChange?.(1);\n                  }, 350);\n                } else if (isControlledPagination) {\n                  onPageChange?.(1);\n                } else {\n                  setPagination({ ...pagination, current: 1 });\n                }\n              }}\n              allowClear\n              className=\"job-search-input\"\n            />\n            <Tooltip title=\"Filter\">\n              <Button className=\"job-toolbar-icon-button\" icon={<FilterOutlined />} />\n            </Tooltip>\n            <Tooltip title=\"Card view\">\n              <Button\n                className={`job-toolbar-icon-button param-view-toggle-btn${activeView === 'card' ? ' param-view-toggle-btn--active' : ''}`}\n                icon={<AppstoreOutlined />}\n                onClick={() => onViewChange?.('card')}\n              />\n            </Tooltip>\n            <Tooltip title=\"List view\">\n              <Button\n                className={`job-toolbar-icon-button param-view-toggle-btn${activeView === 'list' ? ' param-view-toggle-btn--active' : ''}`}\n                icon={<UnorderedListOutlined />}\n                onClick={() => onViewChange?.('list')}\n              />\n            </Tooltip>\n          </Flex>\n        </Flex>\n      </Card>\n\n      <Card>\n        <Flex align=\"center\" gap={3}>\n          <Dropdown\n            open={columnMenuOpen}\n            onOpenChange={setColumnMenuOpen}\n            trigger={['click']}\n            dropdownRender={() => columnVisibilityContent}\n            placement=\"bottomLeft\"\n            overlayClassName=\"column-visibility-dropdown\"\n          >\n            <Button\n              type=\"text\"\n              icon={<img src={unorderedListOutlinedIcon} alt=\"\" className=\"job-action-list-icon\" />}\n              size=\"small\"\n              className=\"job-actions-button\"\n            />\n          </Dropdown>\n          {selectedRowKeys.length > 0 && (\n            <>\n              <Dropdown menu={{ items: menuItems }} trigger={['click']}>\n                <Button\n                  type=\"text\"\n                  size=\"small\"\n                  className=\"job-actions-button job-actions-menu-button\"\n                >\n                  <img src={frameIcon} alt=\"\" className=\"job-actions-frame-icon\" />\n                  Actions <DownOutlined className=\"job-actions-caret\" />\n                </Button>\n              </Dropdown>\n              <Text className=\"job-selected-count\">\n                Selected ({selectedRowKeys.length})\n              </Text>\n            </>\n          )}\n        </Flex>\n      </Card>\n\n      <Spin spinning={loading}>\n        <Table\n          rowSelection={rowSelection ? {\n            type: 'checkbox',\n            selectedRowKeys,\n            // onChange: setSelectedRowKeys,\n            onChange: (keys, rows) => {\n              setSelectedRowKeys(keys);\n              setSelectedRows(rows);\n            },\n          } : undefined}\n          columns={columns}\n          dataSource={pagedData}\n          size=\"middle\"\n          scroll={{ x: 'max-content' }}\n          showSorterTooltip={false}\n          tableLayout=\"auto\"\n          pagination={false}\n          className={tableClassName}\n          rowKey={(record) => record.id ?? record.key}\n        />\n      </Spin>\n\n      <CustomPagination\n        current={activePagination.current}\n        pageSize={activePagination.pageSize}\n        total={displayTotal}\n        onChange={(page) => {\n          if (isControlledPagination) onPageChange?.(page);\n          else setPagination((currentState) => ({ ...currentState, current: page }));\n        }}\n        onPageSizeChange={(size) => {\n          if (isControlledPagination) onPageSizeChange?.(size);\n          else setPagination({ current: 1, pageSize: size });\n        }}\n      />\n    </div>\n  );\n}\n","import { InputNumber, Slider, Space } from 'antd';\nimport PropTypes from 'prop-types';\n\n// How the range is presented. The admin picks this per field, so a team that\n// dislikes the horizontal slider can fall back to plain From/To boxes without\n// any code change.\nconst RANGE_DISPLAYS = ['both', 'slider', 'inputs'];\n\n// Value is always [from, to]. The slider and the number boxes are two views of\n// that one tuple, so editing either updates the other.\nexport default function RangeSliderField({ field, value, onChange, disabled }) {\n  const min = Number(field.min ?? 0);\n  const max = Number(field.max ?? 30);\n  const display = RANGE_DISPLAYS.includes(field.display) ? field.display : 'both';\n\n  const current = Array.isArray(value) && value.length === 2 ? value : [undefined, undefined];\n  const [from, to] = current;\n\n  // All three are admin-configurable so this stays generic: a salary range would\n  // read \"Min / Max / USD\" without touching this component. `unit` is optional —\n  // omit it and the numbers stand alone, since the field's own label usually\n  // already names the unit.\n  const fromLabel = field.fromLabel ?? 'From';\n  const toLabel = field.toLabel ?? 'To';\n  const unit = field.unit ?? '';\n\n  // What the two ends READ AS. Blank falls back to the bound itself, so an admin\n  // who raises Max from 30 to 40 gets a track labelled 40 without also having to\n  // remember to edit the caption.\n  const minLabel = String(field.minLabel ?? '').trim() || String(min);\n  const maxLabel = String(field.maxLabel ?? '').trim() || String(max);\n\n  // The two ends stay labelled under the track at all times; everything between\n  // them is read off the tooltip riding the handle. `marks` is the escape hatch\n  // for a mid-point label and wins outright when set.\n  const marks = field.marks ?? { [min]: minLabel, [max]: maxLabel };\n\n  // The number boxes DO borrow the end labels — the To box reads \"30+\" when it\n  // sits on the ceiling. The tooltip deliberately does not: it tracks a handle\n  // being dragged, where a label that stops counting at the last step reads as\n  // the drag having stuck.\n  //\n  // While the user is mid-keystroke their own text is echoed back untouched.\n  // Substituting the label there would fight the caret: typing \"3\" then \"0\"\n  // against a max of 30 would rewrite the box to \"30+\" and send the next\n  // keystroke after the plus.\n  const formatBound = (val, info) => {\n    if (info?.userTyping) return info.input;\n    if (val === null || val === undefined || val === '') return '';\n    if (Number(val) === min) return minLabel;\n    if (Number(val) === max) return maxLabel;\n    return String(val);\n  };\n\n  // Inverse of formatBound: what the user sees typed back into a number antd can\n  // hold. Anything else falls back to stripping non-numerics, so pasting \"12 yrs\"\n  // still lands on 12 rather than clearing the box.\n  const parseBound = (text) => {\n    const raw = String(text ?? '').trim();\n    if (raw === '') return '';\n    if (raw === maxLabel) return String(max);\n    if (raw === minLabel) return String(min);\n    return raw.replace(/[^0-9.-]/g, '');\n  };\n\n  const emit = (next) => {\n    const lo = next[0] === null || next[0] === undefined || next[0] === '' ? undefined : Number(next[0]);\n    const hi = next[1] === null || next[1] === undefined || next[1] === '' ? undefined : Number(next[1]);\n    if (lo === undefined && hi === undefined) {\n      onChange(undefined);\n      return;\n    }\n    // Dragging the low handle past the high one (or typing 10 then 2) would\n    // otherwise send an inverted range the backend rejects.\n    if (lo !== undefined && hi !== undefined) {\n      onChange([Math.min(lo, hi), Math.max(lo, hi)]);\n      return;\n    }\n    onChange([lo, hi]);\n  };\n\n  return (\n    <div className=\"sbv1-range\">\n      {display !== 'inputs' && (\n        <Slider\n          range\n          min={min}\n          max={max}\n          marks={marks}\n          disabled={disabled}\n          value={[from ?? min, to ?? max]}\n          // The marks label only the two END points, so a handle dragged\n          // somewhere in between would otherwise show no number at all. antd's\n          // default tooltip rides the handle showing the raw number, which is\n          // exactly the reading wanted — the value stays where the eye already\n          // is, and it keeps counting right up to the ceiling.\n          onChange={emit}\n        />\n      )}\n      {display !== 'slider' && (\n        <Space size={8} className=\"sbv1-range-inputs\">\n          {/* Visible labels rather than placeholders: a placeholder disappears\n              the moment a value is typed, leaving two bare boxes with no way to\n              tell which end is which. */}\n          <span className=\"sbv1-range-label\">{fromLabel}</span>\n          <InputNumber\n            size=\"small\"\n            min={min}\n            max={max}\n            disabled={disabled}\n            value={from ?? null}\n            placeholder={minLabel}\n            aria-label={fromLabel}\n            formatter={formatBound}\n            parser={parseBound}\n            onChange={(next) => emit([next, to])}\n          />\n          <span className=\"sbv1-range-label\">{toLabel}</span>\n          <InputNumber\n            size=\"small\"\n            min={min}\n            max={max}\n            disabled={disabled}\n            value={to ?? null}\n            placeholder={maxLabel}\n            aria-label={toLabel}\n            formatter={formatBound}\n            parser={parseBound}\n            onChange={(next) => emit([from, next])}\n          />\n          {unit && <span className=\"sbv1-range-label\">{unit}</span>}\n        </Space>\n      )}\n    </div>\n  );\n}\n\nRangeSliderField.propTypes = {\n  field: PropTypes.object.isRequired,\n  value: PropTypes.array,\n  onChange: PropTypes.func.isRequired,\n  disabled: PropTypes.bool,\n};\n","import dayjs from 'dayjs';\n\n// Same seven presets as the (never-wired) reference implementation\n// (CORE-THEME history: SourceCandidatePage.jsx dateMenuItems) — kept\n// identical so the UI matches what was already designed for this.\nexport const DATE_RANGE_PRESETS = [\n  { key: 'today', label: 'Today' },\n  { key: 'yesterday', label: 'Yesterday' },\n  { key: 'last7', label: 'Last 7 Days' },\n  { key: 'last30', label: 'Last 30 Days' },\n  { key: 'thisMonth', label: 'This Month' },\n  { key: 'lastMonth', label: 'Last Month' },\n  { key: 'custom', label: 'Custom Range' },\n];\n\nexport const DATE_FORMAT = 'YYYY-MM-DD';\n\n// Mirrors the day-boundary style DynamicFieldFilter.jsx's DATE_SHORTCUTS\n// already uses (subtract(6,'day') for \"last 7\", startOf('month') for \"this\n// month\"), so the two date-shortcut UIs in the app agree on what \"last 7\n// days\" actually means.\nexport function resolvePresetRange(preset) {\n  const now = dayjs();\n  switch (preset) {\n    case 'today':\n      return [now.startOf('day'), now.endOf('day')];\n    case 'yesterday': {\n      const yesterday = now.subtract(1, 'day');\n      return [yesterday.startOf('day'), yesterday.endOf('day')];\n    }\n    case 'last7':\n      return [now.subtract(6, 'day').startOf('day'), now.endOf('day')];\n    case 'last30':\n      return [now.subtract(29, 'day').startOf('day'), now.endOf('day')];\n    case 'thisMonth':\n      return [now.startOf('month'), now.endOf('day')];\n    case 'lastMonth': {\n      const lastMonth = now.subtract(1, 'month');\n      return [lastMonth.startOf('month'), lastMonth.endOf('month')];\n    }\n    default:\n      return [null, null];\n  }\n}\n\n// Plain display formatter. NOT for filter values — see the two below.\nexport function toDateString(value) {\n  return value ? dayjs(value).format(DATE_FORMAT) : null;\n}\n\n// Both range ends are sent as full ISO instants rather than bare 'YYYY-MM-DD'\n// strings, because the backend (Be_Auth_DevOps models/moduleDataList.go\n// castFilterValue) reads a bare date as MIDNIGHT UTC. That silently clipped\n// both ends for anyone not on UTC:\n//\n//   to   → \"2026-08-14\" meant 00:00, excluding everything created that day\n//   from → \"2026-08-02\" meant 05:30 IST, excluding that morning\n//\n// A full instant lands on castFilterValue's RFC3339 branch instead, so both\n// ends agree that a \"day\" is the user's local calendar day.\nexport function toEndOfDayString(value) {\n  return value ? dayjs(value).endOf('day').toISOString() : null;\n}\n\nexport function toStartOfDayString(value) {\n  return value ? dayjs(value).startOf('day').toISOString() : null;\n}\n","import { DatePicker, Select } from 'antd';\nimport dayjs from 'dayjs';\nimport PropTypes from 'prop-types';\nimport { DATE_RANGE_PRESETS, resolvePresetRange, toEndOfDayString, toStartOfDayString } from './dateRangePresets';\n\nconst { RangePicker } = DatePicker;\n\n// Value shape: { preset, from, to } — resolved at selection time so\n// buildFilterConditions never redoes date math. Both ends are full ISO\n// datetimes covering the user's local calendar day (start-of-day / end-of-day);\n// a bare YYYY-MM-DD would be read server-side as midnight UTC, which clips\n// either end for anyone not on UTC.\nexport default function DateRangePresetField({ field, value, onChange, disabled }) {\n  const current = value && typeof value === 'object' ? value : {};\n  const preset = current.preset;\n\n  const handlePresetChange = (nextPreset) => {\n    if (nextPreset === 'custom') {\n      // Nothing resolved yet — wait for the RangePicker below.\n      onChange({ preset: nextPreset, from: null, to: null });\n      return;\n    }\n    const [from, to] = resolvePresetRange(nextPreset);\n    onChange({ preset: nextPreset, from: toStartOfDayString(from), to: toEndOfDayString(to) });\n  };\n\n  const handleCustomRangeChange = (dates) => {\n    const [from, to] = Array.isArray(dates) ? dates : [null, null];\n    onChange({ preset: 'custom', from: toStartOfDayString(from), to: toEndOfDayString(to) });\n  };\n\n  const customRangeValue = preset === 'custom' && (current.from || current.to)\n    ? [current.from ? dayjs(current.from) : null, current.to ? dayjs(current.to) : null]\n    : null;\n\n  return (\n    <div className=\"sbv1-date-range-preset\">\n      <Select\n        value={preset}\n        disabled={disabled}\n        allowClear\n        placeholder={field.placeholder ?? 'Select date'}\n        options={DATE_RANGE_PRESETS.map(({ key, label }) => ({ value: key, label }))}\n        onChange={handlePresetChange}\n        onClear={() => onChange(undefined)}\n      />\n      {preset === 'custom' && (\n        // A plain RangePicker — clicking the Start Date segment opens the\n        // calendar by antd's own default behaviour, nothing custom needed.\n        <RangePicker\n          style={{ width: '100%', marginTop: 8 }}\n          disabled={disabled}\n          value={customRangeValue}\n          disabledDate={(current_) => current_ && current_.isAfter(dayjs(), 'day')}\n          onChange={handleCustomRangeChange}\n        />\n      )}\n    </div>\n  );\n}\n\nDateRangePresetField.propTypes = {\n  field: PropTypes.object.isRequired,\n  value: PropTypes.object,\n  onChange: PropTypes.func.isRequired,\n  disabled: PropTypes.bool,\n};\n","import { Checkbox, DatePicker, Input, InputNumber, Radio, Select, Space, Spin } from 'antd';\nimport RangeSliderField from './RangeSliderField.jsx';\nimport DateRangePresetField from './DateRangePresetField.jsx';\n\nconst { TextArea } = Input;\nconst { RangePicker } = DatePicker;\n\n// Every renderer is called with the same props, so a new input type never has to\n// re-implement option fetching, disabled handling or Form wiring:\n//   { field, value, onChange, options, optionsLoading, disabled, placeholder }\n//\n// Registry entry flags:\n//   booleanEligible — admins may mark fields of this type \"Boolean capable\"\n//   needsOptions    — SearchFieldControl resolves field.dataSource before rendering\n//   multiValue      — the control emits an array, mapped onto several API params\nexport const FIELD_TYPE_REGISTRY = {};\n\nexport function registerFieldType(type, definition) {\n  if (!type || typeof definition?.render !== 'function') {\n    throw new Error('registerFieldType(type, { render }) requires a type name and a render function');\n  }\n  FIELD_TYPE_REGISTRY[type] = {\n    booleanEligible: false,\n    needsOptions: false,\n    multiValue: false,\n    ...definition,\n  };\n  return FIELD_TYPE_REGISTRY[type];\n}\n\nexport function getFieldType(type) {\n  return FIELD_TYPE_REGISTRY[type] ?? FIELD_TYPE_REGISTRY.text;\n}\n\nexport function isBooleanEligible(type) {\n  return Boolean(getFieldType(type).booleanEligible);\n}\n\nexport function getBooleanEligibleTypes() {\n  return Object.entries(FIELD_TYPE_REGISTRY)\n    .filter(([, definition]) => definition.booleanEligible)\n    .map(([type]) => type);\n}\n\nfunction enterText(field) {\n  return `Enter ${String(field.label ?? field.field ?? '').toLowerCase()}`;\n}\n\nfunction selectText(field) {\n  return `Select ${String(field.label ?? field.field ?? '').toLowerCase()}`;\n}\n\nregisterFieldType('text', {\n  booleanEligible: true,\n  render: ({ field, value, onChange, disabled, placeholder }) => (\n    <Input\n      value={value ?? ''}\n      disabled={disabled}\n      placeholder={placeholder ?? enterText(field)}\n      allowClear\n      onChange={(event) => onChange(event.target.value)}\n    />\n  ),\n});\n\nregisterFieldType('email', {\n  booleanEligible: true,\n  render: ({ field, value, onChange, disabled, placeholder }) => (\n    <Input\n      type=\"email\"\n      value={value ?? ''}\n      disabled={disabled}\n      placeholder={placeholder ?? enterText(field)}\n      allowClear\n      onChange={(event) => onChange(event.target.value)}\n    />\n  ),\n});\n\nregisterFieldType('textarea', {\n  booleanEligible: true,\n  render: ({ field, value, onChange, disabled, placeholder }) => (\n    <TextArea\n      rows={field.rows ?? 3}\n      value={value ?? ''}\n      disabled={disabled}\n      placeholder={placeholder ?? enterText(field)}\n      onChange={(event) => onChange(event.target.value)}\n    />\n  ),\n});\n\nregisterFieldType('number', {\n  render: ({ field, value, onChange, disabled, placeholder }) => (\n    <InputNumber\n      style={{ width: '100%' }}\n      value={value ?? null}\n      disabled={disabled}\n      min={field.min}\n      max={field.max}\n      placeholder={placeholder ?? enterText(field)}\n      onChange={onChange}\n    />\n  ),\n});\n\nregisterFieldType('select', {\n  booleanEligible: true,\n  needsOptions: true,\n  render: ({ field, value, onChange, options, optionsLoading, disabled, placeholder }) => (\n    <Select\n      mode={field.multiSelect || field.mode === 'multiple' ? 'multiple' : undefined}\n      value={value ?? undefined}\n      disabled={disabled}\n      options={options}\n      loading={optionsLoading}\n      allowClear\n      showSearch\n      optionFilterProp=\"label\"\n      placeholder={placeholder ?? selectText(field)}\n      notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n      onChange={onChange}\n    />\n  ),\n});\n\nregisterFieldType('multiselect', {\n  booleanEligible: true,\n  needsOptions: true,\n  multiValue: true,\n  render: ({ field, value, onChange, options, optionsLoading, disabled, placeholder }) => (\n    <Select\n      mode=\"multiple\"\n      value={value ?? undefined}\n      disabled={disabled}\n      options={options}\n      loading={optionsLoading}\n      allowClear\n      showSearch\n      optionFilterProp=\"label\"\n      placeholder={placeholder ?? selectText(field)}\n      notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n      onChange={onChange}\n    />\n  ),\n});\n\n// Live search configs use type:\"location\" for a single location picker, so it\n// resolves against the location master unless the config says otherwise.\nregisterFieldType('location', {\n  needsOptions: true,\n  defaultDataSource: 'locationMaster',\n  render: ({ field, value, onChange, options, optionsLoading, disabled, placeholder }) => (\n    <Select\n      value={value ?? undefined}\n      disabled={disabled}\n      options={options}\n      loading={optionsLoading}\n      allowClear\n      showSearch\n      optionFilterProp=\"label\"\n      placeholder={placeholder ?? selectText(field)}\n      notFoundContent={optionsLoading ? <Spin size=\"small\" /> : undefined}\n      onChange={onChange}\n    />\n  ),\n});\n\n// Free-text multi-entry: type a value, press Enter, it becomes a chip. Boolean\n// eligible because a skills-style field is the most common boolean target.\nregisterFieldType('tagify', {\n  booleanEligible: true,\n  multiValue: true,\n  render: ({ field, value, onChange, disabled, placeholder }) => (\n    <Select\n      mode=\"tags\"\n      value={value ?? undefined}\n      disabled={disabled}\n      open={false}\n      suffixIcon={null}\n      allowClear\n      tokenSeparators={[',']}\n      placeholder={placeholder ?? enterText(field)}\n      onChange={onChange}\n    />\n  ),\n});\n\n// A \"locked\" option (admin-configured, off by default — see FormGroupsSection\n// Options/Values editor) is pre-selected and cannot be deselected, e.g.\n// \"Internal\" always included in Search Preference. Radio only allows one\n// selection at all, so a locked radio option fixes the whole group to it\n// (disabled) rather than mixing \"one fixed, others free\" into a\n// mutually-exclusive control where that has no real meaning.\nregisterFieldType('radio', {\n  needsOptions: true,\n  render: ({ value, onChange, options, disabled }) => {\n    const locked = options.find((option) => option.locked);\n    return (\n      <Radio.Group\n        value={locked ? locked.value : value}\n        disabled={disabled || Boolean(locked)}\n        options={options}\n        onChange={(event) => onChange(event.target.value)}\n      />\n    );\n  },\n});\n\n// An \"All\" checkbox is automatic, not admin-authored: any checkbox field\n// with more than one option gets one, unless the field explicitly opts out\n// (field.hideSelectAll — FormGroupsSection's one field-level switch). It is\n// never part of `options` and never enters the submitted value — its\n// checked state is computed fresh every render from whether every real\n// option is currently selected, so it can never visibly disagree with\n// reality the way a stored trigger flag could. `locked` (per-option,\n// admin-configured, unrelated to this) still composes for free, since the\n// derived state reads from the already-locked-merged value.\nregisterFieldType('checkbox', {\n  needsOptions: true,\n  multiValue: true,\n  render: ({ field, value, onChange, options, disabled }) => {\n    if (options.length === 0) {\n      return (\n        <Checkbox\n          checked={Boolean(value)}\n          disabled={disabled}\n          onChange={(event) => onChange(event.target.checked)}\n        >\n          {field.checkboxLabel ?? field.label}\n        </Checkbox>\n      );\n    }\n\n    const lockedValues = options.filter((option) => option.locked).map((option) => option.value);\n    const allValues = options.map((option) => option.value);\n    const current = Array.isArray(value) ? value : [];\n\n    // Every read and write goes through here, so the stored value is always in\n    // the admin's configured option order. Downstream this value IS the\n    // source-tab order (SearchBuilderV1 -> getSearchSources -> buildSourceTabs),\n    // and the merges below concatenate lockedValues onto whatever came in — so a\n    // locked value merged into a stored or seeded value could otherwise land out\n    // of order and reorder the tab strip. antd already hands the group's value\n    // back in options order, so this is a guarantee at the boundary rather than\n    // a fix for a live bug; the tab reordering itself was buildSourceTabs.\n    const orderByOptions = (values) => {\n      const wanted = new Set(values);\n      return allValues.filter((option) => wanted.has(option));\n    };\n\n    // Seeds locked values in even before any Form initialValue has resolved,\n    // and guards against them ever being missing from what's displayed.\n    const effectiveValue = orderByOptions([...current, ...lockedValues]);\n    const groupOptions = options.map((option) => (\n      option.locked ? { ...option, disabled: true } : option\n    ));\n\n    const handleGroupChange = (next) => {\n      onChange(orderByOptions([...next, ...lockedValues]));\n    };\n\n    const showSelectAll = field.hideSelectAll !== true && options.length > 1;\n    const allChecked = showSelectAll && allValues.every((v) => effectiveValue.includes(v));\n    const handleSelectAllChange = (event) => {\n      onChange(event.target.checked ? orderByOptions(allValues) : orderByOptions(lockedValues));\n    };\n\n    return (\n      <Space direction=\"vertical\" size={4} className=\"sbv1-checkbox-with-select-all\">\n        {showSelectAll && (\n          <Checkbox checked={allChecked} disabled={disabled} onChange={handleSelectAllChange}>\n            All\n          </Checkbox>\n        )}\n        <Checkbox.Group\n          value={effectiveValue}\n          disabled={disabled}\n          options={groupOptions}\n          onChange={handleGroupChange}\n        />\n      </Space>\n    );\n  },\n});\n\nregisterFieldType('date', {\n  render: ({ value, onChange, disabled, placeholder }) => (\n    <DatePicker\n      style={{ width: '100%' }}\n      value={value ?? null}\n      disabled={disabled}\n      placeholder={placeholder ?? 'Select date'}\n      onChange={onChange}\n    />\n  ),\n});\n\nregisterFieldType('daterange', {\n  multiValue: true,\n  render: ({ value, onChange, disabled }) => (\n    <RangePicker\n      style={{ width: '100%' }}\n      value={value ?? null}\n      disabled={disabled}\n      onChange={onChange}\n    />\n  ),\n});\n\n// The experience \"dragger\" — one config field, two values.\nregisterFieldType('range', {\n  multiValue: true,\n  render: (props) => <RangeSliderField {...props} />,\n});\n\n// Preset dropdown (Today/Yesterday/.../Custom Range) that reveals a\n// RangePicker for Custom Range. Not booleanEligible — the boolean-search API\n// has no date parameter at all (Be_Auth_DevOps/models/boolean_search.go), so\n// this field can never contribute to a boolean request in any mapping.\nregisterFieldType('daterangePreset', {\n  multiValue: true,\n  render: (props) => <DateRangePresetField {...props} />,\n});\n","import { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { getDropdownValues } from '../../services/moduleDataApi';\nimport { getFieldType } from './fieldTypeRegistry.jsx';\n\nfunction normalizeOptions(options = []) {\n  if (!Array.isArray(options)) return [];\n  return options\n    .map((option) => {\n      if (option === null || option === undefined) return null;\n      if (typeof option === 'string' || typeof option === 'number') {\n        return { label: String(option), value: option };\n      }\n      const label = option.label ?? option.name ?? option.value ?? option.id;\n      const value = option.value ?? option.id ?? option.name ?? option.label;\n      if (value === undefined) return null;\n      // Preserved (not just label/value) so checkbox/radio can pre-select and\n      // disable it — a remote source could plausibly carry this too, even\n      // though today only the static admin-authored list does.\n      return { label: String(label ?? value), value, locked: Boolean(option.locked) };\n    })\n    .filter(Boolean);\n}\n\n// Resolves a field's options once, for any registry type flagged needsOptions,\n// so individual renderers never touch the network.\nexport default function SearchFieldControl({ field, moduleName, value, onChange, disabled }) {\n  const definition = getFieldType(field.type ?? 'text');\n  // A type may declare where its options come from (location → location master)\n  // so an existing config that never set dataSource still resolves them.\n  const dataSource = field.dataSource ?? definition.defaultDataSource ?? 'static';\n  const isRemote = Boolean(definition.needsOptions) && dataSource !== 'static';\n\n  const staticOptions = useMemo(\n    () => normalizeOptions(field.options ?? field.values ?? []),\n    [field.options, field.values],\n  );\n  const [remoteOptions, setRemoteOptions] = useState(null);\n  // Seeded from isRemote rather than flipped inside the effect: a remote field\n  // is loading from its first render, so there is nothing to announce later.\n  const [optionsLoading, setOptionsLoading] = useState(isRemote);\n\n  useEffect(() => {\n    if (!isRemote) return undefined;\n\n    let cancelled = false;\n\n    (async () => {\n      try {\n        const raw = await getDropdownValues(moduleName, field.field, '', 200, 0, {\n          dataSource,\n          masterName: field.masterName,\n          groupName: field.groupName,\n        });\n        const list = Array.isArray(raw) ? raw : (raw?.data ?? raw?.values ?? []);\n        if (!cancelled) setRemoteOptions(normalizeOptions(list));\n      } catch (error) {\n        console.error(`[SearchBuilderV1] Failed to load options for \"${field.field}\":`, error);\n        if (!cancelled) setRemoteOptions([]);\n      } finally {\n        if (!cancelled) setOptionsLoading(false);\n      }\n    })();\n\n    return () => { cancelled = true; };\n  }, [isRemote, dataSource, field.field, field.masterName, field.groupName, moduleName]);\n\n  return definition.render({\n    field,\n    value,\n    onChange: onChange ?? (() => {}),\n    options: remoteOptions ?? staticOptions,\n    optionsLoading,\n    disabled,\n    placeholder: field.placeholder,\n    moduleName,\n  });\n}\n\nSearchFieldControl.propTypes = {\n  field: PropTypes.object.isRequired,\n  moduleName: PropTypes.string,\n  value: PropTypes.any,\n  onChange: PropTypes.func,\n  disabled: PropTypes.bool,\n};\n","import { Input } from 'antd';\nimport PropTypes from 'prop-types';\n\nconst { TextArea } = Input;\n\n// Just the textarea. The AND/OR/NOT/()/\"\" insert buttons that used to sit\n// under it were dropped as visual clutter — the placeholder already spells the\n// whole syntax out. insertTokenAtCursor (booleanQueryUtils) still ships as a\n// library export for any project that wants to build its own toolbar.\n//\n// Client-side grammar errors/warnings are not validated in here — they're\n// wired as antd Form.Item `rules` on the parent (one blocking, one\n// `warningOnly`), so antd's own validateStatus/help rendering handles them\n// consistently with every other field on the form. The only thing still shown\n// locally is a server-rejected query, which is necessarily async and outside\n// the rules lifecycle.\nexport default function BooleanQueryField({ field, value, onChange, disabled, serverError }) {\n  return (\n    <div className=\"sbv1-boolean-field\">\n      <TextArea\n        rows={field.rows ?? 3}\n        value={value ?? ''}\n        disabled={disabled}\n        status={serverError ? 'error' : undefined}\n        placeholder={field.booleanPlaceholder ?? '(Java OR J2EE) AND \"Spring Boot\" NOT Hibernate'}\n        onChange={(event) => onChange(event.target.value)}\n      />\n      {serverError && <div className=\"v1-input-validator-hint\">{serverError}</div>}\n    </div>\n  );\n}\n\nBooleanQueryField.propTypes = {\n  field: PropTypes.object.isRequired,\n  value: PropTypes.string,\n  onChange: PropTypes.func.isRequired,\n  disabled: PropTypes.bool,\n  serverError: PropTypes.string,\n};\n","// Client-side approximation of the Go grammar in Be_Auth_DevOps\n// models/boolean_search.go. It exists to catch the common mistakes before a\n// round trip; the server stays the authority and its INVALID_BOOLEAN_QUERY\n// details surface in the same inline slot as these messages.\n\nconst BINARY_OPERATORS = new Set(['AND', 'OR']);\nconst OPERATORS = new Set(['AND', 'OR', 'NOT']);\n\nexport function tokenizeBooleanQuery(query) {\n  const text = String(query ?? '');\n  const tokens = [];\n  let i = 0;\n\n  while (i < text.length) {\n    const char = text[i];\n\n    if (/\\s/.test(char)) { i += 1; continue; }\n\n    if (char === '(' || char === ')') {\n      tokens.push({ type: char === '(' ? 'lparen' : 'rparen', value: char });\n      i += 1;\n      continue;\n    }\n\n    if (char === '\"') {\n      const close = text.indexOf('\"', i + 1);\n      if (close === -1) {\n        tokens.push({ type: 'unterminated', value: text.slice(i) });\n        break;\n      }\n      tokens.push({ type: 'term', value: text.slice(i + 1, close), quoted: true });\n      i = close + 1;\n      continue;\n    }\n\n    let end = i;\n    while (end < text.length && !/[\\s()\"]/.test(text[end])) end += 1;\n    const word = text.slice(i, end);\n    const upper = word.toUpperCase();\n    tokens.push(OPERATORS.has(upper) ? { type: 'operator', value: upper } : { type: 'term', value: word });\n    i = end;\n  }\n\n  return tokens;\n}\n\n// Tokens people carry over from other search tools that mean something\n// different (or nothing) to this grammar — flagged as a hint on the operator\n// term itself, distinct from the AND/OR/NOT set the tokenizer already parses.\nconst FOREIGN_OPERATOR_HINTS = [\n  { pattern: /&&/, message: 'Use AND instead of &&.' },\n  { pattern: /\\|\\|/, message: 'Use OR instead of ||.' },\n  { pattern: /(?:^|\\s)!(?=\\S)/, message: 'Use NOT instead of !.' },\n];\n\nconst MAX_COMFORTABLE_DEPTH = 4;\nconst MAX_COMFORTABLE_TERMS = 12;\n\n// Only these BooleanSearchRequest params are actually run through the Go\n// tokenizer/parser (candidateBooleanSearchController.go — Query/Skills/\n// JobTitle/Designation). Every other param (currentLocation, experience.*,\n// sourceType, …) is a plain substring/exact match server-side. A field\n// mapped to one of those but marked booleanCapable would send a literal\n// \"(hyderabad OR pune)\" as search text and silently return nothing — legal\n// JSON, wrong behaviour, no error anywhere. This is the allowlist that keeps\n// the admin UI and the runtime component from allowing that combination.\nexport const BOOLEAN_PARSEABLE_API_KEYS = ['query', 'skills', 'jobTitle', 'designation'];\nconst PARSEABLE_SET = new Set(BOOLEAN_PARSEABLE_API_KEYS);\n\nexport function isBooleanParsable(apiKey) {\n  if (Array.isArray(apiKey)) return apiKey.length === 1 && PARSEABLE_SET.has(apiKey[0]);\n  return PARSEABLE_SET.has(apiKey);\n}\n\n// Two tiers, matching how the two kinds of \"wrong\" actually differ:\n//   errors   — the grammar itself is broken (unbalanced brackets, a dangling\n//              operator, \"&&\" instead of \"AND\"). The backend's own parser\n//              would reject these too, so blocking here just saves the round\n//              trip.\n//   warnings — grammatically legal but likely not what was intended (an\n//              expression that's ALL exclusions and so matches almost\n//              everyone; a bare \"*\"/\"?\" the backend treats as a literal\n//              character, not a wildcard, per regexp.QuoteMeta in\n//              Be_Auth_DevOps/models/boolean_search.go — so it silently\n//              returns nothing rather than erroring). These never block\n//              Search; a query can be legal and still worth a second look.\nexport function validateBooleanQuery(query) {\n  const errors = [];\n  const warnings = [];\n  const text = String(query ?? '').trim();\n  if (!text) return { valid: true, errors, warnings };\n\n  FOREIGN_OPERATOR_HINTS.forEach(({ pattern, message }) => {\n    if (pattern.test(text)) errors.push(message);\n  });\n\n  const tokens = tokenizeBooleanQuery(text);\n\n  if (tokens.some((token) => token.type === 'unterminated')) {\n    errors.push('Unclosed quote — every \" needs a closing \".');\n  }\n\n  let depth = 0;\n  let maxDepth = 0;\n  let closedTooEarly = false;\n  tokens.forEach((token) => {\n    if (token.type === 'lparen') {\n      depth += 1;\n      maxDepth = Math.max(maxDepth, depth);\n    } else if (token.type === 'rparen') {\n      depth -= 1;\n      if (depth < 0) { closedTooEarly = true; depth = 0; }\n    }\n  });\n  if (closedTooEarly || depth > 0) errors.push('Unbalanced parentheses.');\n\n  const parsed = tokens.filter((token) => token.type !== 'unterminated');\n  const termTokens = [];\n\n  parsed.forEach((token, index) => {\n    const prev = parsed[index - 1];\n    const next = parsed[index + 1];\n\n    if (token.type === 'operator') {\n      // NOT is unary, so it legitimately opens an expression (\"NOT Hibernate\")\n      // and legitimately follows a binary operator (\"Java AND NOT Python\").\n      const isBinary = BINARY_OPERATORS.has(token.value);\n      const missingLeft = !prev\n        || prev.type === 'lparen'\n        || (prev.type === 'operator' && BINARY_OPERATORS.has(prev.value));\n      if (isBinary && missingLeft) errors.push(`\"${token.value}\" needs a term before it.`);\n      if (!next || next.type === 'rparen') errors.push(`\"${token.value}\" needs a term after it.`);\n    }\n\n    if (token.type === 'lparen' && next?.type === 'rparen') errors.push('Empty parentheses.');\n\n    if (token.type === 'term') {\n      termTokens.push({ token, index });\n      if (!token.quoted && token.value.length === 1) {\n        warnings.push(`\"${token.value}\" is a single character and will match very broadly.`);\n      }\n      if (/[*?]/.test(token.value)) {\n        warnings.push(`\"${token.value}\" — * and ? are matched as literal characters here, not wildcards.`);\n      }\n    }\n  });\n\n  if (errors.length === 0 && termTokens.length > 0) {\n    // A term counts as \"excluded\" only when the nearest non-paren token\n    // before it is NOT — i.e. it's actually negated, not just near one.\n    const allExcluded = termTokens.every(({ index }) => {\n      for (let i = index - 1; i >= 0; i -= 1) {\n        const candidate = parsed[i];\n        if (candidate.type === 'lparen') continue;\n        return candidate.type === 'operator' && candidate.value === 'NOT';\n      }\n      return false;\n    });\n    if (allExcluded) {\n      warnings.push('This query is only exclusions and will match nearly everyone.');\n    }\n  }\n\n  if (maxDepth > MAX_COMFORTABLE_DEPTH) {\n    warnings.push(`Nested ${maxDepth} levels deep — consider simplifying so it stays easy to verify.`);\n  }\n  if (termTokens.length > MAX_COMFORTABLE_TERMS) {\n    warnings.push(`${termTokens.length} terms in one query — consider narrowing it.`);\n  }\n\n  return {\n    valid: errors.length === 0,\n    errors: [...new Set(errors)],\n    warnings: [...new Set(warnings)],\n  };\n}\n\n// Returns the next textarea value plus where the caret should land, so a\n// toolbar click behaves like typing at the cursor rather than appending.\nexport function insertTokenAtCursor(value, selectionStart, selectionEnd, token) {\n  const text = String(value ?? '');\n  const start = Math.max(0, Math.min(selectionStart ?? text.length, text.length));\n  const end = Math.max(start, Math.min(selectionEnd ?? start, text.length));\n\n  const before = text.slice(0, start);\n  const selected = text.slice(start, end);\n  const after = text.slice(end);\n\n  if (token === '()' || token === '\"\"') {\n    const [open, close] = token === '()' ? ['(', ')'] : ['\"', '\"'];\n    return {\n      value: `${before}${open}${selected}${close}${after}`,\n      cursor: selected ? start + selected.length + 2 : start + 1,\n    };\n  }\n\n  // Keep any selected text and place the operator after it — a toolbar click\n  // should never destroy what the user highlighted.\n  const head = before + selected;\n  const leading = head.length > 0 && !/\\s$/.test(head) ? ' ' : '';\n  const trailing = !/^\\s/.test(after) ? ' ' : '';\n  const insert = `${leading}${token}${trailing}`;\n\n  // When the following text already starts with a space, step over it so the\n  // next keystroke begins the next term instead of gluing onto the operator.\n  const skipExistingSpace = !trailing && /^\\s/.test(after) ? 1 : 0;\n\n  return {\n    value: `${head}${insert}${after}`,\n    cursor: head.length + insert.length + skipExistingSpace,\n  };\n}\n","// Maps form values onto the BooleanSearchRequest body using each field's\n// configured booleanApiKey. The enum mirrors the Go struct in\n// Be_Auth_DevOps models/boolean_search.go, which this frontend cannot change.\nexport const BOOLEAN_API_KEYS = [\n  'query',\n  'skills',\n  'jobTitle',\n  'designation',\n  'currentLocation',\n  'experience.from',\n  'experience.to',\n  'workExperienceYears',\n  'sourceType',\n  // Sent as a pair by a daterangePreset field. The Go BooleanSearchRequest does\n  // not declare these yet, so they are accepted and ignored server-side (Go's\n  // json.Decode drops unknown keys) until the boolean-search API adds them.\n  'createdFrom',\n  'createdTo',\n];\n\nconst NUMERIC_KEYS = new Set(['experience.from', 'experience.to', 'workExperienceYears']);\n\nfunction setDeep(body, key, value) {\n  if (!key.includes('.')) {\n    body[key] = value;\n    return;\n  }\n  const [root, leaf] = key.split('.');\n  body[root] = { ...(body[root] ?? {}), [leaf]: value };\n}\n\nfunction unwrap(raw) {\n  if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n    return raw.value ?? raw.label ?? raw.name ?? '';\n  }\n  return raw;\n}\n\nfunction coerce(key, input) {\n  const raw = unwrap(input);\n\n  if (NUMERIC_KEYS.has(key)) {\n    // Number('') is 0, and 0 is finite — without this guard an absent value (or\n    // an object unwrap that yielded '') would be sent as a real bound of zero.\n    if (raw === '' || raw === null || raw === undefined) return undefined;\n    const numeric = Number(raw);\n    return Number.isFinite(numeric) ? numeric : undefined;\n  }\n\n  if (Array.isArray(raw)) {\n    const parts = raw\n      .map(unwrap)\n      .filter((part) => part !== undefined && part !== null && String(part).trim() !== '');\n    if (!parts.length) return undefined;\n    // sourceType is a comma list server-side; every other string key is parsed\n    // as a boolean expression, so multi-select values become an OR group.\n    return key === 'sourceType' ? parts.join(',') : parts.join(' OR ');\n  }\n\n  const text = String(raw ?? '').trim();\n  return text === '' ? undefined : text;\n}\n\nexport function buildBooleanRequest(values = {}, fields = [], options = {}) {\n  const body = {};\n\n  fields.forEach((field) => {\n    const apiKey = field.booleanApiKey;\n    if (!apiKey) return;\n\n    const raw = values[field.field];\n    if (raw === undefined || raw === null || raw === '') return;\n\n    // A composite control (range slider, date range) maps one value tuple onto\n    // several request params. A range slider already holds a [from, to] array;\n    // a daterangePreset holds {preset, from, to}, so unpack it in the same order\n    // as its configured key pair.\n    if (Array.isArray(apiKey)) {\n      let parts;\n      if (Array.isArray(raw)) {\n        parts = raw;\n      } else if (raw && typeof raw === 'object' && ('from' in raw || 'to' in raw)) {\n        parts = [raw.from, raw.to];\n      } else {\n        parts = [raw];\n      }\n      apiKey.forEach((key, index) => {\n        const value = coerce(key, parts[index]);\n        if (value !== undefined) setDeep(body, key, value);\n      });\n      return;\n    }\n\n    const value = coerce(apiKey, raw);\n    if (value !== undefined) setDeep(body, apiKey, value);\n  });\n\n  // Only when the caller supplies one. This used to fall back to 'internal',\n  // which is Candidates vocabulary — a Jobs or Clients search form has no source\n  // picker at all, and sending it a sourceType it never configured is noise the\n  // backend has to ignore. The caller knows whether its form has the field.\n  if (!body.sourceType && options.defaultSourceType) {\n    body.sourceType = options.defaultSourceType;\n  }\n\n  // Which module's config answers for this search — the same key the traditional\n  // endpoint receives as ?module=, so both search modes resolve their columns,\n  // row actions and rules from one place. Omitted when the caller supplies none,\n  // so an existing form's payload is byte-identical to before.\n  if (options.module) body.module = String(options.module);\n\n  return body;\n}\n","import { getFieldType } from './fieldTypeRegistry.jsx';\n\n// Which two query params a composite control fills on the traditional list\n// endpoint. Configurable because param names differ per module; the default\n// covers the usual `<field>From` / `<field>To` pair.\nexport function rangeKeysFor(field) {\n  if (Array.isArray(field.rangeKeys) && field.rangeKeys.length === 2) return field.rangeKeys;\n  return [`${field.field}From`, `${field.field}To`];\n}\n\n// GET /module-data-list takes flat params, so a positional tuple ([from, to])\n// has to be split. A multi-select's list of chips is left alone — that is one\n// param the list endpoint already understands.\nexport function buildTraditionalParams(values = {}, fields = []) {\n  const params = { ...values };\n\n  fields.forEach((field) => {\n    const type = field.type ?? 'text';\n\n    // Sent via the generic `filters` mechanism instead (buildFilterConditions)\n    // — its {preset,from,to} object has no flat-param representation, so it\n    // must not reach the flatten-everything loop in searchModuleData.\n    if (type === 'daterangePreset') {\n      delete params[field.field];\n      return;\n    }\n\n    if (!getFieldType(type).multiValue) return;\n    if (type !== 'range' && type !== 'daterange') return;\n\n    const raw = values[field.field];\n    if (!Array.isArray(raw)) return;\n\n    const [fromKey, toKey] = rangeKeysFor(field);\n    delete params[field.field];\n\n    const [from, to] = raw;\n    if (from !== undefined && from !== null && from !== '') params[fromKey] = from;\n    if (to !== undefined && to !== null && to !== '') params[toKey] = to;\n  });\n\n  return params;\n}\n","// Produces rows in the exact shape Be_Auth_DevOps/models/moduleDataList.go's\n// FilterCondition already parses (field/op/value/operator), the same\n// mechanism DynamicFieldFilter.jsx's Filters drawer uses — reused here rather\n// than inventing a second convention for date-range filtering.\n//\n// Only daterangePreset fields participate today; the shape is generic\n// (op: gte/lte/...) so a future field type can emit rows the same way without\n// this function changing.\nexport function buildFilterConditions(values = {}, fields = []) {\n  const conditions = [];\n\n  fields.forEach((field) => {\n    if (field.type !== 'daterangePreset') return;\n\n    const raw = values[field.field];\n    const from = raw?.from;\n    const to = raw?.to;\n    if (!from && !to) return;\n\n    const targetField = field.filterField || field.field;\n    if (from) conditions.push({ field: targetField, op: 'gte', value: from, operator: 'and' });\n    if (to) conditions.push({ field: targetField, op: 'lte', value: to, operator: 'and' });\n  });\n\n  return conditions;\n}\n","import { AUTH_URL } from './apiConfig';\nimport { fetchJsonWithAuth } from './authApi';\n\n// The endpoint comes from the form's admin config (booleanSearchEndpoint), so\n// this service is not tied to candidates — any module that gains a\n// boolean-search route can point its own search form at it.\nexport async function searchBoolean(endpoint, body = {}, { limit = 10, offset = 0 } = {}) {\n  if (!endpoint) throw new Error('No boolean search endpoint is configured for this form.');\n\n  let json;\n  try {\n    json = await fetchJsonWithAuth(AUTH_URL, endpoint, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ ...body, limit, offset }),\n    });\n  } catch (error) {\n    // A 400 carries { status:false, message, error:{ code, details } } — lift the\n    // code/details so the caller can route INVALID_BOOLEAN_QUERY to the field.\n    const envelope = error?.response?.error;\n    if (envelope) {\n      error.code = envelope.code;\n      error.details = envelope.details;\n      if (error.response?.message) error.message = error.response.message;\n    }\n    throw error;\n  }\n\n  if (json?.status === false) {\n    const error = new Error(json?.message || 'Boolean search failed');\n    error.code = json?.error?.code;\n    error.details = json?.error?.details;\n    throw error;\n  }\n\n  const data = json?.data ?? json ?? {};\n  const items = Array.isArray(data.items) ? data.items : [];\n  const count = data.count ?? {};\n  const total = Number(count.total);\n\n  const counts = {};\n  if (Number.isFinite(Number(count.internal))) counts.internal = Number(count.internal);\n  if (Number.isFinite(Number(count.dice))) counts.dice = Number(count.dice);\n\n  return {\n    rows: items,\n    total: Number.isFinite(total) ? total : items.length,\n    counts,\n    sources: Array.isArray(data.sources) ? data.sources : [],\n  };\n}\n","import { AUTH_URL } from './apiConfig';\nimport { fetchJsonWithAuth } from './authApi';\nimport { getSearchSources } from './sourceProviderActions';\n\n// Bridges ListView's fixed fetch signature onto a single search endpoint, so the\n// results table, tabs, paging and sorting are all owned by ListView rather than\n// re-implemented in the search form.\n//\n// ListView calls:\n//   fetchData(moduleName, limit, offset, { scope, sort, sortDir, search, filters, queryParams })\n//\n// and hands whatever comes back to mapListResponse, which resolves rows/total/\n// tabs/fields/actions from config (src/config/responseMappings/default.json).\n// So this returns the RAW payload — no reshaping — and the response frame in\n// Be_Auth_DevOps/docs/candidate-search-api-spec.md is what makes that work.\n\n// The four parameters the API decides everything from. See the spec's §1.\n//   module      → which config answers, i.e. the columns and actions returned\n//   sourceType  → every ticked source; drives the tab set and the counts\n//   scope       → the active tab; whose rows come back. Omitted on first load,\n//                 so the API falls back to the first source (Internal)\n//   searchMode  → the Boolean toggle; whether text fields are parsed as\n//                 expressions or matched literally\nexport function buildSearchRequest({\n  moduleName,\n  criteria = {},\n  searchMode = 'traditional',\n  sources = [],\n  sourceModules,\n  scope = '',\n  sort = '',\n  sortDir = '',\n}) {\n  const activeScope = String(scope ?? '').trim().toLowerCase();\n  const sourceList = getSearchSources(sources);\n\n  return {\n    ...criteria,\n    module: (activeScope && sourceModules?.[activeScope]) || moduleName,\n    searchMode,\n    ...(sourceList.length ? { sourceType: sourceList.join(',') } : {}),\n    // Absent on the first search — the API defaults to the first source rather\n    // than the client guessing which tab is \"default\".\n    ...(activeScope ? { scope: activeScope } : {}),\n    ...(sort ? { sortBy: sort } : {}),\n    ...(sortDir ? { sortOrder: sortDir } : {}),\n  };\n}\n\n// Tabs normally arrive in the response. This is the fallback for a server that\n// only reports per-source counts: build the strip from the CONFIGURED source\n// order, never from the response's own `sources` array — the API sorts that\n// alphabetically (sort.Strings in models/boolean_search.go), which is what used\n// to put Dice ahead of Internal.\nexport function tabsFromCounts(sources, count) {\n  return getSearchSources(sources).map((source) => {\n    const value = Number(count?.[source]);\n    return {\n      key: source,\n      label: source.charAt(0).toUpperCase() + source.slice(1),\n      ...(Number.isFinite(value) ? { count: value } : {}),\n    };\n  });\n}\n\n// Dice rows arrive in the provider's own shape. Normalizing here — before\n// mapListResponse sees them — keeps every consumer downstream working with one\n// record shape.\nasync function normalizeRows(payload) {\n  const rows = payload?.data ?? payload?.items;\n  if (!Array.isArray(rows) || rows.length === 0) return payload;\n\n  const { isDiceResponse, mapDiceCandidatesToInternal } = await import('./diceCandidateMapper');\n  if (!isDiceResponse({ data: payload })) return payload;\n\n  const mapped = mapDiceCandidatesToInternal(rows);\n  return { ...payload, data: mapped, items: mapped };\n}\n\nexport function makeSearchFetcher({\n  endpoint,\n  criteria,\n  searchMode,\n  sources,\n  sourceModules,\n}) {\n  if (!endpoint) throw new Error('No search endpoint is configured for this form.');\n\n  return async function fetchSearchResults(moduleName, limit, offset, options = {}) {\n    const { scope, sort, sortDir } = options;\n\n    const body = buildSearchRequest({\n      moduleName, criteria, searchMode, sources, sourceModules, scope, sort, sortDir,\n    });\n\n    let json;\n    try {\n      json = await fetchJsonWithAuth(AUTH_URL, endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ ...body, limit, offset }),\n      });\n    } catch (error) {\n      // A 400 carries { status:false, message, error:{ code, details } }. Lift\n      // code/details so the caller can route INVALID_BOOLEAN_QUERY back onto the\n      // field that carries the bad expression.\n      const envelope = error?.response?.error;\n      if (envelope) {\n        error.code = envelope.code;\n        error.details = envelope.details;\n        if (error.response?.message) error.message = error.response.message;\n      }\n      throw error;\n    }\n\n    if (json?.status === false) {\n      const error = new Error(json?.message || 'Search failed');\n      error.code = json?.error?.code;\n      error.details = json?.error?.details;\n      throw error;\n    }\n\n    const payload = await normalizeRows(json?.data ?? json ?? {});\n\n    // Rows go out under `items` ONLY, never `data`.\n    //\n    // mapListResponse resolves each key from one of two roots, the second being\n    // `response.data ?? response`. A payload that carries its own rows under\n    // `data` makes that root resolve to the row ARRAY, and every key looked up\n    // there — actions, actionRules, columnActions, tabField — is then read off\n    // an array and comes back undefined. That is what emptied the Actions menu\n    // on both tabs while columns and tabs still rendered.\n    //\n    // Fixing it here rather than in the shared mapping keeps this endpoint's\n    // shape from redefining the contract every other module's list resolves\n    // through. `items` is already in the mapper's row path list, so nothing\n    // downstream needs to know.\n    const { data: _rowsUnderData, ...rest } = payload;\n\n    // Everything else passes through untouched for mapListResponse.\n    return {\n      ...rest,\n      items: payload.items ?? _rowsUnderData ?? [],\n      tabs: payload.tabs?.length ? payload.tabs : tabsFromCounts(sources, payload.count),\n    };\n  };\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Button, Card, Col, Form, Row, Skeleton, Space, Switch, Tooltip, Typography, message } from 'antd';\nimport { FileTextOutlined, FilterOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons';\nimport PropTypes from 'prop-types';\nimport { useNavigate } from 'react-router-dom';\nimport ListView from './ListView.jsx';\nimport SearchFieldControl from './searchBuilder/SearchFieldControl.jsx';\nimport BooleanQueryField from './searchBuilder/BooleanQueryField.jsx';\nimport { BOOLEAN_PARSEABLE_API_KEYS, isBooleanParsable, validateBooleanQuery } from './searchBuilder/booleanQueryUtils';\nimport { buildBooleanRequest } from './searchBuilder/buildBooleanRequest';\nimport { buildTraditionalParams } from './searchBuilder/buildTraditionalParams';\nimport { buildFilterConditions } from './searchBuilder/buildFilterConditions';\nimport { safeNavTarget } from '../utils/afterSubmitNav';\nimport { getCustomForms } from '../services/adminApi';\nimport { searchModuleData } from '../services/moduleDataApi';\nimport { searchBoolean } from '../services/booleanSearchApi';\nimport { makeSearchFetcher } from '../services/candidateSearchAdapter';\nimport { mapListResponse } from '../services/responseMapping/mapListResponse';\nimport { fetchJsonWithAuth } from '../services/authApi';\nimport { AUTH_URL } from '../services/apiConfig';\nimport {\n  buildSourceModuleMap,\n  buildSourceTabs,\n  getAvailableSourceActions,\n  getSearchSources,\n  getSourceActionInstanceKey,\n  normalizeSourceKey,\n  resolveSearchSource,\n  runSourceAction,\n  sourceActionAppliesToRecord,\n} from '../services/sourceProviderActions';\nimport { resolveDiceProfileId } from '../services/diceCandidateMapper';\nimport '../styles/SearchBuilderV1.css';\n\nconst { Text } = Typography;\n\n// The field key that turns the source picker on. Naming an existing contract\n// rather than adding one: runSearch already reads values under exactly this key.\nconst SOURCE_FIELD = 'selectedSource';\n\n// Picking a source is not itself a search criterion — searching on it alone\n// would return the entire collection.\nconst SOURCE_ONLY_FIELDS = new Set([SOURCE_FIELD, 'source', 'sourceType', 'scope']);\n\nconst EMPTY_RESULTS = {\n  searched: false, rows: [], total: 0, fields: [], actions: [], actionRules: [], loading: false,\n};\n\nfunction extractGroups(schema) {\n  if (Array.isArray(schema)) return schema;\n  if (Array.isArray(schema?.groups)) return schema.groups;\n  if (Array.isArray(schema?.data?.groups)) return schema.data.groups;\n  return [];\n}\n\nfunction truthy(value) {\n  return value === true || value === 1 || value === '1';\n}\n\n// A locked checkbox/radio option (admin-configured — off by default, see\n// FormGroupsSection's Options/Values editor) must be selected from the very\n// first render, not just visually via the registry renderer's own defensive\n// merge — otherwise submitting without ever touching the control would omit\n// it from the request entirely. Radio only allows one selection, so its\n// locked default is a single value; checkbox's is every locked option.\nfunction lockedInitialValue(field) {\n  const options = Array.isArray(field.options) ? field.options : [];\n  const locked = options.filter((option) => option.locked).map((option) => option.value);\n  if (!locked.length) return undefined;\n  return field.type === 'radio' ? locked[0] : locked;\n}\n\n// Dice rows do not always carry _id, and ListView needs a stable key per row or\n// selection attaches to the wrong record after a re-sort or page change.\nfunction resolveRowKey(record, index) {\n  return String(\n    record?._id\n    ?? record?.id\n    ?? record?.applicantRefrenceId\n    ?? record?.applicantReferanceId\n    ?? record?.diceId\n    ?? record?.profileId\n    ?? index,\n  );\n}\n\nfunction hasCriteria(values) {\n  return Object.entries(values ?? {}).some(([key, value]) => {\n    if (SOURCE_ONLY_FIELDS.has(key)) return false;\n    if (value === undefined || value === null || value === '') return false;\n    if (Array.isArray(value)) return value.length > 0;\n    return true;\n  });\n}\n\nexport default function SearchBuilderV1({\n  moduleName,\n  action,\n  formType = 'search',\n  title,\n  migrationJobId,\n  sourceModules,\n  searchActionContext,\n  onBack,\n}) {\n  const [form] = Form.useForm();\n  const navigate = useNavigate();\n  const [schema, setSchema] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [loadError, setLoadError] = useState('');\n  const [reloadToken, setReloadToken] = useState(0);\n\n  const [searchMode, setSearchMode] = useState('traditional');\n  const [selectedSource, setSelectedSource] = useState('internal');\n  const [fieldErrors, setFieldErrors] = useState({});\n  const [tabs, setTabs] = useState([]);\n  const [results, setResults] = useState(EMPTY_RESULTS);\n  const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });\n  const [lastValues, setLastValues] = useState(null);\n  const [sourceActionState, setSourceActionState] = useState({});\n  const [formValues, setFormValues] = useState({});\n  // Unified path only: the submitted criteria, and a nonce that remounts\n  // ListView so pressing Search again re-runs even when nothing changed.\n  const [criteria, setCriteria] = useState(null);\n  const [searchNonce, setSearchNonce] = useState(0);\n  const [activeView, setActiveView] = useState('list');\n\n  // Every state write happens in a promise callback, and a config that resolves\n  // after the props changed (or after unmount) is discarded rather than\n  // overwriting the newer one.\n  useEffect(() => {\n    if (!moduleName) return undefined;\n    let cancelled = false;\n\n    getCustomForms(moduleName, formType, action)\n      .then((data) => {\n        if (cancelled) return;\n        setSchema(Array.isArray(data) ? data[0] ?? null : data ?? null);\n        setLoadError('');\n      })\n      .catch((error) => {\n        if (!cancelled) setLoadError(error?.message || 'Failed to load the search form configuration.');\n      })\n      .finally(() => {\n        if (!cancelled) setLoading(false);\n      });\n\n    return () => { cancelled = true; };\n  }, [moduleName, formType, action, reloadToken]);\n\n  const retry = () => { setLoading(true); setReloadToken((token) => token + 1); };\n\n  const fields = useMemo(() => (\n    extractGroups(schema)\n      .filter((group) => !truthy(group.hideGroup))\n      .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n      .flatMap((group) => group.fields ?? [])\n      .filter((field) => field?.field && field.show !== 0 && !truthy(field.hidden))\n      .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n  ), [schema]);\n\n  // Built once and shared by BOTH request paths, so a source tab cannot ask one\n  // endpoint for its own module and the other for the form's. Config (the\n  // option's `module`) beats the `sourceModules` prop; a source with neither\n  // falls back to moduleName, which is every source on every other form.\n  const sourceModuleMap = useMemo(\n    () => buildSourceModuleMap(fields, sourceModules),\n    [fields, sourceModules],\n  );\n\n  // Sources are OPT-IN, and this is the switch. Candidates configures a\n  // selectedSource field and gets Internal/Dice tabs; a Jobs or Clients search\n  // configures none and must not be handed that vocabulary — no selectedSource\n  // or scope on the wire, no sourceType in a boolean body, and no phantom\n  // \"Internal\" tab beside the module's own. Everything a plain form needs is\n  // then just its module name.\n  const hasSourceField = useMemo(\n    () => fields.some((field) => field.field === SOURCE_FIELD),\n    [fields],\n  );\n\n  // A form whose config never opted in shows no toggle at all, so every\n  // existing search form behaves exactly as it did before.\n  const booleanEnabled = Boolean(schema?.booleanSearchEnabled) && Boolean(schema?.booleanSearchEndpoint);\n  const isBooleanMode = booleanEnabled && searchMode === 'boolean';\n\n  // Only fields the backend actually parses as an expression may render as\n  // one — see isBooleanParsable's doc comment. A field the admin marked\n  // booleanCapable but mapped elsewhere (a config mistake, not a user\n  // mistake) still renders traditionally; it just can't reach the broken\n  // combination, so it's surfaced to whoever builds the form, not the person\n  // searching.\n  const booleanFields = useMemo(\n    () => fields.filter((field) => field.booleanCapable && isBooleanParsable(field.booleanApiKey)),\n    [fields],\n  );\n\n  useEffect(() => {\n    fields\n      .filter((field) => field.booleanCapable && !isBooleanParsable(field.booleanApiKey))\n      .forEach((field) => {\n        console.warn(\n          `[SearchBuilderV1] \"${field.field}\" is marked booleanCapable but its booleanApiKey `\n          + `(${JSON.stringify(field.booleanApiKey)}) is not one of ${BOOLEAN_PARSEABLE_API_KEYS.join(', ')} — `\n          + 'the backend cannot parse it as an expression, so it will render as a normal field. Fix in Admin → Form Groups.',\n        );\n      });\n  }, [fields]);\n\n  const handleModeChange = (checked) => {\n    const nextMode = checked ? 'boolean' : 'traditional';\n    // A boolean-capable field holds a different value type in each mode (chips\n    // vs. an expression string), so carrying values across would submit junk.\n    const cleared = {};\n    fields.forEach((field) => { if (field.booleanCapable) cleared[field.field] = undefined; });\n    form.setFieldsValue(cleared);\n    setFormValues((current) => ({ ...current, ...cleared }));\n    setFieldErrors({});\n    setCriteria(null);\n    setSearchMode(nextMode);\n  };\n\n  const runSearch = useCallback(async (values, sourceOverride, paginationOverride = {}) => {\n    const pageSize = Number(paginationOverride.pageSize) > 0\n      ? Number(paginationOverride.pageSize) : pagination.pageSize;\n    const requested = Number(paginationOverride.current);\n    const current = Number.isFinite(requested) && requested > 0 ? Math.floor(requested) : 1;\n\n    const checkedSources = getSearchSources(values?.[SOURCE_FIELD]);\n    // '' when the form has no source picker: resolveSearchSource always lands on\n    // something ('internal' by default), which is the right answer only when a\n    // source was actually asked for.\n    const activeSource = !hasSourceField ? '' : (sourceOverride\n      ? resolveSearchSource(sourceOverride, selectedSource)\n      : (checkedSources.includes('internal')\n        ? 'internal'\n        : resolveSearchSource(values?.[SOURCE_FIELD], selectedSource)));\n\n    // A source tab can be served by its OWN module key, so that tab gets its own\n    // columns and row actions — the backend keeps the requested key for every\n    // config lookup and falls back to the base module for the data (see\n    // configModule in moduleDataController.go). No mapping for a source means\n    // the form's own moduleName, exactly as before, so every other form and\n    // project is unaffected.\n    const activeModule = sourceModuleMap[normalizeSourceKey(activeSource)] || moduleName;\n\n    setLastValues(values);\n    setPagination({ current, pageSize });\n    setFieldErrors({});\n    setResults((prev) => ({ ...prev, loading: true, searched: true }));\n\n    try {\n      let result;\n      if (isBooleanMode) {\n        const body = buildBooleanRequest(values, fields, {\n          // Left blank for a form with no source picker, so buildBooleanRequest\n          // sends no sourceType at all rather than assuming Candidates.\n          defaultSourceType: hasSourceField\n            ? (schema?.booleanDefaultSourceType || activeSource || 'internal')\n            : '',\n          // Same module key the traditional endpoint gets as ?module=, so the\n          // backend can resolve fields/actions/rules from the same config\n          // whichever mode the search ran in.\n          module: activeModule,\n        });\n        result = await searchBoolean(schema.booleanSearchEndpoint, body, {\n          limit: pageSize,\n          offset: (current - 1) * pageSize,\n        });\n      } else {\n        // selectedSource is the full ticked list, scope is the one being viewed.\n        // That is the contract the API was built for (moduleDataController.go):\n        // both enabled -> internal records + a Dice count, in ONE call, with a\n        // tab per source. Sending only the active source made the server return\n        // a single tab and forced the client to invent the rest of the strip.\n        result = await searchModuleData(\n          activeModule,\n          {\n            ...buildTraditionalParams(values, fields),\n            ...(activeSource\n              ? { [SOURCE_FIELD]: (checkedSources.length ? checkedSources : [activeSource]).join(',') }\n              : {}),\n          },\n          { limit: pageSize, offset: (current - 1) * pageSize },\n          { scope: activeSource, filters: buildFilterConditions(values, fields) },\n        );\n      }\n\n      // With several sources ticked the server's `total` is the COMBINED figure\n      // (internal + dice), which makes pagination read \"1-10 of 281460\" on a tab\n      // holding 9 records. The per-source count is the honest one for the tab\n      // being viewed; fall back to the total when it is absent.\n      const sourceCount = Number(result.counts?.[activeSource]);\n      const pagedTotal = Number.isFinite(sourceCount) ? sourceCount : result.total;\n\n      setSelectedSource(activeSource);\n      setResults({\n        searched: true,\n        rows: result.rows,\n        total: pagedTotal,\n        fields: result.fields ?? [],\n        actions: result.actions ?? [],\n        actionRules: result.actionRules ?? [],\n        loading: false,\n      });\n      // Only a source form owns its tab strip. Everything else — jobs' My Jobs /\n      // All Jobs, a field-based tab set — is the backend's to report, and\n      // buildSourceTabs would prepend an Internal tab that module never had.\n      if (!hasSourceField) {\n        setTabs(result.tabs ?? []);\n        return;\n      }\n      setTabs((currentTabs) => buildSourceTabs({\n        // The ticked options are the single source of truth for tab ORDER, in\n        // both modes. The server's own list can't be: boolean search runs its\n        // sources through sort.Strings (models/boolean_search.go), so it always\n        // comes back alphabetical — \"dice\" before \"internal\" — which put Dice\n        // first the moment the Boolean toggle went on. result.sources is only a\n        // fallback for when nothing is ticked.\n        sources: checkedSources.length ? checkedSources : result.sources,\n        activeSource,\n        activeCount: pagedTotal,\n        responseCounts: result.counts,\n        currentTabs,\n        backendTabs: result.tabs,\n      }));\n    } catch (error) {\n      // Point a rejected expression at the field that carries it when the\n      // server names one; otherwise fall back to a form-level message.\n      const details = error?.details ? String(error.details) : '';\n      const blamed = error?.code === 'INVALID_BOOLEAN_QUERY'\n        ? fields.find((field) => field.booleanCapable && details.toLowerCase().includes(String(field.field).toLowerCase()))\n        : null;\n      if (blamed) setFieldErrors({ [blamed.field]: details });\n      else message.error(details || error?.message || 'Search failed');\n\n      setResults({ ...EMPTY_RESULTS, searched: true });\n    }\n  }, [fields, hasSourceField, isBooleanMode, moduleName, pagination.pageSize, schema, selectedSource, sourceModuleMap]);\n\n  // Which endpoint answers this form, defined in Admin (Form Groups → Form\n  // Identity → Search Endpoint). When set, ListView fetches from it for BOTH\n  // modes and owns tabs, paging, sort and selection. Blank — the default for\n  // every form — keeps the common /module-data-list path unchanged.\n  //\n  // Deliberately NOT booleanSearchEndpoint: that means \"where boolean mode\n  // POSTs\", so reusing it would silently reroute traditional search on any form\n  // that merely enabled the Boolean toggle.\n  const unifiedEndpoint = String(schema?.searchEndpoint ?? '').trim();\n\n  // One vocabulary on the wire for both modes: booleanApiKey-mapped params,\n  // plus fieldFilters for anything the admin added that has no mapping — which\n  // is what keeps custom search fields filtering once the flat query-param\n  // path (buildTraditionalParams) is no longer used.\n  const buildCriteria = useCallback((values) => {\n    const conditions = buildFilterConditions(values, fields);\n    return {\n      ...buildBooleanRequest(values, fields, {\n        // Blank for a form with no source picker, exactly as runSearch does, so\n        // buildBooleanRequest sends no sourceType rather than assuming\n        // Candidates. See hasSourceField.\n        defaultSourceType: hasSourceField\n          ? (schema?.booleanDefaultSourceType || 'internal')\n          : '',\n      }),\n      ...(conditions.length ? { fieldFilters: conditions } : {}),\n    };\n  }, [fields, hasSourceField, schema]);\n\n  const searchFetcher = useMemo(() => {\n    if (!unifiedEndpoint || !criteria) return null;\n    return makeSearchFetcher({\n      endpoint: unifiedEndpoint,\n      criteria,\n      searchMode: isBooleanMode ? 'boolean' : 'traditional',\n      sources: getSearchSources(formValues?.selectedSource),\n      // The map, not the raw prop: the adapter's own lookup is right, it was\n      // simply never given the modules the config declares.\n      sourceModules: sourceModuleMap,\n    });\n  }, [unifiedEndpoint, criteria, isBooleanMode, formValues, sourceModuleMap]);\n\n  // An action that declares BOTH apiPath and routeTemplate means \"call the API,\n  // then go somewhere\" — e.g. Migrate To Internal, which migrates the candidate\n  // and then opens its detail view so the user can tag it to a job or move it\n  // to a stage. Neither built-in branch does both: actionType \"api\" calls and\n  // stays put, \"navigate\" goes without calling. Attaching onClick short-circuits\n  // ListView's own dispatch (it returns as soon as onClick exists), so this needs\n  // no change to the shared component.\n  const withPostActionRoute = useCallback((action) => {\n    if (!action?.apiPath || !action?.routeTemplate) return action;\n\n    return {\n      ...action,\n      onClick: async ({ selectedRecords }) => {\n        const record = selectedRecords?.[0] ?? {};\n        // A Dice row carries no `diceId` — its `_id` IS the provider's profile\n        // id — so a template like /dicemigrate/:diceId resolved to an empty\n        // segment and called /dicemigrate/. resolveDiceProfileId already knows\n        // every spelling the provider uses, including that fallback.\n        const diceId = resolveDiceProfileId(record);\n        const context = diceId ? { ...record, diceId } : record;\n        const apiPath = safeNavTarget(action.apiPath, context._id ?? context.id, context);\n        if (!apiPath) {\n          message.error(`${action.label}: the configured API path is not a valid in-app path.`);\n          return;\n        }\n\n        try {\n          const method = String(action.apiMethod || 'POST').toUpperCase();\n          const response = await fetchJsonWithAuth(AUTH_URL, apiPath, {\n            method,\n            body: ['GET', 'DELETE'].includes(method)\n              ? undefined\n              : JSON.stringify({ ids: [record._id ?? record.id], records: [record] }),\n          });\n          message.success(`${action.label} completed`);\n\n          // The destination may need an id the API only just created, so the\n          // response wins over the row it was launched from.\n          const routeContext = { ...context, ...(response?.data ?? response ?? {}) };\n          const target = safeNavTarget(action.routeTemplate, routeContext._id ?? routeContext.id, routeContext);\n          if (target) navigate(target);\n        } catch (error) {\n          message.error(error?.message || `${action.label} failed`);\n        }\n      },\n    };\n  }, [navigate]);\n\n  // ListView reads actions straight out of whatever the mapper returns, so this\n  // is where per-action behaviour gets attached without touching ListView.\n  const searchResponseMapper = useCallback((response, mapperModule) => {\n    const mapped = mapListResponse(response, mapperModule);\n    return { ...mapped, actions: (mapped.actions ?? []).map(withPostActionRoute) };\n  }, [withPostActionRoute]);\n\n  const handleSearch = () => {\n    // Each boolean-capable field carries its own blocking + warningOnly rule\n    // (see the Form.Item below), so a malformed expression is rejected right\n    // here by antd's own validation — no separate re-check needed.\n    form.validateFields()\n      .then((values) => {\n        if (unifiedEndpoint) {\n          // No fetch here — ListView does it. A fresh nonce remounts it, which\n          // resets page and tab together for the new criteria.\n          setCriteria(buildCriteria(values));\n          setSearchNonce((nonce) => nonce + 1);\n          return;\n        }\n        runSearch(values, undefined, { current: 1 });\n      })\n      .catch(() => message.error('Fix the highlighted field before searching.'));\n  };\n\n  const handleReset = () => {\n    form.resetFields();\n    setFormValues({});\n    setFieldErrors({});\n    setResults(EMPTY_RESULTS);\n    setTabs([]);\n    setSelectedSource('internal');\n    setCriteria(null);\n  };\n\n  const handleSourceAction = useCallback(async (sourceAction, record) => {\n    const key = getSourceActionInstanceKey(sourceAction, record);\n    setSourceActionState((current) => ({ ...current, [key]: { ...current[key], loading: true } }));\n    try {\n      await runSourceAction(sourceAction, record);\n      setSourceActionState((current) => ({ ...current, [key]: { loading: false, completed: true } }));\n      message.success(sourceAction.successMessage);\n    } catch (error) {\n      setSourceActionState((current) => ({ ...current, [key]: { loading: false } }));\n      message.error(error?.message || sourceAction.errorMessage);\n    }\n  }, []);\n\n  const resultFields = useMemo(() => {\n    const base = results.fields?.length ? results.fields : (() => {\n      const first = results.rows[0];\n      if (!first) return [];\n      return Object.keys(first)\n        .filter((key) => !key.startsWith('_') && typeof first[key] !== 'object')\n        .map((key) => ({\n          value: key,\n          field: key,\n          label: key.replace(/([A-Z])/g, ' $1').replace(/^./, (char) => char.toUpperCase()),\n          isVisible: true,\n        }));\n    })();\n\n    const sourceActions = getAvailableSourceActions({ rows: results.rows, selectedSource });\n    if (!sourceActions.length) return base;\n\n    const actionFields = new Set(sourceActions.map((item) => item.field));\n    return [\n      ...base.filter((field) => field.cardRole !== 'action' && !actionFields.has(field.value)),\n      ...sourceActions.map((sourceAction) => ({\n        value: sourceAction.field,\n        field: sourceAction.field,\n        label: sourceAction.label ?? 'Action',\n        cardRole: 'action',\n        isVisible: true,\n        sorter: false,\n        render: (_value, record) => {\n          if (!sourceActionAppliesToRecord(sourceAction, record, selectedSource)) return null;\n          const key = getSourceActionInstanceKey(sourceAction, record);\n          const state = sourceActionState[key] ?? {};\n          return (\n            <Button\n              type=\"primary\"\n              size=\"small\"\n              loading={state.loading}\n              disabled={!key || state.completed}\n              onClick={() => handleSourceAction(sourceAction, record)}\n            >\n              {state.completed ? sourceAction.completedLabel : sourceAction.buttonLabel}\n            </Button>\n          );\n        },\n      })),\n    ];\n  }, [handleSourceAction, results.fields, results.rows, selectedSource, sourceActionState]);\n\n  // The record context this search runs in (e.g. the job being sourced for).\n  // Shared by row actions and the configured link button's URL template, so\n  // the two can never disagree about which record they mean.\n  const actionContext = useMemo(\n    () => searchActionContext ?? (migrationJobId ? { jobId: migrationJobId } : null),\n    [searchActionContext, migrationJobId],\n  );\n\n  const resultActions = useMemo(() => {\n    if (!actionContext) return results.actions;\n    const merge = (item) => ({\n      ...item,\n      popupState: { ...actionContext, ...item.popupState },\n      ...(item.children ? { children: item.children.map(merge) } : {}),\n    });\n    return (results.actions ?? []).map(merge);\n  }, [results.actions, actionContext]);\n\n  // Admin-configured link button (schema.actionButton*). Off by default, so a\n  // form that never enables it renders exactly as it does today.\n  // safeNavTarget resolves :tokens AND rejects anything that isn't a plain\n  // in-app path — an admin-supplied URL is never interpolated raw.\n  const actionButtonEnabled = Boolean(schema?.actionButtonEnabled);\n  const actionButtonTarget = actionButtonEnabled\n    ? safeNavTarget(schema?.actionButtonUrl, undefined, actionContext ?? {})\n    : null;\n\n  const handleActionButton = () => {\n    if (!actionButtonTarget) return;\n    if (schema?.actionButtonTarget === '_blank') {\n      window.open(actionButtonTarget, '_blank', 'noopener');\n      return;\n    }\n    navigate(actionButtonTarget);\n  };\n\n  // Boolean mode mirrors the backend's own EMPTY_QUERY rule: at least one\n  // boolean-capable field must carry a value — filling only Location or\n  // Experience is not a boolean search. Traditional mode keeps the existing\n  // \"any criterion at all\" rule.\n  const hasBooleanCriteria = booleanFields.some((field) => {\n    const value = formValues[field.field];\n    return value !== undefined && value !== null && String(value).trim() !== '';\n  });\n  const searchDisabled = isBooleanMode ? !hasBooleanCriteria : !hasCriteria(formValues);\n  const emptyBooleanHint = isBooleanMode && !hasBooleanCriteria && booleanFields.length\n    ? `Enter a query in at least one of: ${booleanFields.map((field) => field.label ?? field.field).join(', ')}.`\n    : '';\n\n  if (!moduleName) {\n    return (\n      <div className=\"sbv1-page\">\n        <Card className=\"sbv1-card\"><Text type=\"danger\">moduleName is required.</Text></Card>\n      </div>\n    );\n  }\n\n  if (loading) {\n    return (\n      <div className=\"sbv1-page\">\n        <Card className=\"sbv1-card\"><Skeleton active paragraph={{ rows: 4 }} /></Card>\n      </div>\n    );\n  }\n\n  if (loadError) {\n    return (\n      <div className=\"sbv1-page\">\n        <Card className=\"sbv1-card\">\n          <Space direction=\"vertical\" align=\"center\" style={{ width: '100%' }}>\n            <Text strong>Failed to load the search form</Text>\n            <Text type=\"secondary\">{loadError}</Text>\n            <Button icon={<ReloadOutlined />} onClick={retry}>Retry</Button>\n          </Space>\n        </Card>\n      </div>\n    );\n  }\n\n  if (!fields.length) {\n    return (\n      <div className=\"sbv1-page\">\n        <Card className=\"sbv1-card\">\n          <Text type=\"secondary\">No search fields are configured for “{moduleName}”.</Text>\n        </Card>\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"sbv1-page\">\n      <Card\n        className=\"sbv1-card\"\n        title={<Text strong>{title ?? schema?.label ?? 'Search'}</Text>}\n        extra={(\n          <Space size={12}>\n            {/* Every action lives up here in one row — nothing at the bottom of\n                the field grid, so the controls never move as the form grows. */}\n            <Button\n              size=\"small\"\n              className=\"sbv1-action-btn\"\n              icon={<FilterOutlined />}\n              onClick={handleReset}\n            >\n              Reset filters\n            </Button>\n            <Tooltip title={emptyBooleanHint || undefined}>\n              <Button\n                size=\"small\"\n                className=\"sbv1-action-btn\"\n                icon={<SearchOutlined />}\n                disabled={searchDisabled}\n                loading={results.loading}\n                onClick={handleSearch}\n              >\n                Search\n              </Button>\n            </Tooltip>\n            {actionButtonEnabled && (\n              // Disabled rather than hidden when the URL is missing or unsafe,\n              // so a half-finished config is visible instead of silently dead.\n              <Tooltip title={actionButtonTarget ? undefined : 'No valid destination configured'}>\n                <Button\n                  size=\"small\"\n                  className=\"sbv1-action-btn\"\n                  icon={<FileTextOutlined />}\n                  disabled={!actionButtonTarget}\n                  onClick={handleActionButton}\n                >\n                  {schema?.actionButtonLabel || 'Open'}\n                </Button>\n              </Tooltip>\n            )}\n            {onBack && (\n              <Button size=\"small\" className=\"sbv1-action-btn\" onClick={onBack}>Back</Button>\n            )}\n            {booleanEnabled && (\n              <Tooltip title=\"Switch the marked fields to AND / OR / NOT expressions\">\n                <Space size={8}>\n                  <Text type=\"secondary\">Boolean</Text>\n                  <Switch\n                    size=\"small\"\n                    checked={searchMode === 'boolean'}\n                    onChange={handleModeChange}\n                  />\n                </Space>\n              </Tooltip>\n            )}\n          </Space>\n        )}\n      >\n        <Form\n          form={form}\n          layout=\"vertical\"\n          colon={false}\n          onValuesChange={(_changed, all) => setFormValues(all)}\n        >\n          <Row gutter={[24, 0]}>\n            {fields.map((field) => {\n              const asBoolean = isBooleanMode && booleanFields.includes(field);\n              const rules = [];\n              if (truthy(field.req)) {\n                rules.push({ required: true, message: `${field.label ?? field.field} is required` });\n              }\n              if (asBoolean) {\n                // Blocking: a broken expression (unbalanced brackets, a\n                // dangling operator, \"&&\" instead of \"AND\") stops the search —\n                // the Go parser would reject it too, so this just saves the\n                // round trip.\n                rules.push({\n                  validator: (_rule, value) => {\n                    const { errors } = validateBooleanQuery(value);\n                    return errors.length ? Promise.reject(new Error(errors[0])) : Promise.resolve();\n                  },\n                });\n                // warningOnly: legal but likely-wrong (all-exclusions, a bare\n                // \"*\"/\"?\" the backend treats as a literal character, …) shows\n                // as an amber hint and never blocks form.validateFields().\n                rules.push({\n                  warningOnly: true,\n                  validator: (_rule, value) => {\n                    const { warnings } = validateBooleanQuery(value);\n                    return warnings.length ? Promise.reject(new Error(warnings[0])) : Promise.resolve();\n                  },\n                });\n              }\n              return (\n                <Col xs={24} sm={12} lg={field.col ?? 12} key={field.field}>\n                  <Form.Item\n                    name={field.field}\n                    label={field.label ?? field.field}\n                    rules={rules.length ? rules : undefined}\n                    initialValue={lockedInitialValue(field)}\n                  >\n                    {asBoolean\n                      ? <BooleanQueryField field={field} serverError={fieldErrors[field.field]} />\n                      : <SearchFieldControl field={field} moduleName={moduleName} />}\n                  </Form.Item>\n                </Col>\n              );\n            })}\n          </Row>\n\n          {/* The buttons moved to the card header; the hint stays down here\n              next to the fields it is talking about. */}\n          {emptyBooleanHint && (\n            <div className=\"sbv1-actions\">\n              <Text type=\"secondary\" className=\"sbv1-empty-hint\">{emptyBooleanHint}</Text>\n            </div>\n          )}\n        </Form>\n      </Card>\n\n      {/* Unified path: ListView owns fetching, tabs, paging, sort and\n          selection. Deliberately no onPageChange/onPageSizeChange/onSearch —\n          those set isControlled and switch its own fetching off. */}\n      {unifiedEndpoint && searchFetcher && (\n        <ListView\n          key={searchNonce}\n          moduleName={moduleName}\n          breadcrumbItems={[]}\n          fetchData={searchFetcher}\n          responseMapper={searchResponseMapper}\n          queryParams={criteria}\n          rowKey={resolveRowKey}\n          showSearch={false}\n          activeView={activeView}\n          onViewChange={setActiveView}\n          showViewToggle\n          // This screen owns its view. Without this, ListView overrides\n          // activeView and forces cards for any row whose sourceType is not\n          // \"internal\" — which is every Dice row — so the Dice tab could never\n          // open as a list and the toggle did nothing on it.\n          autoCardForExternalRows={false}\n        />\n      )}\n\n      {!unifiedEndpoint && results.searched && (\n        <ListView\n          moduleName={moduleName}\n          breadcrumbItems={[]}\n          dataSource={results.rows}\n          fields={resultFields}\n          total={results.total}\n          loading={results.loading}\n          current={pagination.current}\n          pageSize={pagination.pageSize}\n          showSearch={false}\n          tabs={tabs}\n          selectedSource={selectedSource}\n          onTabChange={(key) => runSearch(lastValues ?? {}, key, { current: 1 })}\n          onPageChange={(current, pageSize) => runSearch(lastValues ?? {}, selectedSource, { current, pageSize })}\n          onPageSizeChange={(current, pageSize) => runSearch(lastValues ?? {}, selectedSource, { current: 1, pageSize })}\n          actions={resultActions}\n          actionRules={results.actionRules}\n        />\n      )}\n    </div>\n  );\n}\n\nSearchBuilderV1.propTypes = {\n  moduleName: PropTypes.string.isRequired,\n  action: PropTypes.string,\n  formType: PropTypes.string,\n  title: PropTypes.string,\n  migrationJobId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n  searchActionContext: PropTypes.object,\n  // { [sourceKey]: moduleKey }, overridden by any option that configures its\n  // own `module` — see buildSourceModuleMap.\n  sourceModules: PropTypes.object,\n  onBack: PropTypes.func,\n};\n","import { Tag } from 'antd';\n\nconst STATUS_COLOR = {\n  active: 'green',\n  approved: 'green',\n  hired: 'green',\n  submitted: 'gold',\n  resubmitted: 'purple',\n  pending: 'gold',\n  draft: 'default',\n  rejected: 'red',\n  inactive: 'default',\n  completed: 'blue',\n  not_submitted: 'default',\n};\n\nexport default function StatusBadge({ status }) {\n  const label = String(status ?? 'unknown');\n  const color = STATUS_COLOR[label.toLowerCase()] ?? 'default';\n\n  return (\n    <Tag color={color} style={{ borderRadius: 6, fontWeight: 600, fontSize: 12, textTransform: 'capitalize' }}>\n      {label.replace(/_/g, ' ')}\n    </Tag>\n  );\n}\n","import { Badge } from 'antd';\nimport '../styles/StylishDynamicTabs.css';\n\nfunction normalizeTab(tab, index) {\n  if (!tab || typeof tab !== 'object') return null;\n  const key   = tab.key   ?? tab.value ?? tab.id ?? String(index);\n  const label = tab.label ?? tab.title ?? tab.name ?? tab.tabTitle;\n  if (!key || !label) return null;\n  return { key: String(key), label: String(label), count: tab.count ?? tab.countValue };\n}\n\nexport default function StylishDynamicTabs({ tabs = [], activeKey, onChange, className = '' }) {\n  const items = tabs.map(normalizeTab).filter(Boolean);\n  if (!items.length) return null;\n\n  const selectedKey = items.some((t) => t.key === activeKey) ? activeKey : items[0].key;\n\n  return (\n    <div className={`stylish-tabs ${className}`.trim()}>\n      {items.map((tab) => {\n        const isActive  = tab.key === selectedKey;\n        const hasCount  = tab.count != null;\n\n        return (\n          <button\n            key={tab.key}\n            type=\"button\"\n            className={`stylish-tabs__item${isActive ? ' stylish-tabs__item--active' : ''}`}\n            onClick={() => onChange?.(tab.key)}\n          >\n            <span className=\"stylish-tabs__label\">{tab.label}</span>\n            {hasCount && (\n              <Badge\n                count={tab.count}\n                showZero\n                overflowCount={999}\n                className={`stylish-tabs__badge${isActive ? ' stylish-tabs__badge--active' : ''}`}\n              />\n            )}\n          </button>\n        );\n      })}\n    </div>\n  );\n}\n","import { Input } from 'antd';\n\nconst { TextArea } = Input;\n\nexport default function TemplateEditor({\n  value = '',\n  onChange,\n  placeholder = 'e.g.  ${{clientRate}} /{{rateType}}',\n  disabled = false,\n  textareaRef,\n}) {\n  return (\n    <TextArea\n      ref={textareaRef}\n      value={value}\n      disabled={disabled}\n      placeholder={placeholder}\n      autoSize={{ minRows: 2, maxRows: 6 }}\n      spellCheck={false}\n      onChange={(event) => onChange?.(event.target.value)}\n      style={{\n        width: '100%',\n        fontFamily: '\"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, monospace',\n        fontSize: 12,\n        lineHeight: '20px',\n        resize: 'vertical',\n      }}\n    />\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// FinanceListToolbar — single filter toolbar for the Billing / Payroll lists.\n// Fully controlled: the host page owns state, debouncing and fetching.\n// ─────────────────────────────────────────────────────────────────────────\nimport { Button, DatePicker, Input, Select, Tooltip } from 'antd';\nimport {\n  ClearOutlined,\n  DownloadOutlined,\n  ReloadOutlined,\n  SearchOutlined,\n  ThunderboltOutlined,\n} from '@ant-design/icons';\nimport './finance-components.css';\n\nconst CYCLE_OPTIONS = ['Weekly', 'Bi-Weekly', 'Monthly'].map((value) => ({ value, label: value }));\n\n// Payment terms decide WHEN a candidate or partner is due to be paid, which is\n// the rule Finance actually works from. The legacy payment-cycle filter above\n// matches a free-text cadence field that usually just reads \"Weekly\" and says\n// nothing about timing — it stays for hosts that still pass onCycleChange.\nconst TERMS_OPTIONS = [7, 15, 30, 45, 60, 90].map((days) => ({\n  value: `NET_${days}`,\n  label: `NET ${days}`,\n}));\n\nexport default function FinanceListToolbar({\n  search,\n  onSearchChange,\n  searchPlaceholder = 'Search employee, client, employer, project…',\n  monthValue,\n  onMonthChange,\n  cycleValue,\n  onCycleChange,\n  termsValue,\n  onTermsChange,\n  termsOptions = TERMS_OPTIONS,\n  statusValue,\n  onStatusChange,\n  statusOptions = [],\n  chips = [],\n  activeChips = [],\n  onToggleChip,\n  onReset,\n  onRefresh,\n  onExport,\n  exporting = false,\n  disabled = false,\n}) {\n  return (\n    <div className=\"fin-toolbar\">\n      <div className=\"fin-toolbar__main\">\n        <div className=\"fin-toolbar__filters\">\n          <Input\n            className=\"fin-toolbar__search\"\n            size=\"large\"\n            allowClear\n            prefix={<SearchOutlined className=\"fin-toolbar__search-icon\" />}\n            placeholder={searchPlaceholder}\n            value={search}\n            onChange={(event) => onSearchChange?.(event.target.value)}\n            disabled={disabled}\n          />\n          <DatePicker\n            className=\"fin-toolbar__control\"\n            picker=\"month\"\n            allowClear\n            placeholder=\"All months\"\n            value={monthValue}\n            onChange={onMonthChange}\n            disabled={disabled}\n          />\n          {onTermsChange ? (\n            <Select\n              className=\"fin-toolbar__control\"\n              allowClear\n              placeholder=\"Payment terms\"\n              value={termsValue || undefined}\n              onChange={(value) => onTermsChange(value ?? '')}\n              options={termsOptions}\n              disabled={disabled}\n              popupMatchSelectWidth={false}\n            />\n          ) : null}\n          {/* Rendered only for hosts still filtering on the legacy cadence\n              field, so adding the terms filter above breaks no existing page. */}\n          {onCycleChange ? (\n            <Select\n              className=\"fin-toolbar__control\"\n              allowClear\n              placeholder=\"Payment cycle\"\n              value={cycleValue || undefined}\n              onChange={(value) => onCycleChange(value ?? '')}\n              options={CYCLE_OPTIONS}\n              disabled={disabled}\n              popupMatchSelectWidth={false}\n            />\n          ) : null}\n          <Select\n            className=\"fin-toolbar__control\"\n            allowClear\n            placeholder=\"Status\"\n            value={statusValue || undefined}\n            onChange={(value) => onStatusChange?.(value ?? '')}\n            options={statusOptions}\n            disabled={disabled}\n            popupMatchSelectWidth={false}\n          />\n        </div>\n        <div className=\"fin-toolbar__actions\">\n          <Tooltip title=\"Reset filters\">\n            <Button icon={<ClearOutlined />} onClick={onReset} disabled={disabled} aria-label=\"Reset filters\" />\n          </Tooltip>\n          <Tooltip title=\"Refresh\">\n            <Button icon={<ReloadOutlined />} onClick={onRefresh} disabled={disabled} aria-label=\"Refresh\" />\n          </Tooltip>\n          <Button icon={<DownloadOutlined />} onClick={onExport} loading={exporting} disabled={disabled}>\n            Export\n          </Button>\n        </div>\n      </div>\n      {chips.length ? (\n        <div className=\"fin-toolbar__chips\">\n          <span className=\"fin-toolbar__chips-label\">\n            <ThunderboltOutlined /> Quick filters\n          </span>\n          {chips.map((chip) => {\n            const active = activeChips.includes(chip.key);\n            return (\n              <button\n                type=\"button\"\n                key={chip.key}\n                className={`fin-chip${active ? ' fin-chip--active' : ''}`}\n                onClick={() => onToggleChip?.(chip.key)}\n                disabled={disabled}\n              >\n                {chip.label}\n              </button>\n            );\n          })}\n        </div>\n      ) : null}\n    </div>\n  );\n}\n","// ── Timesheet daily-hours policy engine ─────────────────────────────────────\n// Pure, framework-free rules for a single day's Standard/Overtime/Leave hours.\n// No React/antd/JSX here on purpose — DayLogModal (TimesheetComponents.jsx) is\n// a thin renderer over `computeHoursPolicy(...)`, and every rule below is\n// asserted directly in timesheetHoursPolicy.test.js without rendering\n// anything. Modelled on the finance suite's financeApprovalEngine.js (a\n// config object + pure compute function).\n//\n// Day model, three kinds (see resolveDayKind):\n//   holiday — no log required at all; the modal hides its form entirely.\n//   weekOff — Standard and Leave are not applicable; the day is loggable as\n//             Overtime only.\n//   working — the ordinary case: Standard + Leave share an 8h regular\n//             allocation. Overtime only unlocks once Standard reaches a full\n//             8 — a day can't mix \"worked less than a full day\" with\n//             \"worked overtime\", and since Leave is itself forced to 0 the\n//             moment Standard hits 8, this same rule is what keeps Leave and\n//             Overtime from ever coexisting on the same day.\n\nexport const DEFAULT_HOURS_POLICY = {\n  regularDayHours: 8, // the Standard+Leave envelope on a working day\n  standardMaxHours: 8, // Standard's own ceiling (equal to regularDayHours today)\n  overtimeMaxRegular: 16, // OT cap on a regular working day\n  overtimeMaxWeekOff: 24, // OT cap on a week off (the whole day is overtime)\n  step: 0.5, // input increment\n  decimals: 2, // rounding precision for derived values\n  epsilon: 0.001, // float-slop guard, e.g. 7.5 + 0.5 landing on 7.999999999999999\n};\n\nexport const HOURS_MESSAGES = {\n  ST_MAX: 'Standard hours cannot exceed 8 hours.',\n  LEAVE_MAX: 'Leave hours cannot exceed 8 hours.',\n  LEAVE_REMAINING: 'Leave hours cannot exceed the remaining regular hours.',\n  DAY_TOTAL: 'Standard + Leave hours cannot exceed 8 hours.',\n  OT_MAX_REGULAR: 'Overtime cannot exceed 16 hours on a regular working day.',\n  OT_MAX_WEEKOFF: 'Overtime cannot exceed 24 hours on a week-off.',\n  OT_REQUIRES_FULL_STANDARD: 'Overtime can only be entered after completing 8 standard working hours.',\n  WEEKOFF_NA: 'Standard and Leave hours are not applicable on a week-off.',\n  ST_NEGATIVE: 'Standard hours cannot be negative.',\n  OT_NEGATIVE: 'Overtime cannot be negative.',\n  LEAVE_NEGATIVE: 'Leave hours cannot be negative.',\n};\n\n// Coerces antd's InputNumber values (undefined/null/'' when cleared, or a\n// stray non-numeric string) down to a plain finite number.\nfunction toNumber(value) {\n  const n = Number(value);\n  return Number.isFinite(n) ? n : 0;\n}\n\nexport function roundHours(value, decimals = DEFAULT_HOURS_POLICY.decimals) {\n  const factor = 10 ** decimals;\n  return Math.round(toNumber(value) * factor) / factor;\n}\n\nexport function clampHours(value, min, max, decimals = DEFAULT_HOURS_POLICY.decimals) {\n  return roundHours(Math.min(Math.max(toNumber(value), min), max), decimals);\n}\n\n// Holiday wins over week-off when a date is flagged as both — matches the\n// modal's existing precedence (`isLocked = day?.isHoliday`), so the engine\n// and the JSX never disagree on a day carrying both flags.\nexport function resolveDayKind(day) {\n  if (day?.isHoliday) return 'holiday';\n  if (day?.isWeekOff) return 'weekOff';\n  return 'working';\n}\n\nfunction pushViolation(violations, field, code, policy, blocking = true) {\n  violations.push({ field, code, message: HOURS_MESSAGES[code], blocking });\n}\n\nexport function computeHoursPolicy(day, values, policy = DEFAULT_HOURS_POLICY) {\n  const dayKind = resolveDayKind(day);\n  const ST = roundHours(values?.ST, policy.decimals);\n  const OT = roundHours(values?.OT, policy.decimals);\n  const Leave = roundHours(values?.Leave, policy.decimals);\n  const violations = [];\n\n  let fields;\n  let overtimeCap;\n\n  if (dayKind === 'holiday') {\n    // No manual log required — the modal hides the whole form for this case,\n    // so the engine must never block a path that has no Save button.\n    overtimeCap = 0;\n    fields = {\n      ST: { min: 0, max: 0, step: policy.step, disabled: true },\n      OT: { min: 0, max: 0, step: policy.step, disabled: true },\n      Leave: { min: 0, max: 0, step: policy.step, disabled: true },\n    };\n  } else if (dayKind === 'weekOff') {\n    overtimeCap = policy.overtimeMaxWeekOff;\n    fields = {\n      ST: { min: 0, max: 0, step: policy.step, disabled: true },\n      OT: { min: 0, max: overtimeCap, step: policy.step, disabled: false },\n      Leave: { min: 0, max: 0, step: policy.step, disabled: true },\n    };\n    // A blocking error here would deadlock the user: ST/Leave are disabled,\n    // so there is nothing they could type to clear it. This only ever fires\n    // on legacy data (a day logged as \"working\" later reclassified as a week\n    // off) — reconcileHours() auto-zeroes it on modal open instead.\n    if (ST > policy.epsilon || Leave > policy.epsilon) {\n      pushViolation(violations, 'ST', 'WEEKOFF_NA', policy, false);\n    }\n    if (OT < 0) {\n      pushViolation(violations, 'OT', 'OT_NEGATIVE', policy);\n    } else if (OT > overtimeCap + policy.epsilon) {\n      pushViolation(violations, 'OT', 'OT_MAX_WEEKOFF', policy);\n    }\n  } else {\n    overtimeCap = policy.overtimeMaxRegular;\n    let leaveMax = clampHours(policy.regularDayHours - ST, 0, policy.regularDayHours, policy.decimals);\n    let stErrored = false;\n\n    if (ST < 0) {\n      pushViolation(violations, 'ST', 'ST_NEGATIVE', policy);\n      stErrored = true;\n    } else if (ST > policy.standardMaxHours + policy.epsilon) {\n      pushViolation(violations, 'ST', 'ST_MAX', policy);\n      stErrored = true; // skip the leave-remaining check below — ST is already\n      // the sole owner of this failure, and 8-9=-1 would otherwise also\n      // (spuriously) fault Leave for \"exceeding\" a negative remainder.\n    }\n\n    if (!stErrored) {\n      if (Leave < 0) {\n        pushViolation(violations, 'Leave', 'LEAVE_NEGATIVE', policy);\n      } else if (Leave > policy.regularDayHours + policy.epsilon) {\n        // Absolute ceiling, checked before the ST-dependent remaining-hours\n        // check below — mirrors ST_MAX. A value like 8888 always gets this\n        // flat \"cannot exceed 8 hours\" message, regardless of what Standard\n        // happens to be set to.\n        pushViolation(violations, 'Leave', 'LEAVE_MAX', policy);\n      } else if (Leave > leaveMax + policy.epsilon) {\n        // Leave's own input is disabled exactly when leaveMax is 0 (ST===8) —\n        // the message has to live on the only field the user can still move.\n        if (leaveMax <= policy.epsilon) {\n          pushViolation(violations, 'ST', 'DAY_TOTAL', policy);\n        } else {\n          pushViolation(violations, 'Leave', 'LEAVE_REMAINING', policy);\n        }\n      }\n    }\n\n    // Overtime only unlocks once Standard reaches a full 8 hours — matches\n    // ST_MAX's own +/-epsilon tolerance so a value that just barely rounds to\n    // 8 doesn't get treated as \"incomplete\".\n    const otAllowed = Math.abs(ST - policy.standardMaxHours) <= policy.epsilon;\n    if (OT < 0) {\n      pushViolation(violations, 'OT', 'OT_NEGATIVE', policy);\n    } else if (OT > policy.epsilon && !otAllowed) {\n      pushViolation(violations, 'OT', 'OT_REQUIRES_FULL_STANDARD', policy);\n    } else if (OT > overtimeCap + policy.epsilon) {\n      pushViolation(violations, 'OT', 'OT_MAX_REGULAR', policy);\n    }\n\n    fields = {\n      ST: { min: 0, max: policy.standardMaxHours, step: policy.step, disabled: false },\n      OT: { min: 0, max: overtimeCap, step: policy.step, disabled: !otAllowed },\n      Leave: { min: 0, max: leaveMax, step: policy.step, disabled: leaveMax <= policy.epsilon },\n    };\n  }\n\n  const regularAllocated = roundHours(ST + Leave, policy.decimals);\n  const regularRemaining =\n    dayKind === 'working'\n      ? Math.max(0, roundHours(policy.regularDayHours - regularAllocated, policy.decimals))\n      : 0;\n  const leaveRemaining =\n    dayKind === 'working' ? Math.max(0, roundHours(fields.Leave.max - Leave, policy.decimals)) : 0;\n  const dayTotal = roundHours(ST + OT + Leave, policy.decimals);\n\n  const errorsByField = { ST: null, OT: null, Leave: null };\n  for (const violation of violations) {\n    if (violation.blocking && !errorsByField[violation.field]) {\n      errorsByField[violation.field] = violation.message;\n    }\n  }\n\n  return {\n    dayKind,\n    values: { ST, OT, Leave },\n    fields,\n    regularAllocated,\n    regularRemaining,\n    leaveRemaining,\n    overtimeCap,\n    dayTotal,\n    isFull: dayKind === 'working' && regularRemaining <= policy.epsilon,\n    violations,\n    errorsByField,\n    valid: !violations.some((v) => v.blocking),\n  };\n}\n\n// Cross-field derivation fired from the form's onValuesChange. Returns a\n// patch of ONLY the keys that actually need to change, or null when nothing\n// does (so the caller can skip a pointless setFieldsValue).\n//\n// Standard and Leave drive each other symmetrically to fill the 8h regular\n// allocation, in both directions — whichever field the user is actively\n// editing is the \"driver\" for that edit, and the OTHER one is recomputed as\n// (8 - driver): editing Standard down to 6 fills Leave with 2, and editing\n// Leave down to 6 fills Standard with 2, exactly the same way. This only\n// ever drives the field the user is NOT currently typing into — an edit to\n// Leave never rewrites Leave itself, only Standard, and vice versa.\n//\n// Crucially, an OUT-OF-RANGE edit never drives the other field: typing 8888\n// into Leave must not silently redefine Standard as 0 — it's left exactly as\n// is, and computeHoursPolicy's validator is what explains why it's invalid.\n// The same value is also never silently clamped back down here (that used to\n// happen and is exactly why no error ever appeared for an out-of-range Leave\n// entry — the value got silently rewritten to a valid one before the\n// validator had anything left to complain about). The lone exception is the\n// modal-just-opened case (changedKeys is empty, not a live edit) fixing up a\n// legacy Leave value left over from before Standard was last saved.\n//\n// Overtime is zeroed whenever the (possibly just-updated) Standard isn't\n// exactly 8 — the field is disabled in that state anyway (see\n// computeHoursPolicy) — checked unconditionally so it also repairs on open.\nexport function reconcileHours(dayKind, values, changedKeys = [], policy = DEFAULT_HOURS_POLICY) {\n  const ST = roundHours(values?.ST, policy.decimals);\n  const Leave = roundHours(values?.Leave, policy.decimals);\n  const OT = roundHours(values?.OT, policy.decimals);\n\n  if (dayKind === 'weekOff') {\n    const patch = {};\n    if (ST !== 0) patch.ST = 0;\n    if (Leave !== 0) patch.Leave = 0;\n    return Object.keys(patch).length ? patch : null;\n  }\n\n  if (dayKind === 'working') {\n    const patch = {};\n    const inRange = (v) => v >= 0 && v <= policy.regularDayHours + policy.epsilon;\n\n    if (changedKeys.includes('ST')) {\n      const leaveMax = clampHours(policy.regularDayHours - ST, 0, policy.regularDayHours, policy.decimals);\n      if (Leave !== leaveMax) patch.Leave = leaveMax;\n    } else if (changedKeys.includes('Leave')) {\n      if (inRange(Leave)) {\n        const stTarget = clampHours(policy.regularDayHours - Leave, 0, policy.regularDayHours, policy.decimals);\n        if (ST !== stTarget) patch.ST = stTarget;\n      }\n    } else {\n      // Modal just opened (no live edit) — repair a Leave value left over\n      // from before Standard was last saved, same as before.\n      const leaveMax = clampHours(policy.regularDayHours - ST, 0, policy.regularDayHours, policy.decimals);\n      if (Leave > leaveMax + policy.epsilon) patch.Leave = leaveMax;\n    }\n\n    const effectiveST = patch.ST !== undefined ? patch.ST : ST;\n    const otAllowed = Math.abs(effectiveST - policy.standardMaxHours) <= policy.epsilon;\n    if (!otAllowed && OT > policy.epsilon) {\n      patch.OT = 0;\n    }\n    return Object.keys(patch).length ? patch : null;\n  }\n\n  // holiday: nothing to reconcile, the form is hidden.\n  return null;\n}\n\nexport function describeCapacity(snapshot) {\n  if (!snapshot) return '';\n  if (snapshot.dayKind === 'holiday') return '';\n  if (snapshot.dayKind === 'weekOff') {\n    return `Week off — overtime only, up to ${snapshot.overtimeCap} hrs.`;\n  }\n  if (snapshot.isFull) {\n    return 'Maximum standard hours reached — 8 regular hours allocated.';\n  }\n  return `Maximum available leave: ${snapshot.leaveRemaining} hrs`;\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n  Alert, Button, Card, Form,\n  Input, InputNumber, message, Modal, Space, Tag, Tooltip, Typography, Upload,\n} from 'antd';\nimport {\n  CheckCircleOutlined, CheckOutlined, ClockCircleOutlined, CloseCircleOutlined,\n  DeleteOutlined, EyeOutlined,\n  FileExcelOutlined, FileImageOutlined, FileOutlined, FilePdfOutlined, FileWordOutlined,\n  InfoCircleOutlined, SendOutlined, SyncOutlined, UploadOutlined,\n} from '@ant-design/icons';\nimport dayjs from 'dayjs';\nimport AppButton from '../AppButton';\nimport { formatFileSize, getFileExtension } from '../upload/bulkUploadValidation.js';\nimport { getPeriodBadgeConfig } from '../cards/cardConfig.js';\nimport {\n  DEFAULT_HOURS_POLICY,\n  computeHoursPolicy,\n  reconcileHours,\n  resolveDayKind,\n} from './timesheetHoursPolicy.js';\nimport { scrollToFirstFormError } from '../../utils/scrollToFirstFormError.js';\nimport '../../styles/timesheet.css';\n\nconst { Text } = Typography;\n\n// ── Status colour map ──────────────────────────────────────────────────────\nconst STATUS_COLOR = {\n  draft:         'default',\n  logged:        'blue',\n  submitted:     'processing',\n  approved:      'success',\n  rejected:      'error',\n  resubmitted:   'purple',\n  reopened:      'warning',\n  save_draft:    'default',\n  pending:       'warning',\n  not_submitted: 'default',\n};\n\n// Status badge label + icon — used both as ApprovalActionBar's own status cue\n// and, exported, as the `headerExtra` badge on the Monthly Summary card\n// (<DynamicCards moduleName=\"timesheetMonthlySummary\" headerExtra={<StatusBadgeTag .../>} />).\nexport function StatusBadgeTag({ status }) {\n  if (!status || status === 'draft' || status === 'not_submitted') return null;\n  const map = {\n    submitted:   { icon: <CheckOutlined />,        color: 'blue',   label: 'Submitted' },\n    approved:    { icon: <CheckCircleOutlined />,   color: 'green',  label: 'Approved' },\n    rejected:    { icon: <CloseCircleOutlined />,   color: 'red',    label: 'Rejected' },\n    resubmitted: { icon: <SyncOutlined />,          color: 'purple', label: 'Re-Submitted' },\n    reopened:    { icon: <SyncOutlined />,          color: 'orange', label: 'Reopened' },\n    save_draft:  { icon: null,                      color: 'default',label: 'Draft' },\n  };\n  const cfg = map[status];\n  if (!cfg) return <Tag color={STATUS_COLOR[status] ?? 'default'}>{status}</Tag>;\n  return (\n    <Tag color={cfg.color} icon={cfg.icon} style={{ borderRadius: 20, fontSize: 12, padding: '2px 10px' }}>\n      {cfg.label}\n    </Tag>\n  );\n}\n\n// Standard vs Supplementary (or whatever the host app configures) — a\n// timesheet logged for a calendar month before the current one reads as the\n// \"past\" label, the current month (and `thresholdMonths` back) renders no\n// badge at all: \"Standard\" is the implicit default, so only the exception\n// (a late/supplementary month) needs calling out.\n// Labels/colors/threshold come entirely from getPeriodBadgeConfig(configKey),\n// which the host app can override via configureCoreTheme({ periodBadgeConfig }).\nexport function PeriodBadgeTag({ configKey = 'timesheet', month, year }) {\n  const cfg = getPeriodBadgeConfig(configKey);\n  const isPast = Boolean(month) && Boolean(year)\n    && dayjs(`${year}-${month}-01`).isBefore(dayjs().subtract(cfg.thresholdMonths, 'month'), 'month');\n  if (!isPast) return null;\n  return <Tag color={cfg.pastColor}>{cfg.pastLabel}</Tag>;\n}\n\n// ── Log type CSS class ─────────────────────────────────────────────────────\nconst LOG_TYPE_CLASS = {\n  working:  'timesheet-day-cell--working',\n  overtime: 'timesheet-day-cell--overtime',\n  leave:    'timesheet-day-cell--leave',\n  holiday:  'timesheet-day-cell--holiday',\n  weekoff:  'timesheet-day-cell--weekoff',\n};\n\n\n// ── Helpers ────────────────────────────────────────────────────────────────\nfunction numberValue(v, fallback = 0) {\n  const n = Number(v);\n  return Number.isFinite(n) ? n : fallback;\n}\n\nfunction formatHoursShort(v) {\n  const n = numberValue(v);\n  return n === 0 ? '0h' : `${n.toFixed(1).replace(/\\.0$/, '')}h`;\n}\n\n// Hour-split colours. Must stay in step with TIMESHEET_LEGEND on the consumer side.\nconst SPLIT_COLORS = {\n  ST:    '#D0E6FF',\n  OT:    '#AAFEBCA6',\n  leave: '#FFECBA',\n};\n\n// Convert a desired AREA fraction into a gradient stop position.\n//\n// On a diagonal (135deg) gradient across a square, a stop at 25% does NOT colour 25%\n// of the visible area — the corner is a triangle whose area grows as t². The area below\n// a stop at axis-fraction t is 2t² (for t <= 0.5), so invert that to place the stop.\n// Without this, 6h+2h would paint a stop at 75% but *look* like ~88% — the ratio the\n// user is meant to read off the cell would be wrong.\nfunction areaToStop(area, angle) {\n  const a = Math.min(Math.max(area, 0), 1);\n  // Straight (vertical/horizontal) gradients are already area-linear.\n  if (!String(angle).startsWith('135') && !String(angle).startsWith('45')) return a;\n  return a <= 0.5\n    ? Math.sqrt(a / 2)\n    : 1 - Math.sqrt((1 - a) / 2);\n}\n\n/**\n * buildDayGradient — background for a day cell, proportional to the hours logged.\n *\n * Returns null when the day has 0 or 1 hour types (a flat class colour is enough).\n * Exported so consumers can unit-test the ratio maths.\n */\nexport function buildDayGradient(day = {}, { angle = '135deg' } = {}) {\n  const segments = [\n    ['ST',    numberValue(day?.workingHours?.ST)],\n    ['OT',    numberValue(day?.workingHours?.OT)],\n    ['leave', numberValue(day?.leave?.CL) + numberValue(day?.leave?.SL)],\n  ].filter(([, hours]) => hours > 0);\n\n  const total = segments.reduce((sum, [, hours]) => sum + hours, 0);\n  if (segments.length < 2 || total <= 0) return null; // single type -> solid class colour\n\n  const stops = [];\n  let cumulative = 0;\n  segments.forEach(([key, hours], index) => {\n    const from = areaToStop(cumulative / total, angle) * 100;\n    cumulative += hours;\n    const to = index === segments.length - 1\n      ? 100\n      : areaToStop(cumulative / total, angle) * 100;\n    stops.push(`${SPLIT_COLORS[key]} ${from.toFixed(2)}% ${to.toFixed(2)}%`);\n  });\n\n  return `linear-gradient(${angle}, ${stops.join(', ')})`;\n}\n\nfunction getDayClass(day = {}, { isUnloggedHighlight = false, selected = false, selectable = false, reviewMode = false } = {}) {\n  const st = numberValue(day?.workingHours?.ST);\n  const ot = numberValue(day?.workingHours?.OT);\n  const leave = numberValue(day?.leave?.CL) + numberValue(day?.leave?.SL);\n  const isMixed = [st, ot, leave].filter((h) => h > 0).length > 1;\n\n  // A mixed day gets its background from the inline computed gradient, so no log-type\n  // colour class is applied (it would paint a flat colour over the split).\n  // A day outside the resource's assignment on this project (before it started\n  // or after it ended) reads as its own category — takes precedence over\n  // week-off/holiday so a pre-assignment Saturday doesn't read as \"day off\"\n  // (which implies an active engagement) when it's really \"not your project yet\".\n  //\n  // The single-type colour is derived from the actual ST/OT/Leave numbers,\n  // NOT trusted from the stored `logType` string: a weekend day logged purely\n  // as Overtime used to get saved with logType:\"working\" (DayLogModal's\n  // submit() fell back to \"working\" whenever Leave was 0, regardless of\n  // whether the hours were entered as Standard or Overtime), so it rendered\n  // blue — Standard's colour — instead of Overtime's green, contradicting the\n  // legend. Deriving it here fixes that for every already-saved record too,\n  // not just ones saved after the submit()-side fix.\n  const soleType = ot > 0 ? 'overtime' : st > 0 ? 'working' : leave > 0 ? 'leave' : null;\n  const outOfRange = Boolean(day?.isOutOfAssignmentRange);\n  const logType = outOfRange\n    ? null\n    : day?.isHoliday\n      ? 'holiday'\n      : soleType ?? (day?.isWeekOff ? 'weekoff' : null);\n  const status = day?.status;\n\n  return [\n    'timesheet-day-cell',\n    outOfRange ? 'timesheet-day-cell--out-of-range' : (!isMixed && logType ? (LOG_TYPE_CLASS[logType] ?? '') : ''),\n    day?.isFuture              ? 'timesheet-day-cell--future'             : '',\n    status === 'rejected'      ? 'timesheet-day-cell--rejected'           : '',\n    status === 'approved'      ? 'timesheet-day-cell--approved'           : '',\n    selected                   ? 'timesheet-day-cell--selected'           : '',\n    isUnloggedHighlight        ? 'timesheet-day-cell--unlogged-highlight' : '',\n    selectable                 ? 'timesheet-day-cell--selectable'         : '',\n    reviewMode                 ? 'timesheet-day-cell--review'             : '',\n  ].filter(Boolean).join(' ');\n}\n\n// ── TimesheetDayCell ───────────────────────────────────────────────────────\n/**\n * A single day in the timesheet calendar.\n *\n * Three modes, all opt-in so existing consumers are unaffected:\n *  - default        : resource logs hours (click -> DayLogModal via onSelect)\n *  - selectable     : quick-log selection (click -> onToggleSelect, NOT onSelect)\n *  - reviewMode     : approver sees ✓/✗ controls on hover\n *\n * The hours background is an inline gradient computed from the day's actual hours\n * (splitMode=\"proportional\"). Pass splitMode=\"fixed\" to restore the old static\n * 50/50 classes.\n */\nexport function TimesheetDayCell({\n  day,\n  readonly      = false,\n  selected      = false,\n  isUnloggedHighlight = false,\n  onSelect,\n  onQuickLog,\n  // hour split\n  splitMode  = 'proportional',\n  splitAngle = '135deg',\n  // quick-log selection\n  selectable = false,\n  onToggleSelect,\n  // approver day review\n  reviewMode = false,\n  onApproveDay,\n  onRejectDay,\n}) {\n  const st        = numberValue(day?.workingHours?.ST);\n  const ot        = numberValue(day?.workingHours?.OT);\n  const cl        = numberValue(day?.leave?.CL);\n  const sl        = numberValue(day?.leave?.SL);\n  const totalLeave = cl + sl;\n  const status     = day?.status;\n  const isApproved = status === 'approved';\n  const isRejected = status === 'rejected';\n\n  // An approved day is locked for the resource (the server enforces this too), but the\n  // approver must still be able to interact with it.\n  const locked      = isApproved && !reviewMode;\n  // Before the assignment started or after it ended — not a day off, the\n  // resource simply wasn't engaged on this project yet/anymore.\n  const outOfRange  = Boolean(day?.isOutOfAssignmentRange);\n  const canQuickLog = !readonly && !selectable && !outOfRange && !day?.isFuture && !day?.isHoliday && !day?.isWeekOff && !day?.isLogged;\n\n  const gradient = splitMode === 'proportional'\n    ? buildDayGradient(day, { angle: splitAngle })\n    : null;\n\n  const handleQuickLog = (e) => {\n    e.stopPropagation();\n    onQuickLog?.(day?.date);\n  };\n\n  const handleClick = () => {\n    // While selecting for quick log, a click toggles the day instead of opening the\n    // log modal.\n    if (selectable) {\n      onToggleSelect?.(day?.date);\n      return;\n    }\n    onSelect?.(day);\n  };\n\n  // In review mode a logged day is clickable (opens the day's review panel) even\n  // though the cell is readonly for editing — the approver still needs to select it.\n  const reviewClickable = reviewMode && day?.isLogged;\n\n  const cell = (\n    <button\n      type=\"button\"\n      className={getDayClass(day, { isUnloggedHighlight, selected, selectable, reviewMode })}\n      style={gradient ? { background: gradient } : undefined}\n      disabled={(readonly && !reviewClickable) || day?.isFuture || outOfRange || (locked && !reviewMode)}\n      onClick={handleClick}\n    >\n      {/* top row: date number + day abbr + quick-log clock */}\n      <span className=\"timesheet-day-cell__top\">\n        <span className=\"timesheet-day-cell__date\">\n          {day?.date ? dayjs(day.date).date() : '-'}\n          {isRejected && <span className=\"timesheet-day-cell__reject-dot\" />}\n        </span>\n        <span className=\"timesheet-day-cell__top-right\">\n          {canQuickLog && (\n            <Tooltip title=\"Quick log 8h\" placement=\"top\">\n              <ClockCircleOutlined\n                className=\"timesheet-day-cell__quick-log-icon\"\n                onClick={handleQuickLog}\n              />\n            </Tooltip>\n          )}\n          {!canQuickLog && !outOfRange && !day?.isHoliday && !day?.isWeekOff && !day?.isFuture && (\n            <ClockCircleOutlined className=\"timesheet-day-cell__quick-log-icon timesheet-day-cell__quick-log-icon--logged\" />\n          )}\n        </span>\n      </span>\n\n      {/* body: hour labels */}\n      <span className=\"timesheet-day-cell__body\">\n        {/* An out-of-range day gets no label at all — it isn't a holiday, isn't\n            a day off, and \"no log\" would wrongly imply the resource should\n            have logged something. Just a dimmed, unlabeled square. */}\n        {!outOfRange && day?.isHoliday && <Tag color=\"purple\" className=\"timesheet-type-tag\">H</Tag>}\n        {!outOfRange && day?.isWeekOff && !day?.isLogged && <Text type=\"secondary\" className=\"timesheet-no-log\">Off</Text>}\n\n        {/* Standard */}\n        {st > 0 && (\n          <span className=\"timesheet-hour-label\">\n            <span className=\"timesheet-hour-value\">{formatHoursShort(st)}</span>\n            <span className=\"timesheet-hour-suffix timesheet-hour-st\"> s</span>\n          </span>\n        )}\n        {/* Overtime */}\n        {ot > 0 && (\n          <span className=\"timesheet-hour-label timesheet-hour-label--ot\">\n            <span className=\"timesheet-hour-value\">{formatHoursShort(ot)}</span>\n            <span className=\"timesheet-hour-suffix timesheet-hour-ot\"> o</span>\n          </span>\n        )}\n        {/* Leave */}\n        {totalLeave > 0 && (\n          <span\n            className={`timesheet-hour-label timesheet-hour-label--leave${gradient ? ' timesheet-hour-label--split-end' : ''}`}\n          >\n            <span className=\"timesheet-hour-value\">{formatHoursShort(totalLeave)}</span>\n            <span className=\"timesheet-hour-suffix timesheet-hour-leave\"> L</span>\n          </span>\n        )}\n\n        {!outOfRange && !day?.isLogged && !day?.isHoliday && !day?.isWeekOff && !day?.isFuture && (\n          <Text type=\"secondary\" className=\"timesheet-no-log\">No log</Text>\n        )}\n      </span>\n\n      {/* Review verdict badge */}\n      {isApproved && <CheckOutlined className=\"timesheet-day-cell__verdict timesheet-day-cell__verdict--approved\" />}\n      {isRejected && <CloseCircleOutlined className=\"timesheet-day-cell__verdict timesheet-day-cell__verdict--rejected\" />}\n\n      {/* Approver ✓/✗, revealed on hover. Rendered as spans (not <button>) because\n          this cell is itself a <button> and nesting buttons is invalid HTML. */}\n      {reviewMode && day?.isLogged && (onApproveDay || onRejectDay) && (\n        <span className=\"timesheet-day-review-actions\">\n          {onApproveDay && (\n            <span\n              role=\"button\"\n              tabIndex={-1}\n              className=\"ts-approve\"\n              title=\"Approve this day\"\n              onClick={(e) => { e.stopPropagation(); onApproveDay(day?.date); }}\n            >\n              <CheckOutlined />\n            </span>\n          )}\n          {onRejectDay && (\n            <span\n              role=\"button\"\n              tabIndex={-1}\n              className=\"ts-reject\"\n              title=\"Reject this day\"\n              onClick={(e) => { e.stopPropagation(); onRejectDay(day?.date); }}\n            >\n              <CloseCircleOutlined />\n            </span>\n          )}\n        </span>\n      )}\n    </button>\n  );\n\n  // D3: hovering a rejected day surfaces WHY it was rejected. The tooltip wraps the\n  // whole cell (it used to hang off a 6px dot, which was almost impossible to hit).\n  if (isRejected && day?.rejectionReason) {\n    return (\n      <Tooltip title={day.rejectionReason} placement=\"top\">\n        {/* span wrapper: Tooltip needs a hoverable node even when the button is disabled */}\n        <span style={{ display: 'block', width: '100%' }}>{cell}</span>\n      </Tooltip>\n    );\n  }\n  return cell;\n}\n\n\n// antd's InputNumber infers a display precision from `step` when none is\n// given — with step={0.5} that's 1 decimal place ALWAYS, so a whole number\n// like 8 shows as \"8.0\" and an empty/zero field shows \"0.0\". These just\n// format/parse the value as plain JS Number->string, so whole numbers show\n// with no decimal at all and a value like 4.5 still shows exactly \"4.5\".\nconst formatHoursInput = (value) => (value === undefined || value === null ? '' : `${value}`);\nconst parseHoursInput = (value) => (value === '' || value === undefined ? undefined : Number(value));\n\n// ── DayLogModal ────────────────────────────────────────────────────────────\n// All hour rules (min/max, disabled states, cross-field limits, messages)\n// live in timesheetHoursPolicy.js — this component is a thin renderer over\n// one computeHoursPolicy(...) snapshot per render. `hoursStep` is a\n// back-compat shim for the entry precision; `policy` is the full override\n// (merged over DEFAULT_HOURS_POLICY) once company-level config exists.\nexport function DayLogModal({\n  open, day, saving = false, onCancel, onSubmit,\n  hoursStep, policy: policyOverride,\n}) {\n  const [form] = Form.useForm();\n  const watchedST = Form.useWatch('ST', form);\n  const watchedOT = Form.useWatch('OT', form);\n  const watchedLeave = Form.useWatch('Leave', form);\n\n  const policy = useMemo(\n    () => ({ ...DEFAULT_HOURS_POLICY, ...(hoursStep ? { step: hoursStep } : null), ...policyOverride }),\n    [hoursStep, policyOverride],\n  );\n\n  useEffect(() => {\n    if (!open) return;\n    const dayKind = resolveDayKind(day);\n    // No pre-filled Standard default on a fresh day. A partial day (e.g. 2h\n    // leave) is valid now, so silently defaulting Standard to 8 would let a\n    // resource Save a full day they never actually worked without touching\n    // anything — the resource must enter every value themselves. Existing\n    // logs still load their saved values.\n    const st = numberValue(day?.workingHours?.ST);\n    const ot  = numberValue(day?.workingHours?.OT);\n    const cl  = numberValue(day?.leave?.CL);\n    const sl  = numberValue(day?.leave?.SL);\n    const loaded = { ST: st, OT: ot, Leave: cl + sl };\n    // A week off's Standard/Leave inputs are disabled, so a legacy value\n    // saved before the day was reclassified would otherwise sit there as an\n    // unfixable error. Reconcile once on open instead of surfacing it. Pass\n    // no changed keys — a genuinely saved partial day (e.g. Standard 6 /\n    // Leave 1) must load exactly as saved, not get force-filled to Leave 2\n    // as if the user had just edited Standard.\n    const patch = reconcileHours(dayKind, loaded, [], policy);\n    // No `date` field: the modal title already states the date, so a second\n    // read-only copy of it inside the form was pure duplication.\n    form.setFieldsValue({ ...loaded, ...patch });\n  }, [day, form, open, policy]);\n\n  // One rule per field, all backed by the same policy engine — it is the\n  // sole arbiter of what's valid, so live validation and Save-time\n  // validation can never disagree.\n  const hoursRule = (field) => ({ getFieldValue }) => ({\n    validator() {\n      const { errorsByField } = computeHoursPolicy(day, {\n        ST: getFieldValue('ST'), OT: getFieldValue('OT'), Leave: getFieldValue('Leave'),\n      }, policy);\n      const message = errorsByField[field];\n      return message ? Promise.reject(new Error(message)) : Promise.resolve();\n    },\n  });\n\n  const revalidateAll = () => {\n    form.validateFields(['ST', 'OT', 'Leave']).catch(() => {});\n  };\n\n  // UX: Standard and Leave auto-fill each other to share the 8h regular\n  // allocation, symmetrically — editing either one fills the other with\n  // whatever's left (8 - the field just edited), in both directions. An\n  // out-of-range edit (e.g. typing 8888 into Leave) never drives the other\n  // field — see reconcileHours for why. Overtime is auto-zeroed only when\n  // Standard ends up somewhere other than exactly 8, since Overtime requires\n  // a full Standard day (see computeHoursPolicy).\n  const handleValuesChange = (_changed, allValues) => {\n    const patch = reconcileHours(resolveDayKind(day), allValues, Object.keys(_changed), policy);\n    if (patch) form.setFieldsValue(patch);\n    revalidateAll();\n  };\n\n  const submit = async () => {\n    let values;\n    try {\n      values = await form.validateFields();\n    } catch (errorInfo) {\n      // Scoped to this modal's own portal root — a plain document-wide query\n      // could otherwise focus an unrelated errored field elsewhere on the\n      // page (e.g. NotesPanel) instead of this form's.\n      const root = document.querySelector('.timesheet-log-modal') ?? document;\n      scrollToFirstFormError(errorInfo, form, { root });\n      return;\n    }\n    const stHours = numberValue(values.ST);\n    const otHours = numberValue(values.OT);\n    const leaveHours = numberValue(values.Leave);\n    const typesLogged = [stHours, otHours, leaveHours].filter((h) => h > 0).length;\n    onSubmit?.({\n      // Straight off the day being edited — the date was never user-editable\n      // (the old form field was permanently disabled), so there is no form\n      // value to read it back from.\n      date:         day?.date,\n      // More than one type present -> 'mixed' (the calendar cell renders the\n      // actual gradient split off the raw hour numbers regardless of this\n      // string). Exactly one type present -> name THAT type, not just\n      // 'working' whenever Leave happens to be 0 — that used to be the\n      // fallback for a week-off day logged purely as Overtime, so it was\n      // saved (and rendered) as if it were an ordinary Standard day, blue\n      // instead of Overtime's green.\n      logType:      typesLogged > 1 ? 'mixed' : otHours > 0 ? 'overtime' : leaveHours > 0 ? 'leave' : 'working',\n      workingHours: { ST: stHours, OT: otHours },\n      leave:        { CL: leaveHours, SL: 0 },\n      isHoliday:    Boolean(day?.isHoliday),\n      isWeekOff:    Boolean(day?.isWeekOff),\n      notes:        '',\n    });\n  };\n\n  // A holiday needs no log at all. A week off is different: the day is still\n  // loggable, just entirely as Overtime — Standard/Leave don't apply, so\n  // only a holiday hides the form outright.\n  const isLocked = day?.isHoliday;\n  const isWeekOff = Boolean(day?.isWeekOff) && !isLocked;\n  const dateLabel = day?.date ? dayjs(day.date).format('MMM DD, YYYY') : 'Log time';\n  const snapshot = useMemo(\n    () => computeHoursPolicy(day, { ST: watchedST, OT: watchedOT, Leave: watchedLeave }, policy),\n    [day, watchedST, watchedOT, watchedLeave, policy],\n  );\n\n  return (\n    <Modal\n      rootClassName=\"timesheet-log-modal\"\n      title={\n        <Space>\n          <Text strong>{dateLabel}</Text>\n          {day?.isHoliday && <Tag color=\"purple\">Holiday</Tag>}\n          {day?.isWeekOff  && <Tag>Week Off</Tag>}\n        </Space>\n      }\n      open={open}\n      onCancel={onCancel}\n      onOk={submit}\n      confirmLoading={saving}\n      okText=\"Save\"\n      cancelText=\"Cancel\"\n      destroyOnHidden\n      width={340}\n      footer={(_, { OkBtn, CancelBtn }) => (\n        <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n          <CancelBtn />\n          {!isLocked && <OkBtn />}\n        </Space>\n      )}\n    >\n      {/* Correcting a rejected day. This modal is used rarely (once a month) by\n          non-technical resources, so the block reads as a plain problem → steps\n          pair: WHY it came back, then exactly WHAT to do. Kept to two compact\n          strips so the form below stays in view. */}\n      {day?.rejectionReason && (\n        <div className=\"timesheet-log-reject\">\n          <div className=\"timesheet-log-reject__note\">\n            <CloseCircleOutlined className=\"timesheet-log-reject__icon\" />\n            <div className=\"timesheet-log-reject__body\">\n              <span className=\"timesheet-log-reject__title\">Sent back by your reviewer</span>\n              <span className=\"timesheet-log-reject__reason\">{day.rejectionReason}</span>\n            </div>\n          </div>\n          <div className=\"timesheet-log-reject__proof\">\n            <UploadOutlined className=\"timesheet-log-reject__proof-icon\" />\n            <div className=\"timesheet-log-reject__body\">\n              <span className=\"timesheet-log-reject__title timesheet-log-reject__title--proof\">\n                To fix it\n              </span>\n              <ol className=\"timesheet-log-reject__steps\">\n                <li>Correct the hours below.</li>\n                <li>Replace the proof / screenshot so it matches.</li>\n                <li>Save, then re-submit your timesheet.</li>\n              </ol>\n            </div>\n          </div>\n        </div>\n      )}\n      {isLocked ? (\n        <Alert\n          type=\"info\"\n          showIcon\n          message=\"Holiday — no manual log required.\"\n        />\n      ) : (\n        <>\n          {isWeekOff && (\n            <Alert\n              type=\"info\"\n              showIcon\n              message=\"Week off — overtime only.\"\n              style={{ marginBottom: 12 }}\n            />\n          )}\n          <Form\n            form={form}\n            layout=\"vertical\"\n            className=\"timesheet-log-form\"\n            validateTrigger={['onChange', 'onBlur']}\n            onValuesChange={handleValuesChange}\n          >\n            {/* Standard and Leave don't apply on a week off at all — only Overtime is\n                loggable, so both are shown disabled (greyed, per the reference\n                design) rather than hidden: the resource can still see them sitting\n                at 0 instead of the row silently disappearing. `disabled` comes\n                straight off the policy snapshot and still hard-blocks typing for a\n                week-off/holiday/maxed-out field. Deliberately NOT passing min/max to\n                the InputNumber itself, though: antd's InputNumber gates its own\n                onChange on the typed value being in-range, so a fully out-of-range\n                keystroke (e.g. typing \"287\") never reaches the Form at all — the\n                input LOOKS like it updated but the real field value silently stays\n                at whatever was last valid, and that stale value is what Save would\n                actually submit. With no min/max configured, every keystroke reaches\n                the Form and re-runs the hoursRule validator below, so the error\n                message appears immediately and Save always sees exactly what's on\n                screen — never a silently-diverged value.\n\n                Each field also gets a short `extra` note, but ONLY while it's\n                actually disabled — never as a constant caption while the field is\n                usable, and never alongside an active error (the error already\n                explains itself). */}\n            <Form.Item\n              name=\"ST\"\n              label={<span style={{ color: '#1d4ed8', fontWeight: 600 }}>Standard <span style={{ fontWeight: 400, color: '#6b7280' }}>hrs</span></span>}\n              dependencies={['Leave']}\n              rules={[hoursRule('ST')]}\n              extra={\n                !snapshot.errorsByField.ST && snapshot.fields.ST.disabled\n                  ? 'Disabled on a week off.'\n                  : undefined\n              }\n            >\n              <InputNumber step={snapshot.fields.ST.step} disabled={snapshot.fields.ST.disabled} style={{ width: '100%' }}\n                formatter={formatHoursInput}\n                parser={parseHoursInput}\n                addonAfter={<span style={{ color: '#1d4ed8', fontWeight: 700 }}>s</span>}\n              />\n            </Form.Item>\n            <Form.Item\n              name=\"OT\"\n              label={<span style={{ color: '#15803d', fontWeight: 600 }}>Overtime <span style={{ fontWeight: 400, color: '#6b7280' }}>hrs</span></span>}\n              dependencies={['ST']}\n              rules={[hoursRule('OT')]}\n              extra={\n                !snapshot.errorsByField.OT && snapshot.fields.OT.disabled\n                  ? 'Complete 8 standard hours to log overtime.'\n                  : undefined\n              }\n            >\n              <InputNumber step={snapshot.fields.OT.step} disabled={snapshot.fields.OT.disabled} style={{ width: '100%' }}\n                formatter={formatHoursInput}\n                parser={parseHoursInput}\n                addonAfter={<span style={{ color: '#15803d', fontWeight: 700 }}>o</span>}\n              />\n            </Form.Item>\n            <Form.Item\n              name=\"Leave\"\n              label={<span style={{ color: '#b45309', fontWeight: 600 }}>Leave <span style={{ fontWeight: 400, color: '#6b7280' }}>hrs</span></span>}\n              dependencies={['ST']}\n              rules={[hoursRule('Leave')]}\n              extra={\n                !snapshot.errorsByField.Leave && snapshot.fields.Leave.disabled\n                  ? (isWeekOff ? 'Disabled on a week off.' : 'Maximum reached — 8 regular hours allocated.')\n                  : undefined\n              }\n            >\n              <InputNumber step={snapshot.fields.Leave.step} disabled={snapshot.fields.Leave.disabled} style={{ width: '100%' }}\n                formatter={formatHoursInput}\n                parser={parseHoursInput}\n                addonAfter={<span style={{ color: '#b45309', fontWeight: 700 }}>L</span>}\n              />\n            </Form.Item>\n          </Form>\n          {/* No summary block and no per-field descriptive hints (e.g. \"Overtime\n              up to 16 hrs.\", \"Maximum available leave: 2 hrs.\") — those read as\n              confusing noise next to the fields. Each Form.Item's `rules`\n              validator is the only messaging: silent while valid, an explicit\n              error the moment a value is actually invalid. */}\n        </>\n      )}\n    </Modal>\n  );\n}\n\n// ── QuickLogSelectionBar ───────────────────────────────────────────────────\n/**\n * Footer bar for quick-log selection.\n *\n * Quick Log does not submit blind and does not open a modal: it strokes every eligible\n * day in the calendar, the user clicks cells to deselect any they don't want, and this\n * bar confirms only what is still selected.\n */\nexport function QuickLogSelectionBar({\n  count = 0,\n  total = 0,\n  hours = 8,\n  loading = false,\n  onConfirm,\n  onCancel,\n  onSelectAll,\n  onSelectNone,\n}) {\n  return (\n    <div className=\"timesheet-quicklog-bar\">\n      <Space size={8} wrap>\n        <Text strong>\n          {count === 0\n            ? 'No days selected'\n            : `Log ${hours}h standard on ${count} day${count === 1 ? '' : 's'}`}\n        </Text>\n        {total > 0 && (\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>\n            {count} of {total} eligible · click a day to deselect it\n          </Text>\n        )}\n      </Space>\n      <Space size={6}>\n        <Button size=\"small\" onClick={onSelectAll} disabled={count === total}>Select all</Button>\n        <Button size=\"small\" onClick={onSelectNone} disabled={count === 0}>Clear</Button>\n        <Button size=\"small\" onClick={onCancel}>Cancel</Button>\n        <Button\n          size=\"small\"\n          type=\"primary\"\n          icon={<ClockCircleOutlined />}\n          loading={loading}\n          disabled={count === 0}\n          onClick={onConfirm}\n        >\n          Confirm\n        </Button>\n      </Space>\n    </div>\n  );\n}\n\n// ── RejectionReasonModal ───────────────────────────────────────────────────\nexport function RejectionReasonModal({ open = false, loading = false, onSave, onCancel }) {\n  const [reason, setReason] = useState('');\n\n  useEffect(() => { if (open) setReason(''); }, [open]);\n\n  return (\n    <Modal\n      title=\"Rejection Reason\"\n      open={open}\n      onCancel={onCancel}\n      footer={\n        <Space>\n          <Button onClick={onCancel}>Cancel</Button>\n          <Button type=\"primary\" danger disabled={!reason.trim()} loading={loading} onClick={() => onSave?.(reason.trim())}>\n            Reject\n          </Button>\n        </Space>\n      }\n      destroyOnHidden\n    >\n      <Form layout=\"vertical\">\n        <Form.Item\n          label={<span><span style={{ color: '#ff4d4f' }}>*</span> Comments</span>}\n          help={!reason.trim() ? 'Rejection reason is required' : ''}\n          validateStatus={!reason.trim() ? 'error' : ''}\n        >\n          <Input.TextArea\n            rows={4} maxLength={1000} showCount\n            placeholder=\"Enter reason for rejection...\"\n            value={reason}\n            onChange={(e) => setReason(e.target.value)}\n          />\n        </Form.Item>\n      </Form>\n    </Modal>\n  );\n}\n\n// ── QuickLogBar (kept for backward compat) ─────────────────────────────────\nexport function QuickLogBar({ loading = false, disabled = false, onQuickLog }) {\n  return (\n    <Card size=\"small\" className=\"timesheet-quick-log\">\n      <Space wrap>\n        <AppButton\n          variant=\"primary\"\n          icon={<ClockCircleOutlined />}\n          loading={loading}\n          disabled={disabled}\n          onClick={() => onQuickLog?.('businessDays')}\n        >\n          Quick Log (8h s)\n        </AppButton>\n      </Space>\n    </Card>\n  );\n}\n\n// Extension → icon + colour tone for the attached-proof row. Deliberately a\n// local map rather than a shared export: AddFormV1 has its own copy bound to\n// its own v1-* class names, and the two rows are look-alikes, not one\n// component — that one is coupled to the dynamic-form field system. The\n// extension parsing is shared (getFileExtension), the JSX is not.\nconst PROOF_ICON_BY_EXT = {\n  '.pdf':  [FilePdfOutlined,   'pdf'],\n  '.doc':  [FileWordOutlined,  'word'],\n  '.docx': [FileWordOutlined,  'word'],\n  '.xls':  [FileExcelOutlined, 'excel'],\n  '.xlsx': [FileExcelOutlined, 'excel'],\n  '.csv':  [FileExcelOutlined, 'excel'],\n  '.png':  [FileImageOutlined, 'image'],\n  '.jpg':  [FileImageOutlined, 'image'],\n  '.jpeg': [FileImageOutlined, 'image'],\n  '.gif':  [FileImageOutlined, 'image'],\n  '.webp': [FileImageOutlined, 'image'],\n};\n\nfunction ProofTypeIcon({ fileName }) {\n  const [Icon, tone] = PROOF_ICON_BY_EXT[getFileExtension(fileName)] ?? [FileOutlined, 'default'];\n  return <Icon className={`timesheet-proof__type-icon timesheet-proof__type-icon--${tone}`} />;\n}\n\n// ── ProofUploadPreview ─────────────────────────────────────────────────────\n// This card is the resource's UPLOAD CONTROL, not an evidence viewer — the\n// manager's evidence view is the review page. So an attached proof reads as a\n// compact one-line receipt (type icon, name, size/status, View) rather than a\n// full-bleed screenshot: the old inline thumbnail cost ~260px of the column and\n// duplicated the caller's own preview. The full render belongs in whatever\n// viewer the caller opens from `onPreview` — on the timesheet pages that is a\n// right-side drawer, so the calendar stays visible beside the proof.\n//\n// @param {object}   [proof]      { fileName, size?, pending? } — only a freshly\n//   picked File carries `size`/`pending`; a saved proof payload has neither\n//   (no size, no uploaded-at), hence the degraded meta line.\n// @param {function} [onPreview]  called with `proof`; omit to hide View.\n// @param {function} [onRemove]   called with `proof`; omit to hide the delete\n//   button. Intended for a not-yet-uploaded pick — clearing a saved proof would\n//   need a backend it does not have.\n// @param {boolean}  [required]   marks the card title with the standard red\n//   asterisk. Proof is mandatory before a timesheet can be submitted, and an\n//   asterisk states that up front the way every other required field does —\n//   quieter than a standing warning banner under the card.\n// @param {string}   [previewUrl] @deprecated — drove the removed inline\n//   thumbnail. Still accepted so existing callers keep working; ignored.\nexport function ProofUploadPreview({\n  proof, uploading = false, disabled = false, required = false,\n  // eslint-disable-next-line no-unused-vars -- previewUrl kept for old callers\n  onUpload, onPreview, onRemove, previewUrl,\n}) {\n  const hasFile = Boolean(proof?.fileName);\n  const sizeText = proof?.size ? formatFileSize(proof.size) : '';\n  const extText = getFileExtension(proof?.fileName ?? '').replace('.', '').toUpperCase();\n  const statusText = proof?.pending ? 'Selected — uploads on submit' : 'Previously uploaded';\n  // Size wins over the extension label whenever it is known, so this upgrades\n  // by itself if the backend ever starts returning a size for saved proofs.\n  const metaText = [sizeText || extText, statusText].filter(Boolean).join(' • ');\n  // Read-only hosts never get an upload control; nor does an attached file that\n  // the row already lets you delete (see the Upload block below).\n  const showUpload = !disabled && !(hasFile && onRemove);\n\n  return (\n    <Card\n      className={`timesheet-proof${hasFile ? ' timesheet-proof--filled' : ''}`}\n      size=\"small\"\n      title={<>Proof / screenshot{required && <span className=\"timesheet-proof__required\"> *</span>}</>}\n    >\n      {hasFile ? (\n        <div className=\"timesheet-proof__file\">\n          <span className=\"timesheet-proof__file-icon\"><ProofTypeIcon fileName={proof.fileName} /></span>\n          <span className=\"timesheet-proof__file-info\">\n            <span className=\"timesheet-proof__file-name\" title={proof.fileName}>{proof.fileName}</span>\n            <span className=\"timesheet-proof__file-meta\">{metaText}</span>\n          </span>\n          <Space size={6} className=\"timesheet-proof__file-actions\">\n            {onPreview && (\n              <Button\n                size=\"small\"\n                icon={<EyeOutlined />}\n                className=\"timesheet-proof__view-btn\"\n                onClick={() => onPreview(proof)}\n              >\n                View\n              </Button>\n            )}\n            {onRemove && (\n              <Tooltip title=\"Remove\">\n                <Button\n                  size=\"small\"\n                  danger\n                  icon={<DeleteOutlined />}\n                  aria-label={`Remove ${proof.fileName}`}\n                  className=\"timesheet-proof__delete-btn\"\n                  onClick={() => onRemove(proof)}\n                />\n              </Tooltip>\n            )}\n          </Space>\n        </div>\n      ) : (\n        <Text type=\"secondary\" style={{ fontSize: 12 }}>Upload Proof</Text>\n      )}\n      {/* Replace is dropped once the row carries a delete button: remove then\n          upload is the same two clicks, so a third control for it is noise.\n          It stays for a file with no delete — a SAVED proof, which has no\n          delete API — because Replace is then the only way to change it, and a\n          rejected month explicitly asks the resource to do exactly that. */}\n      {showUpload && (\n        <Upload\n          beforeUpload={(file) => { onUpload?.(file); return false; }}\n          maxCount={1}\n          showUploadList={false}\n          disabled={disabled}\n          accept=\".pdf,.doc,.docx,.png,.jpg,.jpeg\"\n        >\n          <Button icon={<UploadOutlined />} loading={uploading} block size=\"small\" style={{ marginTop: 6 }}>\n            {hasFile ? 'Replace proof' : 'Upload proof'}\n          </Button>\n        </Upload>\n      )}\n      {/* Only tells the user anything before a file exists — hidden by CSS once\n          the row is showing what was actually attached. */}\n      <Text type=\"secondary\" className=\"timesheet-proof__hint\" style={{ fontSize: 11 }}>\n        Supports: .pdf, .doc, .docx, .png, .jpg — max 10 MB\n      </Text>\n    </Card>\n  );\n}\n\n// ── NotesPanel ─────────────────────────────────────────────────────────────\nexport function NotesPanel({ value, disabled = false, onChange, label = 'Notes / Comments', maxLength = 1000 }) {\n  const count = (value ?? '').length;\n  return (\n    <Card className=\"timesheet-notes\" size=\"small\" title={label}>\n      <div className=\"timesheet-notes__field\">\n        <Input.TextArea\n          className=\"timesheet-notes__textarea\"\n          rows={5}\n          maxLength={maxLength}\n          value={value}\n          disabled={disabled}\n          onChange={(e) => onChange?.(e.target.value)}\n          placeholder=\"Add notes or comments...\"\n        />\n      </div>\n      {/* Static count row (replaces antd showCount, which overlaps the card edge) */}\n      <div className=\"timesheet-notes__count\">{count} / {maxLength}</div>\n    </Card>\n  );\n}\n\n// ── ApprovalActionBar ──────────────────────────────────────────────────────\n// rejectionMode:\n//   'modal'  (default) — Reject opens RejectionReasonModal; the resource-facing\n//            Submit/Re-Submit bar (TimesheetCalendarPage) uses this, unchanged.\n//   'inline' — manager review mode: renders as a \"Review Notes\" card with an\n//            always-visible mandatory-comment textarea instead of a modal, plus\n//            the decided-state \"This timesheet is X.\" + Reopen (TimesheetReviewPage).\nexport function ApprovalActionBar({\n  status,\n  loading    = false,\n  readonly   = false,\n  rejectionReason,\n  rejectionMode = 'modal',\n  title = 'Review Notes',\n  hint = 'Review comment is mandatory while rejecting',\n  approveDisabled = false,\n  approveDisabledReason,\n  rejectDisabled = false,\n  rejectDisabledReason,\n  onSubmit,\n  onApprove,\n  onReject,\n  onReopen,\n}) {\n  const [rejectOpen, setRejectOpen] = useState(false);\n  const [rejectLoading, setRejectLoading] = useState(false);\n  const [inlineComment, setInlineComment] = useState('');\n\n  const pendingManagerAction = ['submitted', 'resubmitted', 'reopened', 'save_draft'].includes(status);\n  const isRejected  = status === 'rejected';\n  const isApproved  = status === 'approved';\n  const isSubmitted = status === 'submitted' || status === 'resubmitted';\n  // Reopened = the approver handed the month back. Like rejected, it is the\n  // RESOURCE's turn again, so it must offer an enabled Re-Submit — not the\n  // disabled \"Submitted\" a submitted-like state would produce.\n  const isReopened  = status === 'reopened';\n  const isDraft     = !status || status === 'draft' || status === 'not_submitted';\n\n  const handleReject = async (reason) => {\n    setRejectLoading(true);\n    try { await onReject?.(reason); setRejectOpen(false); }\n    finally { setRejectLoading(false); }\n  };\n\n  // Reopening hands the month back to the resource to correct and re-submit —\n  // it does NOT return it to \"submitted\", which is what this used to claim.\n  // It is also refused outright once the timesheet's finance record has been\n  // invoiced or paid, so the copy stops short of promising it will work.\n  const confirmReopen = () => Modal.confirm({\n    title: 'Reopen timesheet?',\n    content: 'This returns the month to the resource to correct and re-submit. '\n      + 'It cannot be reopened once its invoice or payment has been processed.',\n    okText: 'Reopen',\n    onOk: onReopen,\n  });\n\n  const submitInlineReject = () => {\n    const reason = inlineComment.trim();\n    if (!reason) { message.error('A review comment is required to reject'); return; }\n    onReject?.(reason);\n  };\n\n  if (rejectionMode === 'inline') {\n    return (\n      <Card size=\"small\" className=\"timesheet-review-notes-card\">\n        <div className=\"timesheet-review-notes-card__head\">\n          <Text strong>{title}</Text>\n          <Text type=\"secondary\" className=\"timesheet-review-notes-card__hint\">\n            <InfoCircleOutlined /> {hint}\n          </Text>\n        </div>\n\n        {rejectionReason && isRejected && (\n          <Alert type=\"error\" showIcon message=\"Rejected\" description={rejectionReason} className=\"timesheet-review-notes-card__alert\" />\n        )}\n\n        {isSubmitted ? (\n          <>\n            <Input.TextArea\n              rows={3}\n              maxLength={1000}\n              value={inlineComment}\n              onChange={(e) => setInlineComment(e.target.value)}\n              placeholder=\"Add your note\"\n              className=\"timesheet-review-notes-card__input\"\n            />\n            <div className=\"timesheet-review-notes-card__actions\">\n              <Tooltip title={rejectDisabled ? rejectDisabledReason : ''}>\n                <Button danger loading={loading} disabled={rejectDisabled} onClick={submitInlineReject}>Reject</Button>\n              </Tooltip>\n              <Tooltip title={approveDisabled ? approveDisabledReason : ''}>\n                <Button type=\"primary\" loading={loading} disabled={approveDisabled} onClick={onApprove}>Approve</Button>\n              </Tooltip>\n            </div>\n          </>\n        ) : (\n          <div className=\"timesheet-review-notes-card__decided\">\n            <Text type=\"secondary\">This timesheet is {status}.</Text>\n            {(isApproved || isRejected) && onReopen ? (\n              <Button icon={<InfoCircleOutlined />} loading={loading} onClick={confirmReopen}>Reopen</Button>\n            ) : null}\n          </div>\n        )}\n      </Card>\n    );\n  }\n\n  // Submit button label + disabled state.\n  //\n  // The label follows one rule: has this month been submitted before? If so the\n  // action is a RE-submission. \"Submit\" is therefore only ever shown on a month\n  // that has never left the resource's hands (draft / not submitted); every\n  // hand-back state — rejected or reopened — reads \"Re-Submit\".\n  let submitLabel = 'Submit';\n  let submitDisabled = false;\n  if (isSubmitted) { submitLabel = status === 'resubmitted' ? 'Re-Submitted' : 'Submitted'; submitDisabled = true; }\n  if (isRejected || isReopened) { submitLabel = 'Re-Submit'; submitDisabled = false; }\n  if (isApproved) { submitLabel = 'Approved'; submitDisabled = true; }\n\n  return (\n    <>\n      {rejectionReason && isRejected && (\n        <Alert type=\"error\" showIcon message=\"Rejected\" description={rejectionReason} style={{ marginBottom: 8 }} />\n      )}\n      <div className=\"timesheet-action-bar\">\n        {/* Resource submit / re-submit — always visible, disabled when already submitted */}\n        {(isDraft || isRejected || isReopened || isSubmitted || isApproved) && onSubmit && (\n          <AppButton\n            variant=\"primary\"\n            icon={<SendOutlined />}\n            loading={loading}\n            disabled={submitDisabled}\n            onClick={!submitDisabled ? onSubmit : undefined}\n            block\n          >\n            {submitLabel}\n          </AppButton>\n        )}\n\n        {/* Manager approve */}\n        {pendingManagerAction && onApprove && (\n          <AppButton variant=\"primary\" icon={<CheckOutlined />} loading={loading} onClick={onApprove}>\n            Approve\n          </AppButton>\n        )}\n        {/* Manager reject */}\n        {pendingManagerAction && onReject && (\n          <Button danger loading={loading} onClick={() => setRejectOpen(true)}>Reject</Button>\n        )}\n        {/* Reopen */}\n        {(isApproved || isRejected) && onReopen && (\n          <Button icon={<InfoCircleOutlined />} loading={loading} onClick={confirmReopen}>Reopen</Button>\n        )}\n      </div>\n\n      <RejectionReasonModal\n        open={rejectOpen}\n        loading={rejectLoading}\n        onSave={handleReject}\n        onCancel={() => setRejectOpen(false)}\n      />\n    </>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// FinanceTimesheetAnalysis — proves the finance figure ties back to the\n// approved timesheet: derived summary tiles, hours × rate equation, a\n// read-only calendar heatmap (CalendarCard controlled mode), weekly rollup\n// and the daily breakdown table. Everything is derived client-side from\n// the record's dailyLogs — no extra API calls.\n// ─────────────────────────────────────────────────────────────────────────\nimport { useMemo } from 'react';\nimport { Table, Tooltip } from 'antd';\nimport {\n  CalendarOutlined,\n  ClockCircleOutlined,\n  DollarOutlined,\n  FieldTimeOutlined,\n  RestOutlined,\n  ThunderboltOutlined,\n} from '@ant-design/icons';\nimport dayjs from 'dayjs';\nimport CalendarCard from '../cards/CalendarCard.jsx';\nimport { buildDayGradient } from '../timesheet/TimesheetComponents.jsx';\nimport {\n  FinanceEquation,\n  FinanceKpiRow,\n  FinanceSection,\n  FinanceStatusPill,\n} from './FinanceComponents.jsx';\nimport {\n  buildDailyRows,\n  buildWeeklyRollup,\n  deriveDayStats,\n  formatHours,\n  formatMoney,\n  formatRate,\n} from './financeUtils';\nimport './finance-components.css';\n\nconst num = (value) => (Number.isFinite(Number(value)) ? Number(value) : 0);\n\n// ── Calendar day cell (read-only heatmap) ──────────────────────────────────\n\nexport function FinanceDayCell(dateKey, dayObj, { isToday } = {}) {\n  const dayNumber = Number(dateKey.slice(-2));\n  const st = num(dayObj?.workingHours?.ST);\n  const ot = num(dayObj?.workingHours?.OT);\n  const leave = num(dayObj?.leave?.CL) + num(dayObj?.leave?.SL);\n  const total = st + ot;\n  const logged = Boolean(dayObj?.isLogged) || total > 0 || leave > 0;\n\n  const kind = !dayObj\n    ? 'blank'\n    : dayObj.isHoliday\n      ? 'holiday'\n      : logged && total > 0\n        ? 'work'\n        : leave > 0\n          ? 'leave'\n          : dayObj.isWeekOff\n            ? 'weekoff'\n            : 'blank';\n\n  const cls = [\n    'fin-daycell',\n    `fin-daycell--${kind}`,\n    dayObj?.status === 'approved' ? 'fin-daycell--approved' : '',\n    dayObj?.status === 'rejected' ? 'fin-daycell--rejected' : '',\n    isToday ? 'fin-daycell--today' : '',\n  ].filter(Boolean).join(' ');\n\n  const gradient = kind === 'work' ? buildDayGradient(dayObj) : null;\n\n  const cell = (\n    <div className={cls} style={gradient ? { background: gradient } : undefined}>\n      <span className=\"fin-daycell__num\">{dayNumber}</span>\n      {kind === 'work' ? (\n        <span className=\"fin-daycell__hours\">\n          {total % 1 === 0 ? total : total.toFixed(1)}h{ot > 0 ? <em> +OT</em> : null}\n        </span>\n      ) : kind === 'leave' ? (\n        <span className=\"fin-daycell__hours\">Leave</span>\n      ) : kind === 'holiday' ? (\n        <span className=\"fin-daycell__hours\">Holiday</span>\n      ) : null}\n    </div>\n  );\n\n  if (!dayObj) return cell;\n  const tooltip = [\n    dayjs(dateKey).format('ddd, MMM D'),\n    st ? `ST ${st}h` : null,\n    ot ? `OT ${ot}h` : null,\n    leave ? `Leave ${leave}h` : null,\n    dayObj.isHoliday ? 'Holiday' : null,\n    dayObj.status === 'rejected' ? `Rejected${dayObj.rejectionReason ? ` — ${dayObj.rejectionReason}` : ''}` : null,\n    dayObj.status === 'approved' ? 'Approved' : null,\n  ].filter(Boolean).join(' · ');\n  return <Tooltip title={tooltip}>{cell}</Tooltip>;\n}\n\nconst HEATMAP_LEGEND = [\n  { label: 'Standard', color: '#3b82f6' },\n  { label: 'Overtime', color: '#22c55e' },\n  { label: 'Leave', color: '#f59e0b' },\n  { label: 'Holiday', color: '#8b5cf6' },\n  { label: 'Rejected', color: '#ef4444' },\n];\n\n// ── Main component ─────────────────────────────────────────────────────────\n\nexport default function FinanceTimesheetAnalysis({\n  dailyLogs = [],\n  timesheetSummary = {},\n  rate = 0,\n  rateLabel = 'Rate',\n  amountLabel = 'Amount',\n  approvedHours,\n  month,\n  year,\n  monthLabel,\n  extraEquationTerms = [],\n}) {\n  const stats = useMemo(() => deriveDayStats(dailyLogs), [dailyLogs]);\n  const dayRows = useMemo(() => buildDailyRows(dailyLogs, rate), [dailyLogs, rate]);\n  const weekRows = useMemo(() => buildWeeklyRollup(dailyLogs, rate), [dailyLogs, rate]);\n\n  const totalHours = stats.totalHours || num(approvedHours);\n  const totalAmount = totalHours * num(rate);\n  const maxDayHours = Math.max(1, ...dayRows.map((d) => d.total));\n  const maxWeekHours = Math.max(1, ...weekRows.map((w) => w.total));\n\n  const tiles = [\n    { key: 'hours', label: 'Approved Hours', value: formatHours(totalHours), icon: <ClockCircleOutlined />, tone: 'brand', sub: `${stats.loggedDays} logged days` },\n    { key: 'st', label: 'Standard', value: formatHours(stats.stHours || timesheetSummary.totalSTHours), icon: <FieldTimeOutlined />, tone: 'neutral' },\n    { key: 'ot', label: 'Overtime', value: formatHours(stats.otHours || timesheetSummary.totalOTHours), icon: <ThunderboltOutlined />, tone: 'warning' },\n    { key: 'leave', label: 'Leave', value: formatHours(stats.leaveHours || timesheetSummary.leaveHours), icon: <RestOutlined />, tone: 'neutral', sub: `${stats.leaveDays} days` },\n    { key: 'avg', label: 'Avg / Logged Day', value: formatHours(stats.avgHoursPerLoggedDay), icon: <CalendarOutlined />, tone: 'info' },\n    { key: 'amount', label: amountLabel, value: formatMoney(totalAmount), icon: <DollarOutlined />, tone: 'success' },\n  ];\n\n  const dayChips = [\n    { label: 'Approved days', value: stats.approvedDays, tone: 'success' },\n    { label: 'Pending days', value: stats.pendingDays, tone: 'gold' },\n    { label: 'Rejected days', value: stats.rejectedDays, tone: stats.rejectedDays ? 'danger' : 'neutral' },\n    { label: 'Holidays', value: stats.holidayDays, tone: 'neutral' },\n    { label: 'Week-offs', value: stats.weekOffDays, tone: 'neutral' },\n  ];\n\n  const dailyColumns = [\n    {\n      title: 'Date',\n      dataIndex: 'date',\n      width: 150,\n      render: (d, row) => (\n        <div className=\"fin-cell-text\">\n          <span className=\"fin-cell__primary\">{d ? dayjs(d).format('ddd, MMM D') : '—'}</span>\n          {row.isHoliday ? <span className=\"fin-cell__secondary\">Holiday</span> : null}\n        </div>\n      ),\n    },\n    { title: 'ST', dataIndex: 'st', align: 'right', width: 70, render: (v) => v.toFixed(2) },\n    { title: 'OT', dataIndex: 'ot', align: 'right', width: 70, render: (v) => (v ? v.toFixed(2) : '—') },\n    { title: 'Leave', dataIndex: 'leave', align: 'right', width: 70, render: (v) => (v ? v.toFixed(2) : '—') },\n    {\n      title: 'Total',\n      dataIndex: 'total',\n      align: 'right',\n      width: 170,\n      render: (v) => (\n        <div className=\"fin-bar\">\n          <span className=\"fin-bar__track\"><span className=\"fin-bar__fill\" style={{ width: `${(v / maxDayHours) * 100}%` }} /></span>\n          <span className=\"fin-bar__value\">{v.toFixed(2)}</span>\n        </div>\n      ),\n    },\n    { title: amountLabel, dataIndex: 'amount', align: 'right', width: 110, render: (v) => <strong className=\"fin-cell-money__value\">{formatMoney(v)}</strong> },\n    { title: 'Status', dataIndex: 'status', align: 'center', width: 100, render: (s) => <FinanceStatusPill status={s} size=\"sm\" /> },\n    { title: 'Reviewer', dataIndex: 'reviewer', width: 130, render: (v) => v || <span className=\"fin-cell__secondary\">—</span> },\n    {\n      title: 'Remarks',\n      dataIndex: 'remarks',\n      ellipsis: true,\n      render: (v) => (v ? <Tooltip title={v}><span className=\"fin-remarks\">{v}</span></Tooltip> : <span className=\"fin-cell__secondary\">—</span>),\n    },\n  ];\n\n  const weeklyColumns = [\n    { title: 'Week', dataIndex: 'label', render: (v, w) => <FinanceTextRow primary={v} secondary={`${w.days} logged days`} /> },\n    { title: 'ST', dataIndex: 'st', align: 'right', width: 64, render: (v) => v.toFixed(1) },\n    { title: 'OT', dataIndex: 'ot', align: 'right', width: 64, render: (v) => (v ? v.toFixed(1) : '—') },\n    {\n      title: 'Hours',\n      dataIndex: 'total',\n      align: 'right',\n      width: 150,\n      render: (v) => (\n        <div className=\"fin-bar\">\n          <span className=\"fin-bar__track\"><span className=\"fin-bar__fill\" style={{ width: `${(v / maxWeekHours) * 100}%` }} /></span>\n          <span className=\"fin-bar__value\">{v.toFixed(1)}</span>\n        </div>\n      ),\n    },\n    { title: amountLabel, dataIndex: 'amount', align: 'right', width: 110, render: (v) => <strong className=\"fin-cell-money__value\">{formatMoney(v)}</strong> },\n  ];\n\n  return (\n    <div className=\"fin-analysis\">\n      <FinanceKpiRow items={tiles} compact />\n\n      <div className=\"fin-daychips\">\n        {dayChips.map((chip) => (\n          <span className={`fin-badge fin-badge--${chip.tone}`} key={chip.label}>\n            {chip.value} {chip.label}\n          </span>\n        ))}\n      </div>\n\n      <FinanceSection className=\"fin-equation-card\">\n        <FinanceEquation\n          terms={[\n            { value: formatHours(totalHours), label: 'Approved Hours' },\n            { op: '×' },\n            { value: formatRate(rate), label: rateLabel },\n            { op: '=' },\n            { value: formatMoney(totalAmount), label: amountLabel, tone: 'accent' },\n            ...extraEquationTerms,\n          ]}\n        />\n      </FinanceSection>\n\n      <div className=\"fin-analysis__grid\">\n        <CalendarCard\n          className=\"fin-heatmap\"\n          days={dailyLogs}\n          startDay=\"Mon\"\n          readonly\n          year={year}\n          month={month}\n          monthLabel={monthLabel}\n          legend={HEATMAP_LEGEND}\n          renderDayContent={FinanceDayCell}\n          onPrevMonth={() => {}}\n          onNextMonth={() => {}}\n        />\n        <FinanceSection title=\"Weekly Breakdown\" className=\"fin-weekly\">\n          <Table\n            className=\"fin-analysis-table\"\n            size=\"small\"\n            rowKey={(w) => w.label}\n            pagination={false}\n            dataSource={weekRows}\n            columns={weeklyColumns}\n            locale={{ emptyText: 'No logged weeks' }}\n          />\n        </FinanceSection>\n      </div>\n\n      <FinanceSection title={`Daily Breakdown — Hours × ${rateLabel} = ${amountLabel}`}>\n        <Table\n          className=\"fin-analysis-table\"\n          size=\"small\"\n          rowKey=\"key\"\n          pagination={false}\n          dataSource={dayRows}\n          columns={dailyColumns}\n          scroll={{ x: 900 }}\n          locale={{ emptyText: 'No approved day logs to analyse' }}\n          summary={() =>\n            dayRows.length ? (\n              <Table.Summary.Row className=\"fin-analysis-total\">\n                <Table.Summary.Cell index={0}><strong>Total</strong></Table.Summary.Cell>\n                <Table.Summary.Cell index={1} align=\"right\">{stats.stHours.toFixed(2)}</Table.Summary.Cell>\n                <Table.Summary.Cell index={2} align=\"right\">{stats.otHours ? stats.otHours.toFixed(2) : '—'}</Table.Summary.Cell>\n                <Table.Summary.Cell index={3} align=\"right\">{stats.leaveHours ? stats.leaveHours.toFixed(2) : '—'}</Table.Summary.Cell>\n                <Table.Summary.Cell index={4} align=\"right\"><strong>{totalHours.toFixed(2)}</strong></Table.Summary.Cell>\n                <Table.Summary.Cell index={5} align=\"right\"><strong>{formatMoney(totalAmount)}</strong></Table.Summary.Cell>\n                <Table.Summary.Cell index={6} />\n                <Table.Summary.Cell index={7} />\n                <Table.Summary.Cell index={8} />\n              </Table.Summary.Row>\n            ) : null\n          }\n        />\n      </FinanceSection>\n    </div>\n  );\n}\n\nfunction FinanceTextRow({ primary, secondary }) {\n  return (\n    <div className=\"fin-cell-text\">\n      <span className=\"fin-cell__primary\">{primary}</span>\n      {secondary ? <span className=\"fin-cell__secondary\">{secondary}</span> : null}\n    </div>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// financeApprovalConfig — declarative behaviour for the config-driven Finance\n// Approval flow. One record here per approval TYPE; the CONTRACT type (W2 /\n// C2C) is a data flag off the record (see financeApprovalEngine) that only\n// swaps the employer-side deduction row, so it is NOT a separate config.\n//\n// FinanceApprovalPanel reads exactly this shape and renders/permits nothing\n// that isn't declared here, so new stages or per-tenant tweaks are a config\n// edit, not a component change.\n//\n// action.api values are resolved by the HOST app (ZINNEXT-V2) to real API\n// calls — CORE-THEME stays backend-agnostic (window.__CORE_THEME_CONFIG__\n// pattern). The panel receives an `actions` prop mapping api-key → handler.\n// ─────────────────────────────────────────────────────────────────────────\n\nexport const FINANCE_TYPE_SUBMISSION_MANAGER = 'submissionManager';\nexport const FINANCE_TYPE_ONBOARDING_MANAGER = 'onboardingManager';\nexport const FINANCE_TYPE_CFO = 'cfo';\nexport const FINANCE_TYPE_ONLY_FINANCE = 'onlyFinance';\n// Re-approval stages — entered when the CFO REJECTS. Identical to their base\n// stage except the CFO's rejection reason is surfaced at the top so the\n// manager knows what to change before re-submitting.\nexport const FINANCE_TYPE_SUBMISSION_MANAGER_REAPPROVE = 'submissionManagerReapprove';\nexport const FINANCE_TYPE_ONBOARDING_MANAGER_REAPPROVE = 'onboardingManagerReapprove';\n\n// ─────────────────────────────────────────────────────────────────────────\n// FINANCE_DEFAULTS — everything the panel used to hardcode, declared once and\n// merged into every type by getFinanceApprovalConfig(). A stage overrides only\n// what it wants to differ; nothing has to be repeated per type.\n//\n// `source` arrays are dotted paths resolved against { record, identity, inputs,\n// computed } in the panel, first non-empty wins. That is what makes the Basic\n// Details grid and the header crumb DATA rather than JSX: adding, removing or\n// reordering a field is a config edit.\n// ─────────────────────────────────────────────────────────────────────────\n// fillTokens — substitutes {name} placeholders in an admin-configured string.\n// Warning and confirm copy on the approval surface is config (see\n// sections.rateBreakdown.proposed.overClient), so the live numbers have to be\n// injected rather than concatenated in the JSX — that is what keeps the wording\n// editable without a deploy. An unknown token is left INTACT so a typo in\n// config shows up as \"{propsed}\" instead of silently blanking the sentence.\nexport function fillTokens(template, tokens = {}) {\n  if (!template) return '';\n  return String(template).replace(\n    /\\{(\\w+)\\}/g,\n    (match, key) => (tokens[key] === undefined ? match : String(tokens[key])),\n  );\n}\n\nexport const FINANCE_DEFAULTS = {\n  // Tail of the engine's currency/unit resolution chains (see\n  // resolveFinanceInputs) — used only when the record itself carries neither.\n  rateUnit: 'hr',\n  currency: '$',\n\n  labels: {\n    // A single 0% employer VMS has two very different meanings and the panel\n    // must not conflate them (see engine: employerVmsAvailable).\n    employerVms: {\n      required: 'Employer VMS',\n      notRequired: 'Not required',\n      notRequiredSub: 'VMS not required for this submission',\n      unavailable: 'VMS Not available',\n      unavailableSub: 'No VMS percentage configured for this employer',\n    },\n  },\n\n  header: {\n    // The crumb above the title. Because it already carries the client and the\n    // job reference, those two are deliberately ABSENT from\n    // sections.jobClient.items below — they were being printed twice.\n    crumbSeparator: ' · ',\n    crumbFields: [\n      { key: 'client', source: ['record.client.clientName', 'identity.client'] },\n      { key: 'reqId', source: ['record.job.jobReferenceId', 'identity.reqId'] },\n    ],\n  },\n\n  sections: {\n    jobClient: {\n      title: 'Basic Details',\n      items: [\n        { key: 'jobTitle', label: 'Job Title', source: ['record.job.jobTitle', 'identity.role'] },\n        { key: 'jobLocation', label: 'Job Location', source: ['identity.location', 'record.job.jobLocation'] },\n        { key: 'candidateName', label: 'Candidate Name', source: ['identity.name', 'record.submission.candidateFullName'] },\n        { key: 'candidateEmail', label: 'Candidate Email', source: ['identity.email', 'record.submission.email'] },\n        { key: 'contractType', label: 'Employment Type', source: ['inputs.contractType'] },\n        { key: 'employer', label: 'Employer', source: ['record.submission.supplierName', 'identity.vendor'] },\n        { key: 'submittedBy', label: 'Submitted By', source: ['identity.submittedBy', 'record.submission.signatureEmail'] },\n        {\n          key: 'submittedAt',\n          label: 'Submitted Date',\n          source: ['identity.submittedAt', 'record.submission.createdAt'],\n          format: 'date',\n        },\n      ],\n    },\n    rateBreakdown: {\n      // Numeric policy for the editable proposed rate. decimals:2 keeps\n      // \"62.50\" valid and rejects a 3rd decimal at the keystroke; setting\n      // decimals:0 here makes the field integer-only with NO code change.\n      proposed: {\n        policy: {\n          decimals: 2,\n          min: 0,\n          message: 'Enter a valid amount — numbers only, up to 2 decimal places.',\n        },\n        // What happens when the proposed (client-facing) rate is ABOVE the\n        // Client Job Rate. This used to be an unconditional hard block, which\n        // conflated two very different situations: \"no rate entered at all\"\n        // (genuinely blocking — the margin, the CFO request and payroll are all\n        // derived from it) and \"the rate is higher than the client's posted\n        // range\", which is a commercial judgement the approver is entitled to\n        // make. Only the first still blocks.\n        //   'warn'   → show the comparison panel, approval stays available\n        //              behind a deliberate confirm step (default)\n        //   'block'  → the previous behaviour, restorable with no code change\n        //   'ignore' → no panel at all\n        overClientPolicy: 'warn',\n        overClient: {\n          title: 'Proposed rate is above the Client Job Rate',\n          // {proposed} {client} {delta} {pct} {unit} are substituted by the\n          // panel; keeping the copy here is what stops it becoming a literal\n          // in the JSX again.\n          body: 'You are asking the client for {delta} ({pct}) more than the rate posted on this job. Approving is allowed — the higher rate will be what goes to the client and what payroll is finalised against.',\n          confirmTitle: 'Approve above the client rate?',\n          confirmBody: 'The proposed rate of {proposed} exceeds the Client Job Rate of {client} by {delta} ({pct}). This will be recorded against your approval.',\n          confirmOk: 'Approve anyway',\n          confirmCancel: 'Go back',\n          // Used only when overClientPolicy is 'block'.\n          blockMessage: 'Proposed rate can’t exceed the Client Job Rate ({client}).',\n        },\n      },\n    },\n    // The referral rate deliberately reuses the SAME policy object shape, so\n    // both money inputs on this surface obey one rule.\n    referral: {\n      policy: {\n        decimals: 2,\n        min: 0,\n        message: 'Enter a valid amount — numbers only, up to 2 decimal places.',\n      },\n    },\n  },\n};\n\n// Shared approval trail — each type marks its own `current` step; earlier\n// steps render as completed, later steps are not shown for manager stages.\nconst TRAIL = [\n  { key: 'submitted', label: 'Recruiter Submitted' },\n  { key: 'manager', label: 'Manager Approved' },\n  { key: 'onboarding', label: 'Onboarding Confirmed' },\n  { key: 'cfo', label: 'CFO Review' },\n];\n\nexport const FINANCE_APPROVAL_CONFIG = {\n  // ── Submission-side finance review (Delivery Manager / Approve access) ───\n  // Reviews & adjusts the proposed rate, optionally attaches a referral, then\n  // approves the submission. Editable proposed + referral rate.\n  [FINANCE_TYPE_SUBMISSION_MANAGER]: {\n    title: 'Finance Review',\n    statusLabel: 'Pending Your Approval',\n    trail: { steps: TRAIL.slice(0, 2), current: 'manager', show: false },\n    sections: {\n      jobClient: { show: true },\n      clientJobRate: { show: true, note: true },\n      rateBreakdown: {\n        show: true,\n        employer: { show: true, editable: false },\n        proposed: { show: true, editable: true }, // ← Delivery Manager's rate input\n      },\n      // Delivery Manager (Approve access on Submissions) may also attach a\n      // referral at this stage — same shape as onboardingManager's referral\n      // card, so it reuses the panel's existing \"select\" rendering as-is.\n      referral: {\n        show: true,\n        toggle: true,\n        toggleLabel: 'Add Referral',\n        toggleHint: 'Include a referral payout — reduces the margin below.',\n        mode: 'select',\n        source: 'referrals',\n        optionLabelField: 'referalCompanyName',\n        rateEditable: true,\n        typeField: true,\n        lastRate: true,\n        linkBothWays: true,\n      },\n    },\n    margin: {\n      label: 'Realtek Margin',\n      formula: 'netProposed-netEmployer-referral',\n    },\n    actions: {\n      // requireProposedRate — the proposed rate is the ONE input on this stage\n      // and everything downstream (margin, CFO sign-off, payroll) is derived\n      // from it, so approving with it blank/0 is never valid. The panel\n      // disables the button and explains why on hover.\n      primary: {\n        key: 'approve', label: 'Approve', tone: 'primary', api: 'submissionApprove', requireProposedRate: true,\n      },\n      // Reject here does NOT collect an inline reason — clicking it hands off\n      // to the dedicated Reject popup (reason dropdown + comments). `openPopup`\n      // is the marker the host body reads to open that popup; the panel skips\n      // the inline reason box because `requireReason` is absent.\n      reject: { key: 'reject', label: 'Reject', tone: 'warn', api: 'submissionReject', openPopup: 'reject' },\n    },\n    // save the edited proposed rate + referral into submissions.proposedRate\n    // history / the linked referral, then run native approve (decision 1 =\n    // \"Save rate + native approve\").\n    persist: { proposedRateHistory: true, referralLink: true, rateHistory: true },\n    readOnly: false,\n  },\n\n  // ── Onboarding-side finance review (MSI / Approve+ReApprove access) ─────\n  // Manager may edit the proposed rate and attach a referral (dropdown from\n  // referrals.referalCompanyName) + referral rate, then send for CFO\n  // approval. `editToggle` renders both as a locked preview by default with\n  // an Edit button — see FinanceApprovalPanel's ratesEditing state.\n  [FINANCE_TYPE_ONBOARDING_MANAGER]: {\n    title: 'Onboarding Review',\n    statusLabel: 'Pending Onboarding',\n    trail: { steps: TRAIL.slice(0, 3), current: 'onboarding', show: true },\n    sections: {\n      jobClient: { show: true },\n      clientJobRate: { show: true, note: true },\n      rateBreakdown: {\n        show: true,\n        editToggle: true, // preview-first UX: Edit button reveals the inputs below\n        employer: { show: true, editable: false, locked: true },\n        proposed: { show: true, editable: true },\n      },\n      referral: {\n        show: true,\n        toggle: true, // \"Add Referral\" checkbox gates the whole referral card\n        toggleLabel: 'Add Referral',\n        toggleHint: 'Include a referral payout — reduces the total margin below.',\n        mode: 'select', // dropdown + rate input\n        source: 'referrals',\n        optionLabelField: 'referalCompanyName',\n        rateEditable: true,\n        typeField: true, // Recurring | One-time\n        lastRate: true, // show last paid referalRate for the picked referral\n        linkBothWays: true, // referralId→engagement, engagementId→referral (decision 3)\n      },\n    },\n    margin: {\n      label: 'Total Margin',\n      formula: 'netProposed-netEmployer-referral',\n    },\n    actions: {\n      primary: { key: 'send', label: 'Send for CFO Approval', tone: 'primary', api: 'cfoSend' },\n      reject: { key: 'reject', label: 'Reject', tone: 'warn', api: 'onboardingReject', requireReason: true },\n    },\n    persist: { proposedRateHistory: true, referralLink: true, referralRateOnEngagement: true, rateHistory: true },\n    readOnly: false,\n  },\n\n  // ── CFO ─────────────────────────────────────────────────────────────────\n  // Everything printed — no typeable fields. Referral shows only if one was\n  // attached upstream. Approve → finalize (advances to PO_MSA); reject needs\n  // only a reason — no \"Return To\" category. Whoever holds the ReApprove\n  // permission on Onboarding resends after a reject, regardless of what\n  // triggered it (access-controlled downstream, not routed by category).\n  [FINANCE_TYPE_CFO]: {\n    title: 'Final Approval',\n    statusLabel: 'Pending CFO Sign-off',\n    trail: { steps: TRAIL, current: 'cfo', show: true },\n    sections: {\n      jobClient: { show: true },\n      clientJobRate: { show: true, note: true },\n      rateBreakdown: {\n        show: true,\n        finalBadge: true,\n        employer: { show: true, editable: false },\n        proposed: { show: true, editable: false },\n      },\n      referral: {\n        // Printed ONLY when the onboarding manager actually enabled a referral\n        // (their checkbox) — otherwise the card and its margin term disappear.\n        show: 'ifEnabled',\n        mode: 'print',\n        typeChip: true,\n      },\n    },\n    margin: {\n      label: 'Total Margin',\n      formula: 'netProposed-netEmployer-referral',\n    },\n    actions: {\n      primary: { key: 'approve', label: 'Approve & Finalize', tone: 'primary', api: 'cfoApprove' },\n      reject: {\n        key: 'reject', label: 'Reject', tone: 'warn', api: 'cfoReject', requireReason: true,\n      },\n    },\n    persist: { rateHistory: false }, // CFO decision only; rates already logged\n    readOnly: true, // no inputs anywhere\n  },\n\n  // ── Read-only finance summary ───────────────────────────────────────────\n  // Page/detail-view surface: only the rate breakdown, an existing referral\n  // (when one was already attached upstream), and the resulting total margin.\n  // It never exposes referral controls or approval actions.\n  [FINANCE_TYPE_ONLY_FINANCE]: {\n    title: 'Finance Summary',\n    statusLabel: '',\n    header: { show: false },\n    trail: { steps: [], current: '', show: false },\n    sections: {\n      jobClient: { show: false },\n      clientJobRate: { show: false },\n      rateBreakdown: {\n        show: true,\n        finalBadge: true,\n        employer: { show: true, editable: false },\n        proposed: { show: true, editable: false, locked: true },\n      },\n      referral: {\n        show: 'ifExists',\n        mode: 'print',\n        typeChip: true,\n      },\n    },\n    margin: {\n      label: 'Total Margin',\n      formula: 'netProposed-netEmployer-referral',\n    },\n    actions: { show: false },\n    persist: { rateHistory: false },\n    readOnly: true,\n  },\n};\n\n// ── Re-approval stages (CFO rejected → back to the manager) ────────────────\n// Same surface as the base stage, plus the rejection banner. Built by\n// derivation so the two stay in lockstep with their base config.\nfunction withRejection(base, { title, primaryLabel, primaryApi }) {\n  return {\n    ...base,\n    title,\n    statusLabel: 'Rejected by CFO — Re-approval Needed',\n    rejection: {\n      show: true,\n      // where the reason lives on the record (checked in order). The\n      // submissionManager surface has no `engagement` object resolved (it's a\n      // plain submission review, not an engagement one) — its reason instead\n      // comes from the submission's own activity log: the last\n      // submissionActivity entry with activityType \"CFO Rejected\" (see\n      // workforceCFOApprovalController.go), attached by the manager-reapprove\n      // popup onto record.submission.cfoRejectionReason before the panel ever\n      // sees it. Harmless to check first for the onboarding surface too — it\n      // just won't have that path and falls through to the next source.\n      sources: [\n        'submission.cfoRejectionReason',\n        'engagement.financeApproval.rejectionReason',\n        'engagement.financeApproval.remarks',\n        'financeApprovalRequest.rejectionReason',\n        'rejectionReason',\n      ],\n      title: 'CFO Rejected This Request',\n    },\n    // A re-approval surface is a \"fix and resend\" step — it offers ONLY its\n    // forward action (Re-Approve / Re-send), never a reject. Dropping\n    // base.actions.reject means the panel renders no reject button here.\n    actions: {\n      primary: {\n        ...base.actions.primary,\n        label: primaryLabel,\n        // A re-approval may target a different handler than its base stage —\n        // e.g. the submission re-approval both re-approves AND re-sends to the\n        // CFO, so it uses its own combined api. Falls back to the base api.\n        ...(primaryApi ? { api: primaryApi } : {}),\n      },\n    },\n  };\n}\n\nFINANCE_APPROVAL_CONFIG[FINANCE_TYPE_SUBMISSION_MANAGER_REAPPROVE] = {\n  ...withRejection(\n    FINANCE_APPROVAL_CONFIG[FINANCE_TYPE_SUBMISSION_MANAGER],\n    // \"Send For Approval\" (not \"Re-Approve\"): after a CFO rate rejection the\n    // submission manager fixes the rate and re-sends it for CFO review — the\n    // handler re-approves the submission AND re-submits the engagement to the CFO.\n    { title: 'Finance Re-Review', primaryLabel: 'Send For Approval', primaryApi: 'submissionReapproveSend' },\n  ),\n  // The onboarding team may already have attached a referral before the CFO\n  // rejection. Show that saved referral as read-only during manager re-review\n  // and include its rate in the recalculated margin.\n  sections: {\n    ...FINANCE_APPROVAL_CONFIG[FINANCE_TYPE_SUBMISSION_MANAGER].sections,\n    referral: {\n      show: 'ifExists',\n      mode: 'print',\n      typeChip: true,\n    },\n  },\n  margin: {\n    label: 'Total Margin',\n    formula: 'netProposed-netEmployer-referral',\n  },\n};\n\nFINANCE_APPROVAL_CONFIG[FINANCE_TYPE_ONBOARDING_MANAGER_REAPPROVE] = withRejection(\n  FINANCE_APPROVAL_CONFIG[FINANCE_TYPE_ONBOARDING_MANAGER],\n  { title: 'Onboarding Re-Review', primaryLabel: 'Re-send for CFO Approval' },\n);\n\n// withDefaults — fill in anything a type did not declare from FINANCE_DEFAULTS.\n// Plain objects merge key-wise (so `sections.rateBreakdown.proposed` keeps its\n// own show/editable/locked AND gains the default policy); everything else,\n// arrays included, is taken WHOLE from the type when present — a stage that\n// declares its own `items` means exactly that list, not that list appended to\n// the defaults.\nconst isPlainObject = (v) => Boolean(v) && typeof v === 'object' && !Array.isArray(v);\n\nfunction withDefaults(value, defaults) {\n  if (!isPlainObject(defaults)) return value === undefined ? defaults : value;\n  if (value === undefined) return defaults;\n  if (!isPlainObject(value)) return value;\n  const out = { ...value };\n  for (const [key, fallback] of Object.entries(defaults)) {\n    out[key] = withDefaults(value[key], fallback);\n  }\n  return out;\n}\n\n// The merged configs are CACHED per type: the panel holds `config` in useMemo\n// dependency arrays, so returning a freshly built object on every render would\n// re-run the finance computation on every keystroke for no reason.\nconst resolvedConfigCache = new Map();\n\n// getFinanceApprovalConfig — safe accessor. Unknown type falls back to the\n// most restrictive (cfo / read-only) rather than throwing, so a misconfigured\n// host never exposes an editable panel by accident.\nexport function getFinanceApprovalConfig(type) {\n  const base = FINANCE_APPROVAL_CONFIG[type] ?? FINANCE_APPROVAL_CONFIG[FINANCE_TYPE_CFO];\n  if (!resolvedConfigCache.has(base)) resolvedConfigCache.set(base, withDefaults(base, FINANCE_DEFAULTS));\n  return resolvedConfigCache.get(base);\n}\n\n// resolveRejectionReason — first non-empty value from the config's source paths.\nexport function resolveRejectionReason(config, record) {\n  const paths = config?.rejection?.sources ?? [];\n  for (const path of paths) {\n    const value = path.split('.').reduce((acc, key) => acc?.[key], record);\n    if (value !== undefined && value !== null && String(value).trim() !== '') return String(value);\n  }\n  return '';\n}\n\n// marginIncludesReferral — the margin formula string is the single source of\n// truth for whether a stage folds the referral into the outcome.\nexport function marginIncludesReferral(config) {\n  return String(config?.margin?.formula ?? '').includes('referral');\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// financeApprovalEngine — pure, framework-free rate math + record resolution\n// for the config-driven Finance Approval flow (submissionManager /\n// onboardingManager / cfo). No JSX, no antd, no fetching — so it is unit\n// testable in isolation and shared identically across all three approval\n// surfaces and both contract types (W2 / C2C).\n//\n// Model (confirmed against zinnext-dev-api-v1):\n//   Client side (context only):\n//     netClientRate  = clientJobRate − clientJobRate × clientVms%\n//   Proposed side (feeds margin):\n//     discountVms    = proposedRate × clientVms%        (clients.vmsFee)\n//     netProposed    = proposedRate − discountVms\n//   Employer side (feeds margin):\n//     C2C: employerDeduction = employerRate × employerVms%   (submission employer)\n//     W2 : employerDeduction = employerRate × locationTax%   (employerLocationTax)\n//     netEmployer    = employerRate − employerDeduction\n//   Outcome:\n//     totalMargin    = netProposed − netEmployer − referralRate\n//   (referralRate is 0 unless a referral is present AND the type shows it.)\n// ─────────────────────────────────────────────────────────────────────────\n\nimport {\n  currencySymbol,\n  rateUnitLabel as unitLabel,\n  rateUnitShort as unitShort,\n  formatMoney as formatMoneyShared,\n  toNumber,\n} from '../../utils/currency.js';\n\nexport const CONTRACT_W2 = 'W2';\nexport const CONTRACT_C2C = 'C2C';\n\n// Last-resort display defaults. They are the FLOOR of the resolution chains\n// below, not a policy: a caller (the panel, from financeApprovalConfig) passes\n// its own `defaults` so the fallback unit/currency is admin-configurable per\n// stage, and these only apply when nothing at all was configured.\nexport const ENGINE_DEFAULTS = { rateUnit: 'hr', currency: '$' };\n\nconst num = (value) => {\n  const n = Number(value);\n  return Number.isFinite(n) ? n : 0;\n};\n\nconst truthy = (value) => value === true || value === 'true' || value === 1 || value === '1';\n\n// hasValue/firstDefined — `??` only skips null/undefined, so a field read\n// straight off a record (not through pick(), which already does this) stops\n// a real fallback dead if the stored value is \"\" — e.g. a client saved before\n// vmsPercentage existed still has SOME doc with the key present but empty,\n// which no plain `??` chain would ever fall through past to reach vmsFee.value.\nconst hasValue = (value) => value !== undefined && value !== null && value !== '';\nconst firstDefined = (...values) => values.find(hasValue);\n\nconst round2 = (value) => Math.round((num(value) + Number.EPSILON) * 100) / 100;\n\n// last(array) — the newest entry of an append-only history array (proposedRate,\n// candidateBudget, submission_current_employer …). Non-arrays pass through.\nexport function lastEntry(value) {\n  if (Array.isArray(value)) return value.length ? value[value.length - 1] : {};\n  return value ?? {};\n}\n\n// idOf — normalize a Mongo id in any of its wire shapes to a plain string.\nexport const idOf = (v) => String(v?.$oid ?? v?._id?.$oid ?? v?._id ?? v?.id ?? v ?? '');\n\n// flattenGroups — /admin/form-groups returns groups[].fields[] as\n// { field, value }. Flatten to { <field>: value }. Dotted field names\n// (\"candidateBudget.candidateBudgetStart\") are preserved verbatim — pick()\n// reads them natively. This is the authoritative record source on backends\n// with no by-id detail route.\nexport function flattenGroups(groups = []) {\n  const flat = {};\n  groups.forEach((group) => {\n    (group.fields ?? []).forEach((f) => {\n      const key = f.field ?? f.fieldName ?? f.name;\n      if (key && f.value !== undefined && f.value !== null && f.value !== '') {\n        flat[key] = f.value;\n      }\n    });\n  });\n  return flat;\n}\n\n// unflattenRecord — the exact inverse of flattenGroups. Configured field keys\n// are dotted when the value is stored nested (\"jobPayDetails.clientBudgetStart\",\n// \"vmsFeeHistory.vmsPercentage\"); rebuild the real nested shape so a record\n// assembled from form-groups reads identically to a raw Mongo document.\n// Generic — no field name appears here, so newly configured nested fields work\n// with no change. A scalar never clobbers a container another key already built.\nexport function unflattenRecord(flat = {}) {\n  const out = {};\n  for (const [key, value] of Object.entries(flat)) {\n    const parts = String(key).split('.');\n    let cursor = out;\n    for (let i = 0; i < parts.length - 1; i += 1) {\n      const part = parts[i];\n      if (!cursor[part] || typeof cursor[part] !== 'object' || Array.isArray(cursor[part])) {\n        cursor[part] = {};\n      }\n      cursor = cursor[part];\n    }\n    const leaf = parts[parts.length - 1];\n    if (cursor[leaf] && typeof cursor[leaf] === 'object' && !Array.isArray(cursor[leaf])) continue;\n    cursor[leaf] = value;\n  }\n  return out;\n}\n\n// findEmployerRow — the employer (addRow) group, identified by carrying an\n// `employerId` field rather than by its label, so renaming the group in admin\n// can't break resolution. Returns { employerId, location, tax, vmsCommission… }.\nexport function findEmployerRow(groups = []) {\n  const group = groups.find((g) => (g.fields ?? []).some((f) => (f.field ?? f.name) === 'employerId'));\n  if (!group) return {};\n  const rows = Array.isArray(group.rows) ? group.rows : null;\n  if (rows?.length) return rows[rows.length - 1] ?? {};\n  const row = {};\n  (group.fields ?? []).forEach((f) => {\n    const key = f.field ?? f.name;\n    if (key && f.value !== undefined && f.value !== null && f.value !== '') row[key] = f.value;\n  });\n  return row;\n}\n\n// pick(record, container[, key]) — read a value that may be stored as ANY of:\n//   • a history ARRAY   record.proposedRate = [{…}, {…}]   → newest entry\n//   • a flat OBJECT     record.proposedRate = {…}\n//   • flattened DOTTED  record['proposedRate.candidateProposedRate']  (detail\n//     header record shape) or record['proposedRate.0.candidateProposedRate']\n//   • a scalar          record.contractType = 'W2'   (call with no key)\n// Returns undefined when nothing is present, so callers can ?? fall back.\nexport function pick(record, container, key) {\n  if (!record) return undefined;\n  const c = record[container];\n  if (key === undefined) {\n    // scalar container (e.g. contractType, city)\n    if (c !== undefined && c !== null && c !== '') return c;\n    return undefined;\n  }\n  // array → newest entry; object → direct\n  if (Array.isArray(c) && c.length) {\n    const v = c[c.length - 1]?.[key];\n    if (v !== undefined && v !== null && v !== '') return v;\n  } else if (c && typeof c === 'object') {\n    const v = c[key];\n    if (v !== undefined && v !== null && v !== '') return v;\n  }\n  // flattened dotted key(s)\n  const dotted = record[`${container}.${key}`];\n  if (dotted !== undefined && dotted !== null && dotted !== '') return dotted;\n  const dotted0 = record[`${container}.0.${key}`];\n  if (dotted0 !== undefined && dotted0 !== null && dotted0 !== '') return dotted0;\n  return undefined;\n}\n\n// normalizeContract — collapse the many spellings the DB carries\n// (contractType \"C2C\"/\"c2c\", onboardingType \"C2C\", \"Corp to Corp\", \"W2\"…)\n// into CONTRACT_W2 / CONTRACT_C2C. Defaults to C2C (the referral-bearing,\n// employer-VMS path) only when nothing W2-ish is present.\nexport function normalizeContract(raw) {\n  const text = String(raw ?? '').trim().toUpperCase().replace(/[\\s_-]/g, '');\n  if (text === 'W2' || text.includes('W2')) return CONTRACT_W2;\n  return CONTRACT_C2C;\n}\n\n// pct(base, percent) — deduction amount for a percentage rate.\nfunction pct(base, percent) {\n  return round2((num(base) * num(percent)) / 100);\n}\n\n// ── Record resolution ──────────────────────────────────────────────────────\n// resolveFinanceInputs — pull every rate/percent the engine needs off a\n// resolved record ({ submission, job, client, employer, engagement }) plus\n// optional lookups (clientVmsFee, employerLocationTax rows). Every source is\n// defensive: missing joins resolve to 0 rather than throwing, so a partial\n// record still renders a coherent (if zeroed) breakdown.\n//\n// `defaults` ({ rateUnit, currency }) is the tail of the unit/currency\n// resolution chains — supplied by the caller from financeApprovalConfig so the\n// fallback is admin config rather than a literal buried in here.\nexport function resolveFinanceInputs(record = {}, lookups = {}, defaults = {}) {\n  const fallback = { ...ENGINE_DEFAULTS, ...(defaults ?? {}) };\n  const submission = record.submission ?? record ?? {};\n  const job = record.job ?? {};\n  const client = record.client ?? {};\n  const engagement = record.engagement ?? {};\n\n  const contractType = normalizeContract(\n    pick(submission, 'contractType') ?? engagement.onboardingType ?? record.contractType,\n  );\n\n  // Client Job Rate — jobs.jobPayDetails, else the submission's own client\n  // budget. A range keeps the TO end (the ceiling we bill against).\n  const pay = job.jobPayDetails ?? {};\n  const clientJobRateFrom = num(pay.clientBudgetStart ?? pick(submission, 'clientBudget', 'clientBudgetStart'));\n  const clientJobRateTo = num(pay.clientBudgetEnd ?? pick(submission, 'clientBudget', 'clientBudgetEnd')) || clientJobRateFrom;\n  const clientJobRate = clientJobRateTo || clientJobRateFrom;\n\n  // Discount (VMS) — Client form's \"Account & Billing Setup\" group now keeps\n  // this as PROPER HISTORY (cmd/wire-client-vms-history): every save appends\n  // {vmsPercentage, vmsPercentageType, timestamp, updatedBy} to\n  // clients.vmsFeeHistory[] instead of overwriting two flat fields, so a rate\n  // change never erases what the fee used to be. Fallback chain, most-current\n  // first: vmsFeeHistory's LAST entry → the old flat vmsPercentage/\n  // vmsPercentageType fields (clients saved between the form existing and this\n  // history migration) → the legacy nested vmsFee object (clients that predate\n  // the form group entirely and were never re-saved).\n  const vmsFeeEntry = lastEntry(client.vmsFeeHistory) ?? {};\n  const vmsFee = lookups.clientVmsFee ?? client.vmsFee ?? {};\n  // vmsPercentage (however it's sourced) wins OUTRIGHT once it's actually set\n  // — vmsFee.isApplicable must NOT gate it: that flag belongs to the legacy\n  // object and is often stale/false on a client whose admin has since set a\n  // real vmsPercentage (e.g. seeded false, never revisited). isApplicable only\n  // gates the FINAL fallback, where vmsFee is the only source we have.\n  const clientVmsPercent = hasValue(vmsFeeEntry.vmsPercentage)\n    ? num(vmsFeeEntry.vmsPercentage)\n    : hasValue(client.vmsPercentage)\n      ? num(client.vmsPercentage)\n      : vmsFee.isApplicable === false\n        ? 0\n        : num(firstDefined(\n          vmsFee.value, vmsFee.percent,\n          typeof vmsFee === 'number' ? vmsFee : undefined,\n          pick(submission, 'clientVmsPercent'), pick(submission, 'vmsPercent'),\n        ));\n  // Billing cadence for the VMS discount — \"recurring\" (every cycle, the\n  // long-standing default/behavior) or \"onetime\" (a single deduction). Purely\n  // descriptive here: computeFinance/callers surface it for display; the\n  // per-cycle amount math is unchanged for either type so existing totals\n  // never move because of this field.\n  // NOTE: vmsFee.type is \"PERCENTAGE\"/\"FLAT\" — the unit the legacy value is\n  // in, NOT a billing cadence — so it is deliberately not a fallback here.\n  const clientVmsPercentageType = String(\n    firstDefined(vmsFeeEntry.vmsPercentageType, client.vmsPercentageType) ?? 'recurring',\n  ).toLowerCase();\n\n  // Proposed Rate — current value and immutable history are stored separately\n  // by onboarding. The newest proposedRateHistory snapshot is authoritative after\n  // an edit; proposedRateCurrent is the current-value fallback; proposedRate keeps\n  // backward compatibility with older submissions.\n  const proposedRateHistory = Array.isArray(submission.proposedRateHistory)\n    ? submission.proposedRateHistory.filter(Boolean)\n    : [];\n  const proposedRateEntry = proposedRateHistory.length\n    ? proposedRateHistory[proposedRateHistory.length - 1]\n    : (submission.proposedRateCurrent && typeof submission.proposedRateCurrent === 'object'\n      ? submission.proposedRateCurrent\n      : lastEntry(submission.proposedRate));\n  const proposedRate = num(\n    proposedRateEntry?.candidateProposedRate\n    ?? proposedRateEntry?.proposedRate\n    ?? proposedRateEntry?.rate\n    ?? pick(submission, 'proposedRate', 'candidateProposedRate')\n    ?? record.proposedRateValue,\n  );\n\n  // Currency — resolved MOST-SPECIFIC-FIRST across every place a rate currency\n  // can live, ending at the job (a submission created before the currency field\n  // existed still bills in the job's currency, not in a guessed dollar).\n  // Two values come out of this deliberately:\n  //   currencyRaw — exactly what was stored (\"USD\" / \"$\" / \"INR\"). This is what\n  //                 gets WRITTEN BACK on approve, so approving never rewrites a\n  //                 tenant's ISO code into a symbol.\n  //   currency    — the same value normalised through the shared\n  //                 currencySymbol(), because the old code prepended the raw\n  //                 value and a stored \"USD\" therefore printed \"USD100\".\n  const currencyRaw = firstDefined(\n    proposedRateEntry?.candidateProposedRateCurrencySymbol,\n    proposedRateEntry?.candidateProposedRateCurrency,\n    pick(submission, 'proposedRate', 'candidateProposedRateCurrencySymbol'),\n    pick(submission, 'proposedRate', 'candidateProposedRateCurrency'),\n    pick(submission, 'candidateBudget', 'candidateBudgetCurrencySymbol'),\n    pick(submission, 'candidateBudget', 'candidateBudgetCurrency'),\n    pay.clientBudgetCurrencySymbol,\n    pay.clientBudgetCurrency,\n    job.currency,\n    job.currencySymbol,\n    fallback.currency,\n  );\n  const currency = currencySymbol(currencyRaw, fallback.currency);\n\n  // Rate unit — the period every rate on this submission is quoted in. Same\n  // shape of chain: what the recruiter actually chose on the submission wins,\n  // then the candidate budget's unit, then the job's own budget unit, then the\n  // configured default. Nothing here assumes hours; \"/hr\" used to be hardcoded\n  // in a dozen render sites AND written back on approve, which silently\n  // overwrote a daily/monthly rate's unit with \"hr\".\n  const rateUnit = firstDefined(\n    proposedRateEntry?.candidateProposedRateUnit,\n    proposedRateEntry?.rateUnit,\n    pick(submission, 'proposedRate', 'candidateProposedRateUnit'),\n    pick(submission, 'candidateBudget', 'candidateBudgetUnit'),\n    pay.clientBudgetUnit,\n    fallback.rateUnit,\n  );\n\n  // Employer Rate — candidateBudget (or candidateRate) history/object/dotted.\n  const employerRate = num(\n    pick(submission, 'candidateBudget', 'candidateBudgetStart')\n    ?? pick(submission, 'candidateBudget', 'candidateBudgetRate')\n    ?? pick(submission, 'candidateRate', 'candidateAcceptedRate'),\n  );\n\n  // Employer-side C2C VMS — submission_current_employer[].{isVmsRequired,\n  // vmsPercentage, vmsType}, the fields the submission form itself writes\n  // (Employer group, gated to C2C by showIf — see the Form Groups config).\n  // Gated on isVmsRequired: when the recruiter left VMS unchecked, the\n  // deduction is 0 even if a stale vmsPercentage sits on an older row —\n  // \"only if this boolean is true\" is enforced HERE, not just at entry.\n  const employerVmsRequired = truthy(\n    pick(submission, 'submission_current_employer', 'isVmsRequired')\n    ?? pick(submission, 'submission_current_employer', 'isVMSRequired'), // legacy key, pre-rename rows\n  );\n  // The percentage as CONFIGURED, independent of the checkbox. Kept separate\n  // from employerVmsPercent (the one that feeds the math) because the UI has to\n  // tell two different situations apart, and a single 0 cannot:\n  //   • the employer HAS a VMS % but the recruiter unchecked \"VMS Required\"\n  //     → \"Not required\" (a deliberate choice on this submission)\n  //   • the employer has no VMS % configured anywhere at all\n  //     → \"VMS Not available\" (nothing to apply, nothing was decided)\n  // A configured 0% counts as *not available*: it deducts nothing and is\n  // indistinguishable from \"never set\", so calling it \"not required\" would put\n  // us back where we started.\n  const employerVmsPercentConfigured = num(firstDefined(\n    pick(submission, 'submission_current_employer', 'vmsPercentage'),\n    pick(submission, 'submission_current_employer', 'vmsCommission'), // legacy key\n    record.employer?.vmsPercentage,\n    record.employer?.vmsCommission,\n    engagement.vmsPercent,\n  ));\n  const employerVmsAvailable = employerVmsPercentConfigured > 0;\n  const employerVmsPercent = employerVmsRequired ? employerVmsPercentConfigured : 0;\n  const employerVmsType = String(\n    pick(submission, 'submission_current_employer', 'vmsType')\n    ?? pick(submission, 'submission_current_employer', 'vmsCommissionType') // legacy key\n    ?? 'Recurring',\n  );\n\n  // W2 location tax — the employer row only carries locationId (tax itself is\n  // payloadMode:\"skip\", never stored); lookups.locationTaxPercent is resolved\n  // by financeApprovalData.js matching that id against the locations\n  // collection. inlineTax/name-matching are fallbacks for rows saved before\n  // that lookup existed.\n  const inlineTax = pick(submission, 'submission_current_employer', 'tax');\n  const locationTaxPercent = lookups.locationTaxPercent != null\n    ? num(lookups.locationTaxPercent)\n    : inlineTax != null && inlineTax !== ''\n      ? num(inlineTax)\n      : matchLocationTax(lookups.locationTaxRows,\n        pick(submission, 'submission_current_employer', 'locationId')\n        ?? pick(submission, 'submission_current_employer', 'location') // legacy key\n        ?? pick(submission, 'city') ?? pick(submission, 'state') ?? job.jobLocation);\n\n  return {\n    contractType,\n    currency,\n    currencyRaw,\n    rateUnit,\n    clientJobRate,\n    clientJobRateFrom,\n    clientJobRateTo,\n    clientVmsPercent,\n    clientVmsPercentageType,\n    proposedRate,\n    employerRate,\n    employerVmsPercent,\n    employerVmsPercentConfigured,\n    employerVmsAvailable,\n    employerVmsType,\n    employerVmsRequired,\n    locationTaxPercent,\n  };\n}\n\n// matchLocationTax — find the taxValue for a location inside an\n// employerLocationTax.locationTax[] rows array. Case-insensitive contains\n// match on the location string; 0 when nothing matches.\nexport function matchLocationTax(rows, location) {\n  if (!Array.isArray(rows) || !location) return 0;\n  const needle = String(location).trim().toLowerCase();\n  const hit = rows.find((row) => {\n    const loc = String(row?.location ?? '').trim().toLowerCase();\n    return loc && (loc === needle || needle.includes(loc) || loc.includes(needle));\n  });\n  return num(hit?.taxValue ?? hit?.taxPercent);\n}\n\n// ── The calculation ─────────────────────────────────────────────────────────\n// computeFinance(inputs, { referralRate, includeReferral, deductReferral }) → every derived\n// line the UI renders, all rounded to cents. `overrides` lets a surface swap\n// in a live-edited value (submissionManager's editable proposed rate) without\n// re-resolving the whole record.\nexport function computeFinance(inputs, options = {}) {\n  const {\n    contractType = CONTRACT_C2C,\n    currency: currencyInput = ENGINE_DEFAULTS.currency,\n    currencyRaw,\n    rateUnit = ENGINE_DEFAULTS.rateUnit,\n    clientJobRate = 0,\n    clientJobRateFrom = 0,\n    clientJobRateTo = 0,\n    clientVmsPercent = 0,\n    clientVmsPercentageType = 'recurring',\n    proposedRate: baseProposed = 0,\n    employerRate = 0,\n    employerVmsPercent = 0,\n    employerVmsPercentConfigured = 0,\n    employerVmsAvailable = false,\n    employerVmsType = 'Recurring',\n    employerVmsRequired = false,\n    locationTaxPercent = 0,\n  } = inputs ?? {};\n\n  // Normalise here too, not only in resolveFinanceInputs: computeFinance is\n  // called directly (tests, surfaces that assemble their own inputs), and a\n  // raw \"USD\" reaching a formatter is exactly the bug this guards.\n  const currency = currencySymbol(currencyInput, ENGINE_DEFAULTS.currency);\n\n  const proposedRate = options.proposedRate != null\n    ? num(options.proposedRate)\n    : num(baseProposed);\n  const includeReferral = Boolean(options.includeReferral);\n  const referralRate = includeReferral ? num(options.referralRate) : 0;\n  // A one-time referral payout still belongs to the finance record and must be\n  // displayed/persisted, but it is not a recurring rate cost and therefore\n  // must not reduce the per-cycle margin. `deductReferral` is separate from\n  // `includeReferral` for exactly that reason. Existing callers keep the old\n  // behaviour because the default mirrors includeReferral.\n  const deductReferral = options.deductReferral == null\n    ? includeReferral\n    : Boolean(options.deductReferral);\n  const referralDeduction = deductReferral ? referralRate : 0;\n\n  // Client side (context strip).\n  const clientDiscount = pct(clientJobRate, clientVmsPercent);\n  const netClientRate = round2(clientJobRate - clientDiscount);\n\n  // Proposed side (margin).\n  const discountVms = pct(proposedRate, clientVmsPercent);\n  const netProposedRate = round2(proposedRate - discountVms);\n\n  // Employer side (margin) — contract-type dependent deduction.\n  const isW2 = contractType === CONTRACT_W2;\n  const employerDeductionPercent = isW2 ? locationTaxPercent : employerVmsPercent;\n  const employerDeduction = pct(employerRate, employerDeductionPercent);\n  const netEmployerRate = round2(employerRate - employerDeduction);\n\n  const totalMargin = round2(netProposedRate - netEmployerRate - referralDeduction);\n\n  return {\n    contractType,\n    currency,\n    // What to write back on approve — the stored form, never the symbol we\n    // derived for display.\n    currencyRaw: currencyRaw ?? currency,\n    rateUnit,\n    rateUnitLabel: unitLabel(rateUnit),\n    rateUnitShort: unitShort(rateUnit),\n    isW2,\n    // client context\n    clientJobRate: round2(clientJobRate),\n    clientJobRateFrom: round2(clientJobRateFrom),\n    clientJobRateTo: round2(clientJobRateTo),\n    clientVmsPercent: num(clientVmsPercent),\n    clientVmsPercentageType,\n    clientDiscount,\n    netClientRate,\n    // proposed\n    proposedRate: round2(proposedRate),\n    discountVms,\n    netProposedRate,\n    // employer\n    employerRate: round2(employerRate),\n    employerDeductionPercent: num(employerDeductionPercent),\n    employerDeduction,\n    employerDeductionLabel: isW2 ? 'Location Tax' : 'Employer VMS',\n    employerVmsType,\n    employerVmsRequired: Boolean(employerVmsRequired),\n    employerVmsPercentConfigured: num(employerVmsPercentConfigured),\n    employerVmsAvailable: Boolean(employerVmsAvailable),\n    netEmployerRate,\n    // referral + outcome\n    includereferral: includeReferral,\n    referralRate: round2(referralRate),\n    referralDeduction: round2(referralDeduction),\n    totalMargin,\n    marginPositive: totalMargin >= 0,\n  };\n}\n\n// resolveAndCompute — convenience one-shot used by read-only surfaces (cfo,\n// onboarding detail) that don't edit inline: resolve inputs off the record\n// then compute. Editable surfaces call resolveFinanceInputs once and\n// computeFinance on every keystroke with an override instead.\nexport function resolveAndCompute(record, lookups, options = {}) {\n  return computeFinance(resolveFinanceInputs(record, lookups, options.defaults), options);\n}\n\n// ── Numeric input policy (config-driven, pure) ───────────────────────────────\n// A rate input's rules live in financeApprovalConfig\n// (sections.rateBreakdown.proposed.policy = { decimals, min, max, step }); these\n// helpers turn that declaration into the three checks a text field needs, with\n// no policy value hardcoded — flipping `decimals` to 0 gives an integer-only\n// field, and to 3 a 3-decimal one, with no component change.\nexport const DEFAULT_NUMERIC_POLICY = { decimals: 2, min: 0 };\n\n// countDecimals('62.5') → 1. Exponent forms (\"1e-3\") are treated as\n// out-of-policy rather than expanded: nobody types one into a rate box, and\n// silently accepting it would sneak past the decimal cap.\nexport function countDecimals(value) {\n  const text = String(value ?? '').trim();\n  if (!text || /e/i.test(text)) return text ? Infinity : 0;\n  const dot = text.indexOf('.');\n  return dot === -1 ? 0 : text.length - dot - 1;\n}\n\n// isWithinPolicy — does this COMPLETE value satisfy the policy? Used for the\n// inline error (a paste bypasses every keystroke guard, so the value itself\n// must be checked as well).\nexport function isWithinPolicy(value, policy = {}) {\n  const { decimals = DEFAULT_NUMERIC_POLICY.decimals, min, max } = { ...DEFAULT_NUMERIC_POLICY, ...policy };\n  if (value === null || value === undefined || value === '') return true;\n  const text = String(value).trim();\n  if (!/^-?\\d*(\\.\\d*)?$/.test(text)) return false;\n  if (countDecimals(text) > num(decimals)) return false;\n  const n = Number(text);\n  if (!Number.isFinite(n)) return false;\n  if (min !== undefined && min !== null && n < num(min)) return false;\n  if (max !== undefined && max !== null && n > num(max)) return false;\n  return true;\n}\n\n// Keys that edit or navigate rather than insert a character — never blocked,\n// otherwise the field becomes impossible to correct.\nconst CONTROL_KEYS = new Set([\n  'Backspace', 'Delete', 'Tab', 'Enter', 'Escape', 'Home', 'End',\n  'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageUp', 'PageDown',\n]);\n\n// acceptsKey — would this keystroke leave the field holding a value the policy\n// still permits? Returns false for a non-numeric character, for a second\n// decimal point, for a minus sign when negatives aren't allowed (min >= 0), and\n// — the reason this exists — for the digit that would become a 3rd decimal.\n//\n// `text`/`start`/`end` describe the field BEFORE the key: we splice the key in\n// at the caret (replacing any selection) and test the resulting string, so\n// typing in the middle of an existing number is judged on the real outcome\n// rather than on the key alone.\nexport function acceptsKey(policy = {}, key, text = '', start = null, end = null) {\n  if (CONTROL_KEYS.has(key) || String(key ?? '').length !== 1) return true;\n  const { decimals = DEFAULT_NUMERIC_POLICY.decimals, min } = { ...DEFAULT_NUMERIC_POLICY, ...policy };\n  const current = String(text ?? '');\n  const from = start ?? current.length;\n  const to = end ?? from;\n  const next = current.slice(0, from) + key + current.slice(to);\n  const allowNegative = min === undefined || min === null || num(min) < 0;\n  if (key === '-') return allowNegative && /^-?\\d*(\\.\\d*)?$/.test(next);\n  if (key === '.') return num(decimals) > 0 && /^-?\\d*(\\.\\d*)?$/.test(next);\n  if (!/^\\d$/.test(key)) return false;\n  if (!/^-?\\d*(\\.\\d*)?$/.test(next)) return false;\n  return countDecimals(next) <= num(decimals);\n}\n\n// clampToPolicy — the value actually committed on change: rounded to the\n// allowed number of decimals and pulled inside min/max.\nexport function clampToPolicy(value, policy = {}) {\n  const { decimals = DEFAULT_NUMERIC_POLICY.decimals, min, max } = { ...DEFAULT_NUMERIC_POLICY, ...policy };\n  let n = num(value);\n  const factor = 10 ** num(decimals);\n  n = Math.round((n + Number.EPSILON) * factor) / factor;\n  if (min !== undefined && min !== null) n = Math.max(n, num(min));\n  if (max !== undefined && max !== null) n = Math.min(n, num(max));\n  return n;\n}\n\n// ── Audit-log helper (workforceFinanceApprovals.rateHistory[]) ───────────────\n// buildRateHistoryEntries — turn a computed snapshot into the timestamped\n// {field, value, updatedBy, timestamp} rows persisted on save, so every rate,\n// VMS, tax and referral change is attributable. The backend $push-es these\n// onto workforceFinanceApprovals.rateHistory (see plan phase 4).\nexport function buildRateHistoryEntries(computed, updatedBy, at = new Date()) {\n  const timestamp = at instanceof Date ? at.toISOString() : at;\n  const fields = [\n    ['proposedRate', computed.proposedRate],\n    ['discountVms', computed.discountVms],\n    ['netProposedRate', computed.netProposedRate],\n    ['employerRate', computed.employerRate],\n    [computed.isW2 ? 'locationTax' : 'employerVms', computed.employerDeduction],\n    ['netEmployerRate', computed.netEmployerRate],\n    ['referralRate', computed.referralRate],\n    ['totalMargin', computed.totalMargin],\n  ];\n  return fields.map(([field, value]) => ({\n    field, value, updatedBy, timestamp,\n  }));\n}\n\n// formatMoney — kept as an export so every existing caller keeps working, but\n// it is now a THIN DELEGATE to the package-wide utils/currency formatter. It\n// used to prepend `currency` verbatim (so a stored \"USD\" printed \"USD100\") and\n// skip thousands separators, which is how the finance panel and the detail view\n// ended up disagreeing about the same number. One implementation, one answer.\n// The `?? 0` keeps this surface's long-standing contract that a blank/absent\n// rate reads as \"$0.00\" (the shared util deliberately passes unparseable text\n// through untouched, which is right for a free-text detail field but would\n// leave a hole in a rate column).\nexport function formatMoney(value, currency = ENGINE_DEFAULTS.currency) {\n  const n = toNumber(value);\n  return formatMoneyShared(Number.isNaN(n) ? 0 : n, currency, { decimals: 2 });\n}\n\n// formatRate — an amount with its unit suffix (\"$62.50/hr\"). The unit is\n// whatever the record resolved to; an empty unit yields the bare amount rather\n// than a dangling slash.\nexport function formatRate(value, currency = ENGINE_DEFAULTS.currency, unit) {\n  const short = unitShort(unit, '');\n  return short ? `${formatMoney(value, currency)}/${short}` : formatMoney(value, currency);\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// FinanceApprovalPanel — the single config-driven finance approval surface for\n// all three stages (submissionManager / onboardingManager / cfo) and both\n// contract types (W2 / C2C). Presentational + local edit state only: it\n// resolves & computes rates via financeApprovalEngine, renders exactly what\n// financeApprovalConfig declares, and calls host-provided `actions` — no\n// fetching, no routing, no backend URLs (CORE-THEME stays app-agnostic).\n//\n// Host contract:\n//   type            one of FINANCE_TYPE_*\n//   record          resolved { submission, job, client, employer, engagement }\n//   lookups         { clientVmsFee, locationTaxRows }  (optional, see engine)\n//   identity        { name, role, email, phone, location, ...meta }  display-only\n//   referralOptions [{ value, label, lastRate, type }]  (onboardingManager)\n//   onReferralChange(value) → optionally returns/sets last paid rate\n//   currentUserId   stamped into the rate-history audit rows\n//   actions         { <api-key>: async ({ computed, proposedRate, referral, reason, category }) => {} }\n//   onClose()       popup dismiss (optional)\n//   variant         'popup' | 'page'  (sticky action bar vs inline)\n// ─────────────────────────────────────────────────────────────────────────\nimport { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport dayjs from 'dayjs';\nimport { InputNumber, Select, Input, Checkbox, Tooltip, Modal, message } from 'antd';\nimport {\n  CheckOutlined,\n  ClockCircleOutlined,\n  LockOutlined,\n  WarningOutlined,\n  RiseOutlined,\n  CloseCircleFilled,\n  UserAddOutlined,\n} from '@ant-design/icons';\nimport AppButton from '../AppButton.jsx';\nimport {\n  getFinanceApprovalConfig,\n  marginIncludesReferral,\n  resolveRejectionReason,\n  fillTokens,\n  FINANCE_TYPE_CFO,\n} from './financeApprovalConfig.js';\nimport {\n  resolveFinanceInputs,\n  computeFinance,\n  buildRateHistoryEntries,\n  formatMoney,\n  acceptsKey,\n  clampToPolicy,\n  isWithinPolicy,\n  DEFAULT_NUMERIC_POLICY,\n} from './financeApprovalEngine.js';\nimport { getDefaults } from '../../services/detailDefaults.js';\nimport { fetchUserName } from '../detail/userNames.js';\nimport './finance-approval.css';\n\nconst { TextArea } = Input;\n\nconst firstValue = (...values) => values.find(\n  (v) => v !== undefined && v !== null && v !== '',\n) ?? '-';\n\n// VMS billing cadence label — the Client form stores \"onetime\"/\"recurring\",\n// the submission's employer VMS type stores \"One Time\"/\"Recurring\" (its own\n// select options); normalize both to the one display label either can mean.\nfunction vmsTypeLabel(type) {\n  return String(type ?? '').toLowerCase().replace(/\\s+/g, '') === 'onetime' ? 'One Time' : 'Recurring';\n}\n\nfunction formatSubmittedDate(value) {\n  const raw = value?.$date ?? value;\n  if (!raw) return '-';\n  const parsed = dayjs(raw);\n  return parsed.isValid() ? parsed.format(getDefaults().dateFormat) : '-';\n}\n\n// ── config-driven value resolution ──────────────────────────────────────────\n// The header crumb and the Basic Details grid are declared in\n// financeApprovalConfig as { key, label, source: ['record.job.jobTitle', …] }.\n// These two helpers are all it takes to render them, and they are the reason no\n// field list survives in the JSX below: reordering, adding or dropping a line\n// (e.g. dropping Client + Job ID because the crumb already prints them) is a\n// config edit with no component change.\n\n// getPath({record, identity, …}, 'record.job.jobTitle') → the value or undefined.\nfunction getPath(ctx, path) {\n  return String(path ?? '')\n    .split('.')\n    .reduce((acc, key) => (acc === null || acc === undefined ? undefined : acc[key]), ctx);\n}\n\n// Named value formatters an item can opt into via `format`. Keeping them in a\n// registry (rather than letting config carry a function) means the config stays\n// serialisable — it can come from the admin API later without change here.\nconst VALUE_FORMATTERS = { date: formatSubmittedDate };\n\n// resolveConfigValue — first non-empty source path wins, exactly like the\n// firstValue() chains that used to be inline in the JSX.\nfunction resolveConfigValue(item, ctx) {\n  const paths = Array.isArray(item?.source) ? item.source : [item?.source].filter(Boolean);\n  const raw = paths\n    .map((path) => getPath(ctx, path))\n    .find((v) => v !== undefined && v !== null && v !== '');\n  const formatter = VALUE_FORMATTERS[item?.format];\n  if (formatter) return formatter(raw);\n  return raw === undefined || raw === null || raw === '' ? '-' : raw;\n}\n\n// ── numeric input policy → antd props ───────────────────────────────────────\n// policyInputProps turns a config policy ({ decimals, min, max, step }) into the\n// props that actually enforce it on an antd InputNumber. Three layers, because\n// each one alone has a hole:\n//   • precision/min/max  — antd's own rounding, applied on blur only\n//   • onKeyDown          — refuses the keystroke that would create a 3rd decimal\n//                          or a non-numeric character, so the bad value never\n//                          appears in the first place\n//   • onChange           — clamps (a PASTE bypasses every keystroke guard) and\n//                          raises the inline error\n// No policy number appears here: decimals:0 in config yields an integer-only\n// field, decimals:3 a three-decimal one, with no edit to this file.\nfunction policyInputProps(policy, { onValue, onError }) {\n  return {\n    min: policy.min,\n    max: policy.max,\n    step: policy.step,\n    precision: policy.decimals,\n    // Strip decoration a user may paste (\"$62.50\", \"1,200\") down to a number.\n    parser: (text) => String(text ?? '').replace(/[^\\d.-]/g, ''),\n    onKeyDown: (event) => {\n      // Never interfere with clipboard/select-all/undo shortcuts — they arrive\n      // as ordinary single-character keys ('v', 'a') and would otherwise be\n      // rejected as \"not a digit\".\n      if (event.ctrlKey || event.metaKey || event.altKey) return;\n      const target = event.target ?? {};\n      if (!acceptsKey(policy, event.key, target.value ?? '', target.selectionStart, target.selectionEnd)) {\n        event.preventDefault();\n        onError(true);\n      }\n    },\n    onChange: (value) => {\n      onError(!isWithinPolicy(value, policy));\n      onValue(clampToPolicy(value ?? 0, policy));\n    },\n  };\n}\n\n// ── small presentational atoms ───────────────────────────────────────────────\n\nfunction InfoItem({ label, value }) {\n  return (\n    <div className=\"fa-info-item\">\n      <div className=\"fa-info-k\">{label}</div>\n      <div className=\"fa-info-v\">{String(value ?? '-')}</div>\n    </div>\n  );\n}\nInfoItem.propTypes = { label: PropTypes.string, value: PropTypes.node };\n\nfunction RateRow({ label, sub, value, deduction, children, total }) {\n  return (\n    <div className={`fa-rate-row${total ? ' fa-rate-total' : ''}`}>\n      <div className=\"fa-rate-label\">\n        {label}\n        {sub ? <span className=\"fa-rate-sub\">{sub}</span> : null}\n      </div>\n      {children ?? (\n        <div className={`fa-rate-val fa-num${deduction ? ' fa-deduction' : ''}`}>{value}</div>\n      )}\n    </div>\n  );\n}\nRateRow.propTypes = {\n  label: PropTypes.node,\n  sub: PropTypes.node,\n  value: PropTypes.node,\n  deduction: PropTypes.bool,\n  children: PropTypes.node,\n  total: PropTypes.bool,\n};\n\nfunction Stat({ label, value, hero, tone }) {\n  return (\n    <div className={`fa-stat${hero ? ' fa-stat-hero' : ''}${tone ? ` fa-stat-${tone}` : ''}`}>\n      <div className=\"fa-stat-k\">{label}</div>\n      <div className=\"fa-stat-v fa-num\">{value}</div>\n    </div>\n  );\n}\nStat.propTypes = {\n  label: PropTypes.string, value: PropTypes.node, hero: PropTypes.bool, tone: PropTypes.string,\n};\n\n// ── main component ───────────────────────────────────────────────────────────\n\nexport default function FinanceApprovalPanel({\n  type,\n  record,\n  lookups,\n  identity,\n  referralOptions,\n  onReferralChange,\n  onAddReferral,\n  onValuesChange,\n  currentUserId,\n  actions,\n  onClose,\n  variant,\n}) {\n  const config = getFinanceApprovalConfig(type);\n  // The tail of the engine's currency/rate-unit resolution chains comes from\n  // config, so \"what do we show when the record says nothing\" is admin policy.\n  const engineDefaults = useMemo(\n    () => ({ rateUnit: config.rateUnit, currency: config.currency }),\n    [config],\n  );\n  const inputs = useMemo(\n    () => resolveFinanceInputs(record, lookups, engineDefaults),\n    [record, lookups, engineDefaults],\n  );\n  const showsReferral = marginIncludesReferral(config);\n\n  // ── local edit state ──\n  const [proposedRate, setProposedRate] = useState(inputs.proposedRate);\n  const [referralId, setReferralId] = useState(\n    record?.engagement?.financeApproval?.referralId\n    ?? record?.referral?._id ?? null,\n  );\n  const [referralRate, setReferralRate] = useState(\n    record?.engagement?.financeApproval?.referralRate\n    ?? record?.referral?.referalRate ?? 0,\n  );\n  const [historicalReferralRate, setHistoricalReferralRate] = useState(\n    record?.referral?.isNewReferral\n      ? 0\n      : record?.referral?.referalRate\n        ?? record?.referral?.referralRate\n        ?? record?.engagement?.financeApproval?.referralRate\n        ?? 0,\n  );\n  const [referralType, setReferralType] = useState(\n    record?.engagement?.financeApproval?.referralType\n    ?? record?.referral?.referralType\n    ?? record?.referral?.referalType\n    ?? 'Recurring',\n  );\n  const [proposedRateError, setProposedRateError] = useState(false);\n  const [referralRateError, setReferralRateError] = useState(false);\n  const [reason, setReason] = useState('');\n  const [reasonError, setReasonError] = useState(false);\n  const [category, setCategory] = useState('');\n  const [categoryError, setCategoryError] = useState(false);\n  const [busy, setBusy] = useState('');\n  // Preview-first UX (MSI / onboarding review): when the stage config sets\n  // rateBreakdown.editToggle, Proposed + Referral render as a locked preview\n  // until the approver deliberately clicks Edit. Stages that don't set the\n  // flag are unaffected — showRateInputs is always true for them.\n  const editToggleCfg = Boolean(config.sections.rateBreakdown?.editToggle);\n  const [ratesEditing, setRatesEditing] = useState(false);\n  const showRateInputs = !editToggleCfg || ratesEditing;\n  // Open state for the \"approve above the client rate?\" confirm. See runAction\n  // for why the *outcome* of that confirm is not stored.\n  const [overClientConfirmOpen, setOverClientConfirmOpen] = useState(false);\n  const [referralSelectOpen, setReferralSelectOpen] = useState(false);\n  const [historyModal, setHistoryModal] = useState({ open: false, title: '', rows: [] });\n  const [historyActorNames, setHistoryActorNames] = useState({});\n\n  const referralCfg = config.sections.referral ?? {};\n  // Was a referral actually enabled upstream (the onboarding manager's\n  // checkbox)? Persisted on the engagement; falls back to \"a rate/ref exists\".\n  const referralEnabledInitial = record?.engagement?.financeApproval?.referralEnabled\n    ?? record?.referralEnabled\n    ?? (Number(referralRate) > 0 || Boolean(referralId));\n  const [referralEnabled, setReferralEnabled] = useState(Boolean(referralEnabledInitial));\n\n  const hasReferralToggle = referralCfg.toggle === true;\n  // Read-only/list finance views should not show a referral name when its\n  // effective rate is zero. The onboarding edit screen still uses its own\n  // referralEnabled toggle and can keep a selected company while entering a rate.\n  const referralExists = Number(referralRate) > 0;\n  // show:true      → always (or gated by its own checkbox when toggle:true)\n  // show:'ifEnabled'/'ifExists' → only when enabled upstream (cfo)\n  const referralVisible = referralCfg.show === true\n    ? (hasReferralToggle ? referralEnabled : true)\n    : referralCfg.show === 'ifEnabled'\n      ? referralEnabled\n      : referralCfg.show === 'ifExists'\n        ? referralExists\n      : false;\n\n  // One-time referral payouts are informational on these rate-based finance\n  // views: show and persist the amount, but do NOT subtract it from the\n  // recurring/per-cycle margin. Accept the common stored spellings so older\n  // records (\"One-time\", \"One time payout\", \"ONETIME\") behave alike.\n  const normalizedReferralType = String(referralType ?? '')\n    .trim()\n    .toLowerCase()\n    .replace(/[\\s_-]+/g, '');\n  const oneTimeReferral = normalizedReferralType.startsWith('onetime');\n  const referralIncluded = showsReferral && referralVisible;\n  const referralInMargin = referralIncluded && !oneTimeReferral;\n  const rejectionReason = config.rejection?.show ? resolveRejectionReason(config, record) : '';\n\n  // ── live computation ──\n  const computed = useMemo(() => computeFinance(inputs, {\n    proposedRate: config.sections.rateBreakdown?.proposed?.editable ? proposedRate : undefined,\n    includeReferral: referralIncluded,\n    deductReferral: referralInMargin,\n    referralRate,\n  }), [inputs, proposedRate, referralRate, referralIncluded, referralInMargin, config]);\n  const cur = computed.currency;\n  const isReadOnly = config.readOnly;\n  const hasProposedRate = Number(computed.proposedRate) > 0;\n\n  // Margin health tone: negative → red (fa-bad); positive but below the\n  // configured minimum profit % (default 20%) → orange (fa-warn); at/above the\n  // threshold → green (fa-good). Percentage is the margin over the net proposed\n  // (client-facing revenue) rate. Threshold is admin-tunable via config.margin.\n  const minMarginPercent = Number(config.margin?.minMarginPercent ?? 20);\n  const marginPercent = Number(computed.netProposedRate) > 0\n    ? (Number(computed.totalMargin) / Number(computed.netProposedRate)) * 100\n    : 0;\n  const marginTone = !computed.marginPositive\n    ? 'fa-bad'\n    : marginPercent < minMarginPercent\n      ? 'fa-warn'\n      : 'fa-good';\n\n  // Employer-side panel label is contract-type aware: a W2 hire's left-hand rate\n  // is the CANDIDATE's pay rate; a C2C hire's is the vendor/EMPLOYER rate.\n  const employerSideLabel = computed.isW2 ? 'Candidate' : 'Employer';\n\n  // Every rate on this surface is quoted in the record's OWN unit (resolved by\n  // the engine: submission → candidate budget → job → config default). Empty\n  // when nothing resolves, so an unknown unit prints \"$100\" and never \"$100/\".\n  const unitSuffix = computed.rateUnitShort ? `/${computed.rateUnitShort}` : '';\n\n  // Config-resolution context for header.crumbFields / sections.jobClient.items.\n  const valueContext = { record, identity, inputs, computed };\n  const crumbText = (config.header?.crumbFields ?? [])\n    .map((field) => resolveConfigValue(field, valueContext))\n    .filter((value) => value !== '-' && value !== '' && value !== undefined && value !== null)\n    .join(config.header?.crumbSeparator ?? ' · ');\n\n  // Numeric policies for the two money inputs. The referral input deliberately\n  // falls back to the proposed rate's policy so one config entry can govern both.\n  const proposedPolicy = config.sections.rateBreakdown?.proposed?.policy ?? DEFAULT_NUMERIC_POLICY;\n  const referralPolicy = config.sections.referral?.policy ?? proposedPolicy;\n\n  const proposedRateHistory = useMemo(() => {\n    const separateHistory = record?.submission?.proposedRateHistory;\n    const legacySource = record?.submission?.proposedRate;\n    const source = Array.isArray(separateHistory) && separateHistory.length\n      ? separateHistory\n      : legacySource;\n    const rows = Array.isArray(source) ? source : (source && typeof source === 'object' ? [source] : []);\n    return rows\n      .map((entry, index) => ({\n        key: entry?._id?.$oid ?? entry?._id ?? `proposed-${index}`,\n        rate: Number(entry?.candidateProposedRate ?? entry?.proposedRate ?? entry?.rate),\n        currency: entry?.candidateProposedRateCurrencySymbol ?? entry?.currencySymbol ?? cur,\n        unit: entry?.candidateProposedRateUnit ?? entry?.rateUnit ?? computed.rateUnitShort ?? '',\n        at: entry?.updatedAt ?? entry?.timestamp ?? entry?.createdAt ?? entry?.candidateProposedRateUpdateDT,\n        by: entry?.updatedByName ?? entry?.updatedBy ?? entry?.createdByName ?? entry?.createdBy,\n      }))\n      .filter((entry) => Number.isFinite(entry.rate))\n      .sort((left, right) => {\n        const leftTime = new Date(left.at ?? 0).getTime();\n        const rightTime = new Date(right.at ?? 0).getTime();\n        return (Number.isNaN(rightTime) ? 0 : rightTime) - (Number.isNaN(leftTime) ? 0 : leftTime);\n      });\n  }, [record?.submission?.proposedRateHistory, record?.submission?.proposedRate, cur, computed.rateUnitShort]);\n\n  const referralRateHistory = useMemo(() => {\n    // Referral history is intentionally independent from referralDetails.\n    // New updates persist only actual referral changes in referralRateHistory.\n    // For legacy records, collapse repeated referralDetails snapshots so a\n    // Proposed Rate-only update cannot appear as a duplicate Referral Rate row.\n    const dedicated = record?.submission?.referralRateHistory;\n    const legacy = record?.submission?.referralDetails ?? record?.submission?.referalDetails;\n    const rawRows = Array.isArray(dedicated) && dedicated.length\n      ? dedicated\n      : (Array.isArray(legacy) ? legacy : (legacy && typeof legacy === 'object' ? [legacy] : []));\n    const rows = rawRows.reduce((result, entry) => {\n      const normalized = {\n        key: entry?._id?.$oid ?? entry?._id ?? `referral-${result.length}`,\n        rate: Number(entry?.referralRate ?? entry?.referalRate ?? entry?.rate),\n        referralId: String(entry?.referralId?.$oid ?? entry?.referralId ?? entry?.referalId?.$oid ?? entry?.referalId ?? ''),\n        referralType: String(entry?.referralType ?? entry?.referalType ?? ''),\n        currency: entry?.referralCurrencySymbol ?? entry?.currencySymbol ?? cur,\n        unit: entry?.referralUnit ?? entry?.referalUnit ?? computed.rateUnitShort ?? '',\n        at: entry?.updatedAt ?? entry?.timestamp ?? entry?.createdAt,\n        by: entry?.updatedByName ?? entry?.updatedBy ?? entry?.createdByName ?? entry?.createdBy,\n      };\n      if (!Number.isFinite(normalized.rate)) return result;\n      const previous = result.at(-1);\n      if (previous\n        && previous.rate === normalized.rate\n        && previous.referralId === normalized.referralId\n        && previous.referralType === normalized.referralType) {\n        return result;\n      }\n      result.push(normalized);\n      return result;\n    }, []);\n    return rows.sort((left, right) => {\n      const leftTime = new Date(left.at ?? 0).getTime();\n      const rightTime = new Date(right.at ?? 0).getTime();\n      return (Number.isNaN(rightTime) ? 0 : rightTime) - (Number.isNaN(leftTime) ? 0 : leftTime);\n    });\n  }, [record?.submission?.referralRateHistory, record?.submission?.referralDetails, record?.submission?.referalDetails, cur, computed.rateUnitShort]);\n\n  useEffect(() => {\n    const actorIds = [...proposedRateHistory, ...referralRateHistory]\n      .map((entry) => entry?.by)\n      .filter((value) => value !== undefined && value !== null && value !== '')\n      .map((value) => String(value).trim())\n      // Names already persisted by newer updates should be rendered directly.\n      // Resolve only values that look like stored auth / Mongo user ids.\n      .filter((value) => /^\\d+$/.test(value) || /^[a-f0-9]{24}$/i.test(value))\n      .filter((value, index, values) => values.indexOf(value) === index)\n      .filter((value) => !historyActorNames[value]);\n\n    if (!actorIds.length) return;\n    let cancelled = false;\n    Promise.all(actorIds.map(async (actorId) => [actorId, await fetchUserName(actorId)]))\n      .then((pairs) => {\n        if (cancelled) return;\n        const resolved = Object.fromEntries(pairs.filter(([, name]) => String(name ?? '').trim()));\n        if (Object.keys(resolved).length) {\n          setHistoryActorNames((current) => ({ ...current, ...resolved }));\n        }\n      })\n      .catch(() => null);\n\n    return () => { cancelled = true; };\n  }, [proposedRateHistory, referralRateHistory, historyActorNames]);\n\n  const openRateHistory = (title, rows) => {\n    setHistoryModal({ open: true, title, rows });\n  };\n\n  useEffect(() => {\n    onValuesChange?.({\n      proposedRate: Number(proposedRate) || 0,\n      referralId: referralId == null ? '' : String(referralId?.$oid ?? referralId),\n      referralRate: Number(referralRate) || 0,\n      referralType: String(referralType ?? ''),\n      referralEnabled: Boolean(referralEnabled),\n    });\n  }, [onValuesChange, proposedRate, referralId, referralRate, referralType, referralEnabled]);\n\n  // Employer VMS wording — three distinct states, all labelled from config:\n  // it applies (deduction row), the employer HAS a VMS % but this submission\n  // didn't require it, or the employer has no VMS % configured at all.\n  const vmsLabels = config.labels?.employerVms ?? {};\n  const employerVmsApplies = computed.employerVmsRequired && computed.employerVmsAvailable;\n\n  // ── proposed rate vs the Client Job Rate ──\n  // Being ABOVE the client's posted rate is a commercial judgement, not an\n  // error: the approver may knowingly ask for more. So it produces a WARNING\n  // (with the full comparison, and a deliberate confirm step) rather than a\n  // dead button. `overClientPolicy` can restore the old hard block, or silence\n  // it entirely, without touching this file.\n  const proposedEditable = Boolean(config.sections.rateBreakdown?.proposed?.editable);\n  const clientJobRate = Number(computed.clientJobRate) || 0;\n  const proposedOverClient = proposedEditable && clientJobRate > 0 && Number(proposedRate) > clientJobRate;\n\n  const overClientCfg = config.sections.rateBreakdown?.proposed?.overClient ?? {};\n  const overClientPolicy = config.sections.rateBreakdown?.proposed?.overClientPolicy ?? 'warn';\n  const overClientBlocks = proposedOverClient && overClientPolicy === 'block';\n  const overClientWarns = proposedOverClient && overClientPolicy === 'warn';\n\n  // The numbers behind the warning, resolved once so the panel, the confirm\n  // dialog and the tooltip all quote exactly the same figures.\n  const overClientDelta = proposedOverClient ? Number(proposedRate) - clientJobRate : 0;\n  const overClientPct = clientJobRate > 0 ? (overClientDelta / clientJobRate) * 100 : 0;\n  const overClientTokens = {\n    proposed: `${formatMoney(Number(proposedRate), cur)}${unitSuffix}`,\n    client: `${formatMoney(clientJobRate, cur)}${unitSuffix}`,\n    delta: `${formatMoney(overClientDelta, cur)}${unitSuffix}`,\n    pct: `${overClientPct.toFixed(overClientPct < 10 ? 1 : 0)}%`,\n    unit: computed.rateUnitShort ?? '',\n  };\n  const overClientText = (key) => fillTokens(overClientCfg[key], overClientTokens);\n\n  // ── primary-action gate ──\n  // Stages whose primary action declares `requireProposedRate` (Approve /\n  // Send For Approval) cannot run until a real proposed rate is entered — it\n  // is what the margin, the CFO request and payroll are all derived from.\n  // `primaryBlockedReason` doubles as the disabled-button hover explanation:\n  // a disabled button with no stated cause is the thing users get stuck on.\n  const primaryAction = config.actions?.primary;\n  const proposedRateMissing = Boolean(primaryAction?.requireProposedRate)\n    && !(Number(computed.proposedRate) > 0);\n  const primaryBlockedReason = proposedRateMissing\n    ? 'Enter the Proposed Rate first — it drives the margin and the rate sent for approval.'\n    : overClientBlocks\n      ? overClientText('blockMessage')\n      : '';\n\n  const handleReferralPick = (value) => {\n    setReferralId(value);\n    setReferralSelectOpen(false);\n    const picked = (referralOptions ?? []).find((o) => o.value === value);\n    if (!picked?.isNewReferral && picked?.lastRate != null && picked.lastRate !== '') {\n      const pickedLastRate = Number(picked.lastRate) || 0;\n      setReferralRate(pickedLastRate);\n      setHistoricalReferralRate(pickedLastRate);\n    } else {\n      setHistoricalReferralRate(0);\n    }\n    if (picked?.type) setReferralType(picked.type);\n    onReferralChange?.(value, picked);\n  };\n\n  const handleReferralEnabledChange = (event) => {\n    const checked = event.target.checked;\n    setReferralEnabled(checked);\n    setReferralSelectOpen(checked);\n  };\n\n  const referralDropdownRender = (menu) => (\n    <div>\n      {menu}\n      {onAddReferral && (\n        <div className=\"fa-referral-dropdown-footer\">\n          <AppButton\n            className=\"fa-referral-add-btn\"\n            icon={<UserAddOutlined />}\n            onMouseDown={(event) => event.preventDefault()}\n            onClick={() => {\n              setReferralSelectOpen(false);\n              onAddReferral();\n            }}\n          >\n            Add\n          </AppButton>\n        </div>\n      )}\n    </div>\n  );\n\n  // `skipOverClientConfirm` is passed only by the confirm dialog's own OK\n  // handler. Deliberately NOT a piece of state: a \"user already confirmed\"\n  // flag would survive a subsequent edit of the proposed rate, so a second,\n  // higher rate could be approved on the strength of confirming the first.\n  const runAction = async (actionCfg, { skipOverClientConfirm = false } = {}) => {\n    if (!actionCfg) return;\n    // Only genuine blockers stop the action here — today that is a missing\n    // proposed rate (and an over-client rate ONLY when config says 'block').\n    // Re-checked outside the button's disabled attribute so a programmatic or\n    // keyboard-triggered call can't slip past it.\n    if (actionCfg === config.actions.primary && primaryBlockedReason) {\n      message.error(primaryBlockedReason);\n      return;\n    }\n    // Over the client rate under the default 'warn' policy: approval is\n    // allowed, but it must be deliberate. The confirm restates the exact\n    // comparison so nobody approves a premium rate by muscle memory.\n    if (actionCfg === config.actions.primary && overClientWarns && !skipOverClientConfirm) {\n      setOverClientConfirmOpen(true);\n      return;\n    }\n    if (actionCfg.requireReason && !reason.trim()) {\n      setReasonError(true);\n      return;\n    }\n    if (actionCfg.requireCategory && !category) {\n      setCategoryError(true);\n      return;\n    }\n    const handler = actions?.[actionCfg.api];\n    if (!handler) {\n      message.error(`No handler wired for \"${actionCfg.api}\"`);\n      return;\n    }\n    setBusy(actionCfg.key);\n    try {\n      await handler({\n        computed,\n        proposedRate: computed.proposedRate,\n        referral: referralVisible\n          ? {\n            referralId, referralRate: computed.referralRate, referralType, referralEnabled: true,\n          }\n          : { referralEnabled: false, referralRate: 0 },\n        referralEnabled,\n        reason: reason.trim(),\n        category,\n        rateHistory: config.persist?.rateHistory\n          ? buildRateHistoryEntries(computed, currentUserId)\n          : undefined,\n      });\n    } catch (error) {\n      message.error(error?.message ?? 'Action failed');\n    } finally {\n      setBusy('');\n    }\n  };\n\n  const primary = config.actions.primary;\n  const reject = config.actions.reject;\n\n  return (\n    <div className={`fa-panel fa-variant-${variant}`}>\n      {/* Header */}\n      {config.header?.show !== false && (\n        <div className=\"fa-topbar\">\n          <div>\n            <div className=\"fa-crumb\">{crumbText}</div>\n            <div className=\"fa-title-row\">\n              <h2 className=\"fa-title\">{config.title} — {firstValue(identity?.name, record?.submission?.candidateFullName)}</h2>\n              <span className=\"fa-status-pill\">\n                <ClockCircleOutlined /> {config.statusLabel}\n              </span>\n            </div>\n          </div>\n        </div>\n      )}\n\n      {/* CFO rejection banner (re-approval stages) */}\n      {config.rejection?.show && (\n        <div className=\"fa-rejection\">\n          <CloseCircleFilled className=\"fa-rejection-icon\" />\n          <div className=\"fa-rejection-body\">\n            <div className=\"fa-rejection-title\">{config.rejection.title}</div>\n            <div className={`fa-rejection-reason${rejectionReason ? '' : ' fa-rejection-empty'}`}>\n              {rejectionReason || 'No reason was provided.'}\n            </div>\n          </div>\n        </div>\n      )}\n\n      {/* Approval trail */}\n      {config.trail?.show && (\n        <div className=\"fa-trail\">\n          {config.trail.steps.map((step, i) => (\n            <span key={step.key} className=\"fa-trail-part\">\n              <span className={`fa-trail-step${step.key === config.trail.current ? ' fa-current' : ''}`}>\n                {step.key === config.trail.current ? <ClockCircleOutlined /> : <CheckOutlined />}\n                {step.label}\n              </span>\n              {i < config.trail.steps.length - 1 && <span className=\"fa-trail-sep\">→</span>}\n            </span>\n          ))}\n        </div>\n      )}\n\n      {/* Job & Client details */}\n      {config.sections.jobClient?.show && (\n        <section className=\"fa-card\">\n          <div className=\"fa-card-head\"><h3>{config.sections.jobClient.title}</h3></div>\n          <div className=\"fa-card-body\">\n            {/* Entirely config-driven (sections.jobClient.items). Client and\n                Job ID are intentionally NOT in the default item list — the\n                header crumb already prints both, and having them here too was\n                the duplication QA reported. */}\n            <div className=\"fa-info-grid\">\n              {(config.sections.jobClient.items ?? []).map((item) => (\n                <InfoItem key={item.key} label={item.label} value={resolveConfigValue(item, valueContext)} />\n              ))}\n            </div>\n          </div>\n        </section>\n      )}\n\n      {/* Client Job Rate (context strip) */}\n      {config.sections.clientJobRate?.show && (\n        <section className=\"fa-card\">\n          <div className=\"fa-card-head\"><h3>Client Job Rate</h3></div>\n          <div className=\"fa-card-body\">\n            <div className=\"fa-strip\">\n              <div className=\"fa-strip-item\">\n                <span className=\"fa-strip-k\">Client Job Rate</span>\n                <span className=\"fa-strip-v fa-num\">{formatMoney(computed.clientJobRate, cur)}{unitSuffix}</span>\n              </div>\n              <span className=\"fa-strip-op fa-num\">\n                − {computed.clientVmsPercent}% VMS\n                <span className=\"fa-type-chip fa-vms-chip\">{vmsTypeLabel(computed.clientVmsPercentageType)}</span>\n              </span>\n              <span className=\"fa-strip-eq\">=</span>\n              <div className=\"fa-strip-item\">\n                <span className=\"fa-strip-k\">Net Client Rate</span>\n                <span className=\"fa-strip-v fa-num\" style={{ color: 'var(--color-brand, #0053a5)' }}>\n                  {formatMoney(computed.netClientRate, cur)}{unitSuffix}\n                </span>\n              </div>\n              {config.sections.clientJobRate.note && (\n                <div className=\"fa-strip-note\">\n                  For context only — the client-side rate doesn&apos;t feed into the {config.margin.label} below.\n                </div>\n              )}\n            </div>\n          </div>\n        </section>\n      )}\n\n      {/* Rate Breakdown */}\n      {config.sections.rateBreakdown?.show && (\n        <section className=\"fa-card\">\n          <div className=\"fa-card-head\">\n            <h3>Rate Breakdown</h3>\n            {config.sections.rateBreakdown.finalBadge && (\n              <span className=\"fa-final-badge\"><LockOutlined /> Final</span>\n            )}\n            {editToggleCfg && !isReadOnly && !ratesEditing && (\n              <AppButton\n                className=\"fa-rate-edit-btn\"\n                size=\"small\"\n                onClick={() => setRatesEditing(true)}\n              >\n                Edit\n              </AppButton>\n            )}\n          </div>\n          <div className=\"fa-card-body\">\n            <div className=\"fa-rate-grid\">\n              {/* Employer side */}\n              <div className=\"fa-rate-panel fa-employer\">\n                <div className=\"fa-panel-head\"><span className=\"fa-dot\" />{employerSideLabel} Rate</div>\n                <div className=\"fa-rate-rows\">\n                  <RateRow label={`${employerSideLabel} Rate`} sub=\"as submitted by recruiter\"\n                    value={<>{formatMoney(computed.employerRate, cur)} <span className=\"fa-unit\">{unitSuffix}</span></>} />\n                  {computed.isW2 && (\n                    <RateRow label=\"Employer Location\" sub=\"used to determine location tax\">\n                      <div className=\"fa-rate-val\">{firstValue(identity?.employerLocation, record?.submission?.city, record?.job?.jobLocation)}</div>\n                    </RateRow>\n                  )}\n                  {!computed.isW2 && !employerVmsApplies ? (\n                    // C2C with no employer-side VMS deduction — but WHY there is\n                    // none matters to the approver, and a single \"Not required\"\n                    // hid the difference: an employer that HAS a VMS % where the\n                    // recruiter unchecked \"VMS Required\" is a decision, while an\n                    // employer with no VMS % configured at all is missing data.\n                    // Both labels come from config.labels.employerVms.\n                    <RateRow\n                      label={<span className=\"fa-locked-label\">{vmsLabels.required}</span>}\n                      sub={computed.employerVmsAvailable ? vmsLabels.notRequiredSub : vmsLabels.unavailableSub}\n                      value={(\n                        <span className=\"fa-vms-none\">\n                          {computed.employerVmsAvailable ? vmsLabels.notRequired : vmsLabels.unavailable}\n                        </span>\n                      )}\n                    />\n                  ) : (\n                    <RateRow\n                      label={!computed.isW2 ? (\n                        <span className=\"fa-locked-label\">\n                          {computed.employerDeductionLabel}\n                          <span className=\"fa-type-chip fa-vms-chip\">{vmsTypeLabel(computed.employerVmsType)}</span>\n                        </span>\n                      ) : computed.employerDeductionLabel}\n                      sub={`${computed.employerDeductionPercent}% of employer rate`}\n                      value={`−${formatMoney(computed.employerDeduction, cur).replace('−', '')}`}\n                      deduction\n                    />\n                  )}\n                  <RateRow total label={`Net ${employerSideLabel} Rate`}\n                    value={<span style={{ color: 'var(--color-purple, #7c3aed)' }}>{formatMoney(computed.netEmployerRate, cur)}</span>} />\n                </div>\n              </div>\n\n              {/* Proposed side */}\n              <div className=\"fa-rate-panel fa-client\">\n                <div className=\"fa-panel-head\"><span className=\"fa-dot\" />Proposed Rate</div>\n                <div className=\"fa-rate-rows\">\n                  {config.sections.rateBreakdown.proposed.editable && showRateInputs ? (\n                    <div className=\"fa-rate-row fa-editable\">\n                      <div className=\"fa-editable-head\">\n                        <span className=\"fa-editable-label\">\n                          Proposed Rate\n                          <span className=\"fa-edit-badge\">Editable</span>\n                          {config.persist?.proposedRateHistory && (\n                            <button\n                              type=\"button\"\n                              className=\"fa-history-btn\"\n                              aria-label=\"View proposed rate history\"\n                              title=\"View proposed rate history\"\n                              onClick={() => openRateHistory('Proposed Rate History', proposedRateHistory)}\n                            >\n                              <ClockCircleOutlined />\n                            </button>\n                          )}\n                        </span>\n                        <InputNumber\n                          className=\"fa-rate-input\"\n                          {...policyInputProps(proposedPolicy, {\n                            onValue: setProposedRate,\n                            onError: setProposedRateError,\n                          })}\n                          value={proposedRate}\n                          prefix={cur}\n                          controls={false}\n                          // An over-client rate is no longer an error state —\n                          // under the default 'warn' policy the input is\n                          // flagged amber, not red, because the value is\n                          // acceptable and only wants a second look.\n                          status={proposedRateError || overClientBlocks\n                            ? 'error'\n                            : overClientWarns ? 'warning' : ''}\n                        />\n                      </div>\n                      <div className=\"fa-editable-sub\">rate we ask the client for</div>\n                      {proposedRateError && (\n                        <div className=\"fa-reason-error\">! {proposedPolicy.message}</div>\n                      )}\n                      {proposedRateMissing && (\n                        <div className=\"fa-reason-error\">\n                          ! Enter the proposed rate to enable {primaryAction?.label ?? 'approval'}.\n                        </div>\n                      )}\n                      {overClientBlocks && (\n                        <div className=\"fa-reason-error\">! {overClientText('blockMessage')}</div>\n                      )}\n                      {/* Re-approval only: the rate that was on the record when the\n                          CFO rejected it (inputs.proposedRate is captured once at\n                          mount, before any edit here) — a quiet reminder of what\n                          didn't work while the manager picks a new number. */}\n                      {config.rejection?.show && (\n                        <div className=\"fa-last-rejected\">\n                          Last rejected at <b>{formatMoney(inputs.proposedRate, cur)}{unitSuffix}</b>\n                        </div>\n                      )}\n                    </div>\n                  ) : (\n                    <RateRow\n                      label={(\n                        <span className=\"fa-locked-label\">\n                          Proposed Rate\n                          {config.sections.rateBreakdown.proposed.editable && config.persist?.proposedRateHistory && (\n                            <button\n                              type=\"button\"\n                              className=\"fa-history-btn\"\n                              aria-label=\"View proposed rate history\"\n                              title=\"View proposed rate history\"\n                              onClick={() => openRateHistory('Proposed Rate History', proposedRateHistory)}\n                            >\n                              <ClockCircleOutlined />\n                            </button>\n                          )}\n                          {config.sections.rateBreakdown.proposed.locked && (\n                            <span className=\"fa-locked-badge\"><LockOutlined /> Locked</span>\n                          )}\n                        </span>\n                      )}\n                      sub=\"approved at finance review\"\n                      value={<>{formatMoney(computed.proposedRate, cur)} <span className=\"fa-unit\">{unitSuffix}</span></>}\n                    />\n                  )}\n                  <RateRow\n                    label={(\n                      <span className=\"fa-locked-label\">\n                        Discount (VMS)\n                        <span className=\"fa-type-chip fa-vms-chip\">{vmsTypeLabel(computed.clientVmsPercentageType)}</span>\n                      </span>\n                    )}\n                    sub={`${computed.clientVmsPercent}% of proposed rate`}\n                    value={`−${formatMoney(computed.discountVms, cur).replace('−', '')}`} deduction />\n                  <RateRow total label=\"Net Proposed Rate\"\n                    value={<span style={{ color: 'var(--color-brand, #0053a5)' }}>{formatMoney(computed.netProposedRate, cur)}</span>} />\n                </div>\n              </div>\n            </div>\n\n            {/* \"Add Referral\" gate — onboarding manager decides whether a\n                referral applies; downstream (CFO) only sees it if enabled. */}\n            {hasReferralToggle && !isReadOnly && showRateInputs && (\n              <div className=\"fa-referral-toggle\">\n                <Checkbox\n                  checked={referralEnabled}\n                  onChange={handleReferralEnabledChange}\n                >\n                  <span className=\"fa-rt-title\">{referralCfg.toggleLabel ?? 'Add Referral'}</span>\n                </Checkbox>\n                <div className=\"fa-rt-hint\">{referralCfg.toggleHint}</div>\n              </div>\n            )}\n          </div>\n        </section>\n      )}\n\n      {/* Referral */}\n      {referralVisible && (\n        <section className=\"fa-card fa-referral-card\">\n          <div className=\"fa-card-head\">\n            <h3><span className=\"fa-dot fa-dot-warning\" />Referral</h3>\n            {referralCfg.mode === 'print' && referralCfg.typeChip && (\n              <span className=\"fa-type-chip\">{referralType}</span>\n            )}\n          </div>\n          <div className=\"fa-card-body\">\n            {referralCfg.mode === 'select' && showRateInputs ? (\n              <div className=\"fa-referral-fields\">\n                <div className=\"fa-referral-field\">\n                  <label className=\"fa-rf-k\" htmlFor=\"fa-referral-company\">Referral Company</label>\n                  <Select\n                    id=\"fa-referral-company\"\n                    className=\"fa-referral-select\"\n                    placeholder=\"Select a referral\"\n                    open={referralSelectOpen}\n                    value={referralId ?? undefined}\n                    onChange={handleReferralPick}\n                    options={referralOptions ?? []}\n                    showSearch\n                    optionFilterProp=\"label\"\n                    onDropdownVisibleChange={setReferralSelectOpen}\n                    onOpenChange={setReferralSelectOpen}\n                    popupRender={referralDropdownRender}\n                    dropdownRender={referralDropdownRender}\n                  />\n                </div>\n                <div className=\"fa-referral-field\">\n                  <label className=\"fa-rf-k\" htmlFor=\"fa-referral-rate\">\n                    Referral Rate\n                    {referralCfg.rateEditable && config.persist?.rateHistory && (\n                      <button\n                        type=\"button\"\n                        className=\"fa-history-btn\"\n                        aria-label=\"View referral rate history\"\n                        title=\"View referral rate history\"\n                        onClick={() => openRateHistory('Referral Rate History', referralRateHistory)}\n                      >\n                        <ClockCircleOutlined />\n                      </button>\n                    )}\n                  </label>\n                  <InputNumber\n                    id=\"fa-referral-rate\"\n                    className=\"fa-referral-rate-input\"\n                    {...policyInputProps(referralPolicy, {\n                      onValue: setReferralRate,\n                      onError: setReferralRateError,\n                    })}\n                    value={referralRate}\n                    prefix={cur}\n                    controls={false}\n                    disabled={!referralId}\n                    status={referralRateError ? 'error' : ''}\n                  />\n                  {referralRateError && (\n                    <div className=\"fa-reason-error\">! {referralPolicy.message}</div>\n                  )}\n                </div>\n                <div className=\"fa-referral-field\">\n                  <label className=\"fa-rf-k\" htmlFor=\"fa-referral-type\">Referral Type</label>\n                  <Select\n                    id=\"fa-referral-type\"\n                    className=\"fa-referral-type\"\n                    value={referralType}\n                    onChange={setReferralType}\n                    disabled={!referralId}\n                    options={[\n                      { value: 'Recurring', label: 'Recurring — every pay cycle' },\n                      { value: 'One-time', label: 'One-time payout' },\n                    ]}\n                  />\n                </div>\n                {referralId && (\n                  <div className=\"fa-referral-note\">\n                    {historicalReferralRate ? (\n                      <>\n                        Last referral rate paid to this company:{' '}\n                        <b>{formatMoney(historicalReferralRate, cur)}</b>\n                      </>\n                    ) : (\n                      <b>New referral</b>\n                    )}\n                  </div>\n                )}\n              </div>\n            ) : (\n              <div className=\"fa-rate-rows fa-print-rows\">\n                <RateRow label=\"Referral Name\" sub=\"added during onboarding\">\n                  <div className=\"fa-rate-val\">{firstValue(record?.referral?.referalCompanyName, identity?.referralName)}</div>\n                </RateRow>\n                <RateRow\n                  label={(\n                    <span className=\"fa-locked-label\">\n                      Referral Rate\n                      {referralCfg.rateEditable && config.persist?.rateHistory && (\n                        <button\n                          type=\"button\"\n                          className=\"fa-history-btn\"\n                          aria-label=\"View referral rate history\"\n                          title=\"View referral rate history\"\n                          onClick={() => openRateHistory('Referral Rate History', referralRateHistory)}\n                        >\n                          <ClockCircleOutlined />\n                        </button>\n                      )}\n                    </span>\n                  )}\n                  sub={oneTimeReferral ? 'one-time payout — excluded from recurring margin' : 'deducted every pay cycle'}\n                  value={oneTimeReferral\n                    ? formatMoney(referralRate, cur)\n                    : `−${formatMoney(referralRate, cur).replace('−', '')}${unitSuffix ? ` ${unitSuffix}` : ''}`}\n                  deduction={!oneTimeReferral}\n                />\n              </div>\n            )}\n          </div>\n        </section>\n      )}\n\n      {/* Outcome — the margin */}\n      {hasProposedRate && (\n        <div className={`fa-outcome ${marginTone}`}>\n          <div className=\"fa-outcome-label\">\n            <div className=\"fa-outcome-icon\">\n              {marginTone === 'fa-good' ? <RiseOutlined /> : <WarningOutlined />}\n            </div>\n            <div className=\"fa-outcome-t\">{config.margin.label}</div>\n          </div>\n          <div className=\"fa-outcome-stats\">\n            <Stat label=\"Net Proposed Rate\" value={<>{formatMoney(computed.netProposedRate, cur)}<span className=\"fa-u\">{unitSuffix}</span></>} />\n            <span className=\"fa-stat-arrow\">−</span>\n            <Stat label={`Net ${employerSideLabel} Rate`} value={<>{formatMoney(computed.netEmployerRate, cur)}<span className=\"fa-u\">{unitSuffix}</span></>} />\n            {referralInMargin && (\n              <>\n                <span className=\"fa-stat-arrow\">−</span>\n                <Stat label=\"Referral Rate\" tone=\"referral\" value={<>{formatMoney(computed.referralRate, cur)}<span className=\"fa-u\">{unitSuffix}</span></>} />\n              </>\n            )}\n            <Stat hero label=\"Margin\" value={<>{formatMoney(computed.totalMargin, cur)}<span className=\"fa-u\">{unitSuffix}</span></>} />\n          </div>\n        </div>\n      )}\n\n      {/* Margin health message — a plain-language read on the profit % against\n          the configured target, coloured to match the outcome tone. */}\n      {hasProposedRate && (\n        <div className={`fa-margin-note ${marginTone}`}>\n          <span className=\"fa-margin-note-pct\">{marginPercent.toFixed(1)}%</span>\n          <span className=\"fa-margin-note-text\">\n            {marginTone === 'fa-bad'\n              ? <>This submission is running at a <b>loss</b>. Adjust the proposed or employer rate before approving.</>\n              : marginTone === 'fa-warn'\n                ? <>Profit margin is <b>below the {minMarginPercent}% target</b>. Consider a higher proposed rate before approving.</>\n                : <>Healthy margin — at or above the {minMarginPercent}% target.</>}\n          </span>\n        </div>\n      )}\n\n      {/* Reject reason (only when the reject action requires one and it's not read-only-CFO-approved) */}\n      {reject?.requireReason && (\n        <div className=\"fa-reason\">\n          {reject.requireCategory && (\n            <>\n              <label className=\"fa-reason-label\" htmlFor=\"fa-rejection-category\">\n                Return To <span>(required to reject)</span>\n              </label>\n              <Select\n                id=\"fa-rejection-category\"\n                placeholder=\"Select where to return this rejection\"\n                value={category || undefined}\n                status={categoryError ? 'error' : ''}\n                options={[\n                  { value: 'submission', label: 'Submission' },\n                  { value: 'onboarding', label: 'Onboarding' },\n                ]}\n                onChange={(value) => { setCategory(value); setCategoryError(false); }}\n                style={{ width: '100%', marginBottom: 16 }}\n              />\n              {categoryError && <div className=\"fa-reason-error\">! Select where to return the rejection.</div>}\n            </>\n          )}\n          <label className=\"fa-reason-label\" htmlFor=\"fa-reason\">\n            Comments <span>(required to reject)</span>\n          </label>\n          <TextArea\n            id=\"fa-reason\"\n            rows={3}\n            maxLength={500}\n            showCount\n            value={reason}\n            status={reasonError ? 'error' : ''}\n            placeholder=\"Enter your comments here…\"\n            onChange={(e) => { setReason(e.target.value); if (e.target.value.trim()) setReasonError(false); }}\n          />\n          {reasonError && <div className=\"fa-reason-error\">! Comments are required when rejecting.</div>}\n        </div>\n      )}\n\n      {/* Over-the-client-rate warning — the full comparison, immediately above\n          the action bar so it is read at the moment of deciding rather than\n          discovered as a disabled button. Every string is config. */}\n      {overClientWarns && (\n        <div className=\"fa-rate-warning\" role=\"status\">\n          <div className=\"fa-rate-warning-head\">\n            <WarningOutlined className=\"fa-rate-warning-icon\" />\n            <h4>{overClientText('title')}</h4>\n          </div>\n          <div className=\"fa-rate-warning-grid\">\n            <div className=\"fa-rate-warning-cell\">\n              <span className=\"fa-rate-warning-key\">Client Job Rate</span>\n              <span className=\"fa-rate-warning-val\">{overClientTokens.client}</span>\n            </div>\n            <div className=\"fa-rate-warning-cell\">\n              <span className=\"fa-rate-warning-key\">Proposed Rate</span>\n              <span className=\"fa-rate-warning-val\">{overClientTokens.proposed}</span>\n            </div>\n            <div className=\"fa-rate-warning-cell fa-rate-warning-delta\">\n              <span className=\"fa-rate-warning-key\">Over by</span>\n              <span className=\"fa-rate-warning-val\">\n                {overClientTokens.delta} <small>({overClientTokens.pct})</small>\n              </span>\n            </div>\n          </div>\n          {overClientText('body') && (\n            <p className=\"fa-rate-warning-body\">{overClientText('body')}</p>\n          )}\n          {/* The resulting margin, in the same language the margin tile uses —\n              the consequence the approver actually needs in order to judge. */}\n          <p className=\"fa-rate-warning-margin\">\n            Resulting margin:{' '}\n            <b className={marginTone}>\n              {formatMoney(computed.totalMargin, cur)}{unitSuffix}\n              {Number(computed.netProposedRate) > 0 && <> ({marginPercent.toFixed(1)}%)</>}\n            </b>\n          </p>\n        </div>\n      )}\n\n      <Modal\n        title={historyModal.title}\n        open={historyModal.open}\n        footer={null}\n        onCancel={() => setHistoryModal((current) => ({ ...current, open: false }))}\n      >\n        {historyModal.rows.length ? (\n          <div className=\"fa-history-list\">\n            {historyModal.rows.map((entry) => (\n              <div className=\"fa-history-row\" key={entry.key}>\n                <div>\n                  <div className=\"fa-history-rate fa-num\">\n                    {entry.currency || cur}{entry.rate.toFixed(2)}{entry.unit ? `/${entry.unit}` : ''}\n                  </div>\n                  {entry.by !== undefined && entry.by !== null && entry.by !== '' && (\n                    <div className=\"fa-history-by\">\n                      Updated by {historyActorNames[String(entry.by)] || String(entry.by)}\n                    </div>\n                  )}\n                </div>\n                <div className=\"fa-history-date\">{formatSubmittedDate(entry.at)}</div>\n              </div>\n            ))}\n          </div>\n        ) : (\n          <div className=\"fa-history-empty\">No rate history available.</div>\n        )}\n      </Modal>\n\n      {/* Deliberate second step for approving above the client rate. */}\n      <Modal\n        open={overClientConfirmOpen}\n        title={overClientText('confirmTitle')}\n        okText={overClientText('confirmOk') || 'Approve anyway'}\n        cancelText={overClientText('confirmCancel') || 'Go back'}\n        okButtonProps={{ danger: true }}\n        onCancel={() => setOverClientConfirmOpen(false)}\n        onOk={() => {\n          setOverClientConfirmOpen(false);\n          runAction(config.actions.primary, { skipOverClientConfirm: true });\n        }}\n      >\n        <p>{overClientText('confirmBody')}</p>\n      </Modal>\n\n      {/* Action bar */}\n      {config.actions?.show !== false && (primary || reject) && (\n        <div className=\"fa-action-bar\">\n          <div className=\"fa-action-note\">\n            {proposedRateMissing\n              ? <><b>Proposed rate required</b> — enter it above to enable {primary?.label ?? 'approval'}.</>\n              : type === FINANCE_TYPE_CFO\n              ? <>Approving finalizes payroll at <b>{formatMoney(computed.netProposedRate, cur)}{unitSuffix}</b>{referralVisible ? <> including the {String(referralType).toLowerCase()} <b>{formatMoney(referralRate, cur)}{unitSuffix}</b> referral</> : null}.</>\n              : <>Approving locks the <b>{formatMoney(computed.netProposedRate, cur)}{unitSuffix}</b> proposed rate and moves this forward.</>}\n          </div>\n          <div className=\"fa-actions\">\n            {onClose && <AppButton className=\"fa-btn-ghost\" onClick={onClose}>Cancel</AppButton>}\n            {reject && (\n              <AppButton\n                danger\n                loading={busy === reject.key}\n                disabled={Boolean(busy)}\n                onClick={() => runAction(reject)}\n              >\n                {reject.label}\n              </AppButton>\n            )}\n            {primary && (\n              // A disabled antd Button swallows mouse events, so the Tooltip is\n              // anchored on a wrapper span — otherwise the \"why is this off?\"\n              // explanation never appears, which is the whole point here.\n              <Tooltip title={primaryBlockedReason || ''} placement=\"top\">\n                <span className=\"fa-btn-tip\">\n                  <AppButton\n                    variant=\"primary\"\n                    icon={<CheckOutlined />}\n                    loading={busy === primary.key}\n                    disabled={Boolean(busy) || Boolean(primaryBlockedReason)}\n                    onClick={() => runAction(primary)}\n                  >\n                    {primary.label}\n                  </AppButton>\n                </span>\n              </Tooltip>\n            )}\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\nFinanceApprovalPanel.propTypes = {\n  type: PropTypes.string.isRequired,\n  record: PropTypes.object,\n  lookups: PropTypes.object,\n  identity: PropTypes.object,\n  referralOptions: PropTypes.array,\n  onReferralChange: PropTypes.func,\n  onAddReferral: PropTypes.func,\n  onValuesChange: PropTypes.func,\n  currentUserId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n  actions: PropTypes.object,\n  onClose: PropTypes.func,\n  variant: PropTypes.oneOf(['popup', 'page']),\n};\n\nFinanceApprovalPanel.defaultProps = {\n  record: {},\n  lookups: {},\n  identity: {},\n  referralOptions: [],\n  variant: 'page',\n};\n","// ─────────────────────────────────────────────────────────────────────────\n// financeApprovalData — resolves the FULL finance picture for a submission.\n//\n// Why this exists: this backend has NO by-id detail route (module-data-detail\n// 404s for submissions/clients/jobs) and its list projections drop both the\n// reference ids and the rate fields. The ONE endpoint that returns a record's\n// real values is /admin/form-groups?module=&id= — it carries every configured\n// field value PLUS `recordMeta` (clientId, jobId, applicantId …). So that is\n// the authoritative source here, and the remaining joins are resolved from the\n// list endpoints that do work.\n//\n// Verified against zinnext-dev-api-v1:\n//   form-groups(submission) → Employer group { employerId, location(id), tax },\n//                             Rate Details  { candidateBudget.*, proposedRate.* },\n//                             Job Information { jobTitle, clientName, jobRefrenceId }\n//   locations list          → { _id, name, taxValue }   ← W2 tax + location NAME\n//   employers list          → { _id, empCompanyName, empCompanyLocation }\n//   clients   list          → ONLY the configured list columns (clientName,\n//                             clientRefrenceId, clientType, websiteUrl,\n//                             federalId, paymentTerms, clientStatus). An\n//                             earlier comment here claimed this returned the\n//                             full document — it does NOT (proven by\n//                             cmd/probe-client-vms-formgroups), which is why\n//                             the client VMS discount kept resolving to 0%.\n//                             The fee is read via fullRecordOf('clients', …).\n//   jobs      detail        → scoped to the caller's recruiter hierarchy, so\n//                             jobPayDetails (Client Job Rate) can come back\n//                             empty; also read via fullRecordOf('jobs', …).\n// ─────────────────────────────────────────────────────────────────────────\nimport { idOf, flattenGroups, findEmployerRow, unflattenRecord } from './financeApprovalEngine.js';\nimport { fetchJsonWithAuth } from '../../services/authApi';\nimport { AUTH_URL } from '../../services/apiConfig';\nimport { getModuleDataList } from '../../services/moduleDataApi';\nimport { getModuleDataDetail } from '../../services/detailedViewApi';\n\nconst norm = (v) => String(v ?? '').trim().toLowerCase();\n\nfunction extractRows(json) {\n  const d = json?.data ?? json;\n  for (const key of ['data', 'rows', 'records', 'items', 'list']) {\n    if (Array.isArray(d?.[key])) return d[key];\n  }\n  return Array.isArray(d) ? d : [];\n}\n\n// listOf — CAUTION: /module-data-list applies a Mongo PROJECTION built from the\n// module's configured list-view columns (see moduleDataController.go's\n// \"Projection: visible fields + sort field + tab field\"). Any field that isn't\n// a visible list column is STRIPPED from every row — e.g. clients come back\n// without vmsFeeHistory/vmsPercentage/vmsFee, and jobs without jobPayDetails.\n// So this is only safe for locating a record and reading its list-visible\n// columns; never trust it for a value the finance math depends on — use\n// fullRecordOf() for those.\nconst listOf = (module) => getModuleDataList(module, 300, 0).then(extractRows).catch(() => []);\nconst byId = (id) => (r) => id && idOf(r._id ?? r.id) === String(id);\n\n// rawRecordOf — the STORED document, projection-free and config-free.\n// /module/list?module=&id= runs a plain Find with no projection (see\n// ModuleListHandler), so it is the only path that returns fields which are\n// neither list-view columns NOR configured form fields. `signatureEmail` is\n// exactly that: it is on every submission but appears in no form group, so\n// flattenGroups can never surface it.\nconst rawRecordOf = (module, id) => (\n  !id\n    ? Promise.resolve({})\n    : fetchJsonWithAuth(\n      AUTH_URL,\n      `/module/list?module=${encodeURIComponent(module)}&id=${encodeURIComponent(id)}`,\n    )\n      .then((json) => {\n        const data = json?.data ?? json ?? {};\n        const rows = Array.isArray(data?.data) ? data.data : (Array.isArray(data) ? data : []);\n        return rows[0] ?? {};\n      })\n      .catch(() => ({}))\n);\n\n// Users are served by the auth API rather than the generic module list.\n// Resolve only the submission creator instead of loading the whole user list.\nconst userById = (userId) => (\n  userId === undefined || userId === null || userId === ''\n    ? Promise.resolve(null)\n    : fetchJsonWithAuth(\n      AUTH_URL,\n      `/get-detailed-view?userId=${encodeURIComponent(userId)}`,\n    ).then((json) => json?.data ?? json ?? null).catch(() => null)\n);\n\nfunction userDisplayName(user) {\n  if (!user) return '';\n  const firstName = user.first_name ?? user.firstName ?? user.FIRST_NAME;\n  const lastName = user.last_name ?? user.lastName ?? user.LAST_NAME;\n  return [firstName, lastName].filter(Boolean).join(' ').trim()\n    || user.user_name\n    || user.userName\n    || user.username\n    || user.email\n    || '';\n}\n\n// payDetailsOf — a source's jobPayDetails as a flat rate object. The field is\n// an appendHistory container, so a raw record holds the whole history ARRAY;\n// the LAST entry is the current rate. A source that already carries a flat\n// object (the form-groups path, unwrapped server-side) passes through.\nfunction payDetailsOf(source) {\n  const pay = source?.jobPayDetails;\n  const entry = Array.isArray(pay) ? pay[pay.length - 1] : pay;\n  return (entry && typeof entry === 'object' && !Array.isArray(entry)) ? entry : {};\n}\n\n// fullRecordOf — the record's REAL stored values, projection-free.\n// /admin/form-groups?module=&id= is the one endpoint that returns every\n// CONFIGURED field's actual value (this file's header explains why), and it\n// resolves append-history groups server-side to their latest entry\n// (AttachHistoryGroupValues) — so a client's current VMS fee arrives already\n// unwrapped from vmsFeeHistory[]. recordMeta is merged in for the scalar\n// linkage ids (clientId/jobId/…) that are never form fields.\nasync function fullRecordOf(module, id) {\n  if (!id) return {};\n  const payload = await getFormGroupsRaw(module, id).catch(() => ({}));\n  return {\n    ...unflattenRecord(flattenGroups(payload.groups ?? [])),\n    ...(payload.recordMeta ?? {}),\n  };\n}\n\n// getFormGroupsRaw — the package's getFormGroups() drops `recordMeta` (it only\n// returns the groups array), so we fetch the raw payload here.\nexport async function getFormGroupsRaw(module, id) {\n  // Routed through the SHARED fetcher (services/addFormApi → formGroupsCache)\n  // rather than issuing its own request: this asks the same question the form\n  // and the detail header already ask on pages that show all three, and three\n  // identical 15-60 kB payloads on one page load is the thing that cache exists\n  // to stop. The envelope (with recordMeta) is what this returns either way.\n  const { fetchFormGroupsPayload } = await import('../../services/addFormApi');\n  const json = await fetchFormGroupsPayload({ module, id });\n  return json?.data ?? json ?? {};\n}\n\n// resolveSubmissionFinance — the one call the finance surfaces use.\n// Returns { record, lookups, display } ready for resolveFinanceInputs().\nexport async function resolveSubmissionFinance(submissionId, seed = {}) {\n  const payload = await getFormGroupsRaw('submission', submissionId).catch(() => ({}));\n  const groups = payload.groups ?? [];\n  const meta = payload.recordMeta ?? {};\n  const flat = flattenGroups(groups);\n  const employerRow = findEmployerRow(groups);\n\n  const submissionClientId = idOf(meta.clientId ?? flat.clientId ?? seed.clientId);\n  const jobId = idOf(meta.jobId ?? flat.jobId ?? seed.jobId);\n  const employerId = idOf(employerRow.employerId);\n  const createdBy = meta.createdBy ?? flat.createdBy ?? seed.createdBy;\n  // \"locationId\" is the field's real stored key (see Form Groups → submissions\n  // → Employer → Location); \"location\" only ever existed as an old config\n  // alias, kept as a fallback for rows written before that field existed.\n  const locationRef = employerRow.locationId ?? employerRow.location;\n\n  const [\n    jobJson, jobsList, clients, employers, locations, engagements, jobFull, submittedByUser, submissionRaw,\n  ] = await Promise.all([\n    jobId ? getModuleDataDetail('jobs', jobId).catch(() => null) : Promise.resolve(null),\n    listOf('jobs'),\n    listOf('clients'),\n    listOf('employers'),\n    listOf('locations'),\n    // workforceEngagements is a plain schema-free module too (same /module-data-list\n    // path as everything else here) — once this submission has moved to\n    // onboarding, its engagement carries a clientId stamped at movement-creation\n    // time, one more independent path to the right client alongside the job.\n    listOf('workforceEngagements'),\n    // Authoritative, projection-free job values — jobPayDetails (the Client\n    // Job Rate) is NOT a list-view column, so the list rows above never carry\n    // it, and getJobDetailView below is scoped to the caller's own recruiter\n    // hierarchy (thin/empty for a manager approving a job they aren't\n    // assigned to). Configured in Form Groups → jobs → \"rate_details\".\n    fullRecordOf('jobs', jobId),\n    userById(createdBy),\n    // The submission's own stored document — for signatureEmail, which no\n    // form group configures and no list projection keeps (see rawRecordOf).\n    rawRecordOf('submissions', submissionId),\n  ]);\n\n  const jobData = jobJson?.data ?? jobJson ?? {};\n  const jobDetail = jobData.record ?? jobData.item ?? jobData ?? {};\n  const jobListMatch = jobsList.find(byId(jobId)) ?? {};\n  // Widest-to-narrowest: projected list row → scoped legacy detail → the\n  // projection-free configured values, which win. jobPayDetails is merged\n  // KEY-WISE (not replaced) so a rate present in only one source survives.\n  // Each source is run through payDetailsOf first: jobs.jobPayDetails is an\n  // appendHistory container, so the RAW sources (list row, legacy detail) hold\n  // the whole history ARRAY, and spreading an array yields {0: {...}} — the\n  // rate keys silently vanish. Take the last entry (the current rate) instead.\n  const job = { ...jobListMatch, ...jobDetail, ...jobFull };\n  job.jobPayDetails = {\n    ...payDetailsOf(jobListMatch),\n    ...payDetailsOf(jobDetail),\n    ...payDetailsOf(jobFull),\n  };\n  // If this submission has moved to onboarding, its workforceEngagement\n  // carries its own clientId (stamped at movement-creation time from the job)\n  // — a third independent path to the client, alongside the job and the\n  // submission's own field, for whichever one didn't drop out.\n  const engagementMatch = (Array.isArray(engagements) ? engagements : [])\n    .find((e) => idOf(e.submissionId) === String(submissionId));\n  // The real link is submission → job → client: jobs.clientId is the\n  // authoritative source (a job's client assignment is the one thing that\n  // can change after a submission was created, so the submission's own\n  // clientId can drift stale) — resolve it FIRST, off the job we just\n  // fetched, then the linked engagement's own clientId, and only fall back to\n  // the submission's own clientId when neither is available.\n  const clientId = idOf(job.clientId) || idOf(engagementMatch?.clientId) || submissionClientId;\n  // Name fallback — last resort for a submission/job whose clientId is missing\n  // or malformed entirely. NOTE clientName is NOT unique here (\"TCS\" alone has\n  // 4 documents; \"Mphasis\"/\"Wipro\" are duplicated too), so this can land on\n  // the wrong twin. It only decides WHICH id to re-read below, never the VMS\n  // value itself, so the blast radius is a wrong client name rather than a\n  // silently wrong discount — but prefer fixing the duplicate client records.\n  const clientNameHint = flat.clientName ?? seed.clientName ?? job.clientName;\n  const nameMatches = clientNameHint\n    ? clients.filter((c) => norm(c.clientName) === norm(clientNameHint))\n    : [];\n  const clientRow = clients.find(byId(clientId)) ?? nameMatches[0] ?? {};\n  // THE fix for \"client discount shows 0%\": the row above came from\n  // /module-data-list, whose projection keeps only the configured list\n  // columns (clientName, clientRefrenceId, clientType, websiteUrl, federalId,\n  // paymentTerms, clientStatus) — the VMS fee is in NONE of them, so that row\n  // is structurally incapable of carrying it no matter which client we match.\n  // Re-read the same client projection-free for its real, current VMS fee.\n  const clientFull = await fullRecordOf('clients', idOf(clientRow._id ?? clientRow.id) || clientId);\n  const client = { ...clientRow, ...clientFull };\n  const employer = employers.find(byId(employerId)) ?? {};\n  // location may be stored as an id OR a name — match either.\n  const location = locations.find(byId(locationRef))\n    ?? locations.find((l) => norm(l.name) === norm(locationRef))\n    ?? {};\n\n  // The synthetic submission: all flat field values + the employer row shaped\n  // as the array the engine expects. signatureEmail is filled in from the raw\n  // document ONLY when nothing else supplied it — the raw doc is deliberately\n  // not merged wholesale, since its append-history fields (proposedRate,\n  // candidateRate …) are arrays the engine does not expect here.\n  const submission = {\n    ...(submissionRaw.signatureEmail ? { signatureEmail: submissionRaw.signatureEmail } : {}),\n    ...seed,\n    ...flat,\n    submission_current_employer: [employerRow],\n  };\n\n  return {\n    record: { submission, job, client, employer },\n    lookups: {\n      // Legacy fallback only — the engine now prefers client.vmsPercentage /\n      // client.vmsPercentageType (the Client form's current, admin-edited\n      // fields) directly off `client` above; this covers clients that predate\n      // that form group and were never re-saved under it.\n      clientVmsFee: client.vmsFee ?? flat.clientVmsFee ?? flat.vmsFee,\n      // W2 tax: inline on the employer row, else the matched location's taxValue.\n      locationTaxPercent: employerRow.tax ?? location.taxValue,\n    },\n    display: {\n      clientName: flat.clientName ?? client.clientName,\n      jobTitle: flat.jobTitle ?? job.jobTitle,\n      reqId: meta.jobClientRefrenceId ?? flat.jobRefrenceId ?? meta.jobRefrenceId ?? meta.mspReqId,\n      jobLocation: flat.jobLocation ?? job.jobLocation,\n      employerName: employer.empCompanyName,\n      employerLocation: location.name ?? employer.empCompanyLocation ?? locationRef,\n      // Submitted By — the submission's OWN signature wins.\n      // signatureEmail is stamped from the logged-in recruiter at submit time,\n      // so it is the record's first-hand account of who submitted it. It beats\n      // the createdBy user lookup, which is a numeric audit stamp that can\n      // resolve to a different account than the one that signed (an admin, an\n      // importer, a shared/stale id) — and did: createdBy 149 resolved to\n      // revinard22@gmail.com on a submission signed sam@realtekconsulting.net.\n      // The two removed fallbacks were not submitters at all: recruiterName is\n      // the EMPLOYER row's recruiter contact and submitSource is the\n      // submission's source (\"Internal\"), read as `vendor` by both popups.\n      submittedBy: submissionRaw.signatureEmail\n        || flat.signatureEmail\n        || seed.signatureEmail\n        || userDisplayName(submittedByUser),\n      email: flat.email,\n      candidateName: [flat.firstName, flat.lastName].filter(Boolean).join(' ') || flat.candidateFullName,\n      createdAt: meta.createdAt,\n      submissionId: meta.submissionId,\n    },\n    // Expose the linked engagement separately for API payload construction.\n    // It is intentionally not merged into record, so manager re-approval UI\n    // does not render onboarding referral details.\n    engagement: engagementMatch ?? null,\n    meta,\n  };\n}\n\n// ── Referral dropdown options ───────────────────────────────────────────────\n// getReferralOptions — every referrals record, normalized into the\n// {value,label,lastRate,type,record} shape FinanceApprovalPanel's referral\n// select expects (see the `mode:'select'` branch of financeApprovalConfig's\n// submissionManager/onboardingManager stages). Backend-agnostic like the rest\n// of this file (listOf → /module-data-list), so any host popup or page —\n// ManagerApproveBody, ZINNEXT-V2's SubmissionFinanceReviewPage,\n// OnboardingDetailPage — can share one resolver instead of each\n// re-implementing referral-list fetching itself.\nfunction referralDisplayName(record = {}) {\n  return record.referalCompanyName\n    ?? record.referralCompanyName\n    ?? record.referalName\n    ?? record.referralName\n    ?? record.vendorName\n    ?? record.employerName\n    ?? record.name\n    ?? record.companyName\n    ?? '';\n}\n\nfunction referralRateOf(record = {}) {\n  const nestedDetails = Array.isArray(record.referralDetails)\n    ? record.referralDetails.at(-1)\n    : record.referralDetails;\n  const finance = record.financeApproval ?? record.financeApprovalRequest ?? {};\n  const nestedFinanceDetails = Array.isArray(finance.referralDetails)\n    ? finance.referralDetails.at(-1)\n    : finance.referralDetails;\n\n  const value = [\n    nestedDetails?.referalRate, nestedDetails?.referralRate,\n    nestedFinanceDetails?.referalRate, nestedFinanceDetails?.referralRate,\n    finance.referalRate, finance.referralRate,\n    record.referalRate, record.referralRate,\n    record.referralLastPayRate, record.referalLastPayRate,\n    record.lastPayRate, record.payRate,\n  ].find((entry) => entry !== undefined && entry !== null && entry !== '');\n  const number = Number(value);\n  return Number.isFinite(number) ? number : 0;\n}\n\nfunction normalizedReferralText(value) {\n  return String(value ?? '').trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nfunction referralIdsFrom(record = {}) {\n  const details = Array.isArray(record.referralDetails)\n    ? record.referralDetails\n    : [record.referralDetails].filter(Boolean);\n  const finance = record.financeApproval ?? record.financeApprovalRequest ?? {};\n  const financeDetails = Array.isArray(finance.referralDetails)\n    ? finance.referralDetails\n    : [finance.referralDetails].filter(Boolean);\n\n  return [\n    record._id, record.id,\n    record.referralId, record.referalId,\n    record.referral_id, record.referal_id,\n    record.referral?._id, record.referral?.id,\n    record.referal?._id, record.referal?.id,\n    finance.referralId, finance.referalId,\n    record.engagement?.referralId, record.engagement?.referalId,\n    record.engagement?.financeApproval?.referralId,\n    record.engagement?.financeApproval?.referalId,\n    ...details.flatMap((item) => [item?.referralId, item?.referalId, item?.referral_id, item?.referal_id]),\n    ...financeDetails.flatMap((item) => [item?.referralId, item?.referalId, item?.referral_id, item?.referal_id]),\n  ].map(idOf).filter(Boolean);\n}\n\nfunction referralNamesFrom(record = {}) {\n  const details = Array.isArray(record.referralDetails)\n    ? record.referralDetails\n    : [record.referralDetails].filter(Boolean);\n  const finance = record.financeApproval ?? record.financeApprovalRequest ?? {};\n  const financeDetails = Array.isArray(finance.referralDetails)\n    ? finance.referralDetails\n    : [finance.referralDetails].filter(Boolean);\n\n  return [\n    referralDisplayName(record),\n    referralDisplayName(record.referral ?? {}),\n    referralDisplayName(record.referal ?? {}),\n    record.referralCompanyName, record.referalCompanyName,\n    record.referralName, record.referalName,\n    finance.referralCompanyName, finance.referalCompanyName,\n    finance.referralName, finance.referalName,\n    record.engagement?.referralCompanyName, record.engagement?.referalCompanyName,\n    record.engagement?.referralName, record.engagement?.referalName,\n    ...details.flatMap((item) => [\n      item?.referralCompanyName, item?.referalCompanyName,\n      item?.referralName, item?.referalName,\n    ]),\n    ...financeDetails.flatMap((item) => [\n      item?.referralCompanyName, item?.referalCompanyName,\n      item?.referralName, item?.referalName,\n    ]),\n  ].map(normalizedReferralText).filter(Boolean);\n}\n\nfunction referralHistoryDate(record = {}) {\n  const raw = record.financeApproval?.approvedAt\n    ?? record.financeApproval?.submittedAt\n    ?? record.financeApprovalRequest?.approvedAt\n    ?? record.financeApprovalRequest?.submittedAt\n    ?? record.decidedAt\n    ?? record.submittedAt\n    ?? record.updatedAt\n    ?? record.createdAt\n    ?? 0;\n  return new Date(raw?.$date ?? raw).getTime() || 0;\n}\n\n// Raw module data is required here because /module-data-list is driven by the\n// admin list-view projection and commonly omits referralId/referralDetails/rate.\nasync function rawModuleRows(module, { pageSize = 100, maxPages = 20 } = {}) {\n  const rows = [];\n  for (let page = 1; page <= maxPages; page += 1) {\n    const params = new URLSearchParams({\n      module,\n      page: String(page),\n      limit: String(pageSize),\n    });\n    const json = await fetchJsonWithAuth(AUTH_URL, `/module/list?${params.toString()}`);\n    const data = json?.data ?? json ?? {};\n    const batch = Array.isArray(data?.data)\n      ? data.data\n      : Array.isArray(data?.rows)\n        ? data.rows\n        : Array.isArray(data)\n          ? data\n          : [];\n    rows.push(...batch);\n\n    const total = Number(data?.total ?? 0);\n    if (batch.length < pageSize || (total > 0 && rows.length >= total)) break;\n  }\n  return rows;\n}\n\nfunction lastReferralRateFromHistory(referral = {}, rows = []) {\n  const ids = new Set(referralIdsFrom(referral));\n  const names = new Set(referralNamesFrom(referral));\n  if (!ids.size && !names.size) return 0;\n\n  return rows\n    .filter((row) => (\n      referralIdsFrom(row).some((id) => ids.has(id))\n      || referralNamesFrom(row).some((name) => names.has(name))\n    ))\n    .map((row) => ({ rate: referralRateOf(row), date: referralHistoryDate(row) }))\n    .filter((entry) => entry.rate > 0)\n    .sort((left, right) => right.date - left.date)[0]?.rate ?? 0;\n}\n\nexport async function getReferralOptions() {\n  const rows = await listOf('referrals');\n  const referrals = rows.filter((row) => !row?.isDeleted && referralDisplayName(row));\n\n  // Fetch history ONCE for the whole dropdown. Doing this inside each referral\n  // option would multiply API calls by the number of referral companies.\n  // Submissions is important here because Manager Approve writes the selected\n  // referral/rate there before onboarding/workforce records exist.\n  const historyModules = [\n    'submissions',\n    'workforceFinanceApprovals',\n    'workforceEngagements',\n    'onboarding',\n    'candidateMovements',\n  ];\n  const historyRows = (await Promise.all(\n    historyModules.map((module) => rawModuleRows(module).catch(() => [])),\n  )).flat();\n\n  const options = await Promise.all(referrals.map(async (row) => {\n    const historicalRate = lastReferralRateFromHistory(row, historyRows);\n    const masterRate = referralRateOf(row);\n    const rate = historicalRate > 0 ? historicalRate : masterRate;\n    return {\n      value: idOf(row._id ?? row.id),\n      label: referralDisplayName(row),\n      isNewReferral: rate <= 0,\n      hasHistory: rate > 0,\n      lastRate: rate,\n      lastPayRate: rate,\n      referralLastPayRate: rate,\n      referalLastPayRate: rate,\n      rate,\n      referralRate: rate,\n      referalRate: rate,\n      type: row.referalType ?? row.referralType,\n      record: row,\n    };\n  }));\n\n  return options.filter((option) => option.value);\n}\n\nexport { idOf, flattenGroups, findEmployerRow };\n","import { Card, Empty, Tooltip } from 'antd';\nimport { DownloadOutlined, EyeOutlined } from '@ant-design/icons';\nimport '../../styles/file-list.css';\n\n/*\n * FileListCard — a titled card of named files, each with a Preview (eye) and\n * Download action. Generic file-list chip UI (not tied to any one module) —\n * pass `onPreview` to wire it to whatever viewer the page already uses\n * (e.g. DocumentViewer). Falls back to an empty state when `files` is empty.\n */\nexport default function FileListCard({\n  title = 'Proof',\n  files = [],\n  onPreview,\n  emptyText = 'No files uploaded',\n  className,\n}) {\n  if (!files.length) {\n    return (\n      <Card size=\"small\" className={`znx-file-list__empty ${className ?? ''}`.trim()}>\n        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={emptyText} />\n      </Card>\n    );\n  }\n\n  return (\n    <Card size=\"small\" title={title} className={`znx-file-list__card ${className ?? ''}`.trim()}>\n      {files.map((file, index) => (\n        <div className=\"znx-file-list__chip\" key={file.url ?? index}>\n          <span className=\"znx-file-list__name\" title={file.name}>\n            {file.name || 'File'}\n          </span>\n          <span className=\"znx-file-list__actions\">\n            {onPreview && (\n              <Tooltip title=\"Preview\">\n                <button\n                  type=\"button\"\n                  className=\"znx-file-list__btn\"\n                  onClick={() => onPreview(index)}\n                  aria-label={`Preview ${file.name || 'file'}`}\n                >\n                  <EyeOutlined />\n                </button>\n              </Tooltip>\n            )}\n            <Tooltip title=\"Download\">\n              <a\n                className=\"znx-file-list__btn\"\n                href={file.url}\n                download={file.name}\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                aria-label={`Download ${file.name || 'file'}`}\n              >\n                <DownloadOutlined />\n              </a>\n            </Tooltip>\n          </span>\n        </div>\n      ))}\n    </Card>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport dayjs from 'dayjs';\nimport { message } from 'antd';\nimport { getFormGroups } from '../services/addFormApi';\nimport { getRecordForEdit, updateRecord } from '../services/detailedViewApi';\nimport { goBackOrTo } from '../utils/backNav';\n\nexport function useEditForm({\n    moduleName,\n    recordId,\n    cancelPath,\n    onSuccess,\n    fieldNameMap = {},\n    onFileUpload = null,\n}) {\n    const navigate = useNavigate();\n\n    const [formGroups, setFormGroups] = useState([]);\n    const [rawRecord, setRawRecord] = useState({});\n    const [loading, setLoading] = useState(false);\n    const [error, setError] = useState('');\n    const [submitting, setSubmitting] = useState(false);\n    const [submitError, setSubmitError] = useState('');\n\n    // Fetch form config + record\n    useEffect(() => {\n        if (!moduleName || !recordId) return;\n        let cancelled = false;\n\n        async function fetchData() {\n            try {\n                setLoading(true);\n                setError('');\n\n                const [groupsRes, recordRes] = await Promise.all([\n                    getFormGroups({ module: moduleName, id: recordId }),\n                    getRecordForEdit(moduleName, recordId),\n                ]);\n\n                if (cancelled) return;\n                setFormGroups(Array.isArray(groupsRes) ? groupsRes : []);\n                setRawRecord(recordRes ?? {});\n            } catch (err) {\n                if (!cancelled) setError(err?.message || 'Failed to load record');\n            } finally {\n                if (!cancelled) setLoading(false);\n            }\n        }\n\n        fetchData();\n        return () => { cancelled = true; };\n    }, [moduleName, recordId]);\n\n    // Build payload — generic, works for all modules\n    function buildPayload(values, groups) {\n        const payload = { ...rawRecord };\n\n        const allFields = groups.flatMap(g => g.fields ?? []);\n\n        Object.entries(values).forEach(([key, value]) => {\n            if (value === undefined) return;\n\n            const field = allFields.find(f => f.field === key);\n            if (field?.type === 'file') return; // uploaded separately\n\n            if (dayjs.isDayjs(value)) {\n                applyDotValue(payload, key, value.format('MM-DD-YYYY'));\n                return;\n            }\n\n            applyDotValue(payload, key, value);\n        });\n\n        // Clean leftover dot-notation keys\n        Object.keys(payload).forEach(k => {\n            if (k.includes('.')) delete payload[k];\n        });\n\n        // Apply field name remapping (e.g. mspReqId → mspreqId)\n        Object.entries(fieldNameMap).forEach(([from, to]) => {\n            if (payload[from] !== undefined) {\n                payload[to] = payload[from];\n                delete payload[from];\n            }\n        });\n\n        // Strip non-ISO date strings Go can't parse\n        Object.keys(payload).forEach(key => {\n            const val = payload[key];\n            if (typeof val === 'string' && val !== '') {\n                const isDateKey = /(date|time|Date|Time|At|at)$/.test(key);\n                const isRelative = /ago|month|year|day|week|hour|minute/i.test(val);\n                const isISO = /^\\d{4}-\\d{2}-\\d{2}/.test(val);\n                if (isDateKey && (isRelative || !isISO)) delete payload[key];\n            }\n        });\n\n        // Strip raw file objects\n        Object.keys(payload).forEach(key => {\n            const val = payload[key];\n            if (Array.isArray(val) && val[0]?.originFileObj) delete payload[key];\n        });\n\n        return payload;\n    }\n\n    // Submit\n    async function submit(values, groups) {\n        try {\n            setSubmitting(true);\n            setSubmitError('');\n\n            // Upload files first\n            if (onFileUpload) {\n                const fileFields = groups\n                    .flatMap(g => g.fields ?? [])\n                    .filter(f => f.type === 'file');\n\n                for (const field of fileFields) {\n                    const fileList = values[field.field];\n                    if (!Array.isArray(fileList)) continue;\n                    const newFiles = fileList.filter(f => f.originFileObj instanceof File);\n                    await Promise.all(\n                        newFiles.map(f => onFileUpload(field.field, f.originFileObj, recordId))\n                    );\n                }\n            }\n\n            await updateRecord(moduleName, recordId, buildPayload(values, groups));\n            message.success(`${moduleName} updated successfully`);\n\n            if (onSuccess) onSuccess();\n            // Back to where the form was opened from; cancelPath is the\n            // cold-deep-link fallback only. See utils/backNav.js.\n            else goBackOrTo(navigate, { cancelPath });\n\n        } catch (err) {\n            setSubmitError(err?.message || 'Failed to save changes');\n            message.error(err?.message || 'Failed to save changes');\n        } finally {\n            setSubmitting(false);\n        }\n    }\n\n    return {\n        formGroups,\n        rawRecord,\n        loading,\n        error,\n        submitting,\n        submitError,\n        submit,\n    };\n}","export default \"data:image/svg+xml,%3csvg%20width='380'%20height='130'%20viewBox='0%200%20380%20130'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_30_1933)'%20filter='url(%23filter0_d_30_1933)'%3e%3cpath%20d='M13.5623%2060V34.296H19.2143V44.16H29.6183V34.296H35.2703V60H29.6183V48.912H19.2143V60H13.5623ZM39.8859%2060V34.296H45.5379V60H39.8859ZM50.1431%2060V34.296H64.0031C66.2591%2034.296%2068.0951%2034.992%2069.5111%2036.384C70.8551%2037.728%2071.5271%2039.396%2071.5271%2041.388C71.5271%2044.58%2070.1711%2046.728%2067.4591%2047.832V47.904C69.7151%2048.48%2070.9631%2050.484%2071.2031%2053.916C71.2751%2054.948%2071.3471%2055.98%2071.4191%2057.012C71.5631%2058.404%2071.8511%2059.4%2072.2831%2060H66.6311C66.3671%2059.352%2066.1631%2058.38%2066.0191%2057.084C65.9231%2056.004%2065.8271%2054.924%2065.7311%2053.844C65.5391%2052.452%2065.1191%2051.456%2064.4711%2050.856C63.8471%2050.256%2062.8391%2049.956%2061.4471%2049.956H55.7951V60H50.1431ZM55.7951%2038.688V45.924H61.9871C64.5791%2045.924%2065.8751%2044.7%2065.8751%2042.252C65.8751%2039.876%2064.5791%2038.688%2061.9871%2038.688H55.7951ZM75.7635%2060V34.296H94.9875V39.048H81.4155V44.556H93.8715V48.948H81.4155V55.248H95.2755V60H75.7635ZM118.336%2060V10.02H125.336L142.626%2053.84L159.846%2010.02H166.846V60H162.086V16.81H161.946L144.866%2060H140.386L123.236%2016.81H123.096V60H118.336ZM190.506%2022.83C195.826%2022.83%20200.05%2024.72%20203.176%2028.5C206.116%2032.0467%20207.586%2036.5267%20207.586%2041.94C207.586%2047.3533%20206.116%2051.8333%20203.176%2055.38C200.05%2059.16%20195.826%2061.05%20190.506%2061.05C185.186%2061.05%20180.963%2059.16%20177.836%2055.38C174.896%2051.8333%20173.426%2047.3533%20173.426%2041.94C173.426%2036.5267%20174.896%2032.0467%20177.836%2028.5C180.963%2024.72%20185.186%2022.83%20190.506%2022.83ZM190.506%2026.54C186.493%2026.54%20183.32%2028.15%20180.986%2031.37C178.886%2034.2633%20177.836%2037.7867%20177.836%2041.94C177.836%2046.0933%20178.886%2049.6167%20180.986%2052.51C183.32%2055.73%20186.493%2057.34%20190.506%2057.34C194.52%2057.34%20197.693%2055.73%20200.026%2052.51C202.126%2049.6167%20203.176%2046.0933%20203.176%2041.94C203.176%2037.7867%20202.126%2034.2633%20200.026%2031.37C197.693%2028.15%20194.52%2026.54%20190.506%2026.54ZM213.443%2060V23.88H217.503V32.35H217.643C218.763%2029.41%20220.513%2027.1467%20222.893%2025.56C225.273%2023.9733%20228.073%2023.25%20231.293%2023.39V27.8C227.373%2027.6133%20224.153%2028.78%20221.633%2031.3C219.113%2033.7733%20217.853%2036.9233%20217.853%2040.75V60H213.443ZM265.203%2043.13H237.413C237.46%2046.8633%20238.393%2050.0367%20240.213%2052.65C242.406%2055.7767%20245.44%2057.34%20249.313%2057.34C255.286%2057.34%20259.066%2054.26%20260.653%2048.1H265.063C263.056%2056.7333%20257.806%2061.05%20249.313%2061.05C243.9%2061.05%20239.746%2059.16%20236.853%2055.38C234.286%2051.9733%20233.003%2047.4933%20233.003%2041.94C233.003%2036.6667%20234.286%2032.28%20236.853%2028.78C239.793%2024.8133%20243.946%2022.83%20249.313%2022.83C254.773%2022.83%20258.926%2024.9533%20261.773%2029.2C264.246%2032.8867%20265.39%2037.53%20265.203%2043.13ZM237.413%2039.42H260.793C260.7%2035.8733%20259.65%2032.8867%20257.643%2030.46C255.496%2027.8467%20252.72%2026.54%20249.313%2026.54C245.906%2026.54%20243.106%2027.87%20240.913%2030.53C238.953%2032.8633%20237.786%2035.8267%20237.413%2039.42Z'%20fill='white'/%3e%3cpath%20d='M124.417%20111V90.048H116.713V85.296H137.773V90.048H130.069V111H124.417ZM141.637%20111V85.296H147.289V111H141.637ZM153.154%20111V85.296H167.014C169.27%2085.296%20171.106%2085.992%20172.522%2087.384C173.866%2088.728%20174.538%2090.396%20174.538%2092.388C174.538%2095.58%20173.182%2097.728%20170.47%2098.832V98.904C172.726%2099.48%20173.974%20101.484%20174.214%20104.916C174.286%20105.948%20174.358%20106.98%20174.43%20108.012C174.574%20109.404%20174.862%20110.4%20175.294%20111H169.642C169.378%20110.352%20169.174%20109.38%20169.03%20108.084C168.934%20107.004%20168.838%20105.924%20168.742%20104.844C168.55%20103.452%20168.13%20102.456%20167.482%20101.856C166.858%20101.256%20165.85%20100.956%20164.458%20100.956H158.806V111H153.154ZM158.806%2089.688V96.924H164.998C167.59%2096.924%20168.886%2095.7%20168.886%2093.252C168.886%2090.876%20167.59%2089.688%20164.998%2089.688H158.806ZM180.034%20111V85.296H199.258V90.048H185.686V95.556H198.142V99.948H185.686V106.248H199.546V111H180.034ZM226.246%20111V61.02H231.006V106.94H259.006V111H226.246ZM295.134%2094.13H267.344C267.391%2097.863%20268.324%20101.037%20270.144%20103.65C272.337%20106.777%20275.371%20108.34%20279.244%20108.34C285.217%20108.34%20288.997%20105.26%20290.584%2099.1H294.994C292.987%20107.733%20287.737%20112.05%20279.244%20112.05C273.831%20112.05%20269.677%20110.16%20266.784%20106.38C264.217%20102.973%20262.934%2098.493%20262.934%2092.94C262.934%2087.667%20264.217%2083.28%20266.784%2079.78C269.724%2075.813%20273.877%2073.83%20279.244%2073.83C284.704%2073.83%20288.857%2075.953%20291.704%2080.2C294.177%2083.887%20295.321%2088.53%20295.134%2094.13ZM267.344%2090.42H290.724C290.631%2086.873%20289.581%2083.887%20287.574%2081.46C285.427%2078.847%20282.651%2077.54%20279.244%2077.54C275.837%2077.54%20273.037%2078.87%20270.844%2081.53C268.884%2083.863%20267.717%2086.827%20267.344%2090.42ZM328.843%2085.45H324.433C324.34%2082.837%20323.36%2080.83%20321.493%2079.43C319.813%2078.17%20317.643%2077.54%20314.983%2077.54C312.696%2077.54%20310.783%2077.983%20309.243%2078.87C307.376%2079.99%20306.443%2081.623%20306.443%2083.77C306.443%2086.71%20308.94%2088.74%20313.933%2089.86L319.813%2091.19C326.673%2092.73%20330.103%2096.067%20330.103%20101.2C330.103%20104.793%20328.54%20107.57%20325.413%20109.53C322.706%20111.21%20319.44%20112.05%20315.613%20112.05C306.373%20112.05%20301.426%20107.803%20300.773%2099.31H305.183C305.37%20102.203%20306.42%20104.443%20308.333%20106.03C310.293%20107.57%20312.79%20108.34%20315.823%20108.34C318.296%20108.34%20320.466%20107.827%20322.333%20106.8C324.573%20105.54%20325.693%20103.767%20325.693%20101.48C325.693%2098.26%20323.056%2096.067%20317.783%2094.9L312.113%2093.64C308.846%2092.893%20306.443%2091.89%20304.903%2090.63C302.99%2089.043%20302.033%2086.827%20302.033%2083.98C302.033%2080.573%20303.503%2077.96%20306.443%2076.14C308.916%2074.6%20311.973%2073.83%20315.613%2073.83C319.393%2073.83%20322.473%2074.787%20324.853%2076.7C327.373%2078.753%20328.703%2081.67%20328.843%2085.45ZM364.294%2085.45H359.884C359.791%2082.837%20358.811%2080.83%20356.944%2079.43C355.264%2078.17%20353.094%2077.54%20350.434%2077.54C348.147%2077.54%20346.234%2077.983%20344.694%2078.87C342.827%2079.99%20341.894%2081.623%20341.894%2083.77C341.894%2086.71%20344.391%2088.74%20349.384%2089.86L355.264%2091.19C362.124%2092.73%20365.554%2096.067%20365.554%20101.2C365.554%20104.793%20363.991%20107.57%20360.864%20109.53C358.157%20111.21%20354.891%20112.05%20351.064%20112.05C341.824%20112.05%20336.877%20107.803%20336.224%2099.31H340.634C340.821%20102.203%20341.871%20104.443%20343.784%20106.03C345.744%20107.57%20348.241%20108.34%20351.274%20108.34C353.747%20108.34%20355.917%20107.827%20357.784%20106.8C360.024%20105.54%20361.144%20103.767%20361.144%20101.48C361.144%2098.26%20358.507%2096.067%20353.234%2094.9L347.564%2093.64C344.297%2092.893%20341.894%2091.89%20340.354%2090.63C338.441%2089.043%20337.484%2086.827%20337.484%2083.98C337.484%2080.573%20338.954%2077.96%20341.894%2076.14C344.367%2074.6%20347.424%2073.83%20351.064%2073.83C354.844%2073.83%20357.924%2074.787%20360.304%2076.7C362.824%2078.753%20364.154%2081.67%20364.294%2085.45Z'%20fill='white'/%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_d_30_1933'%20x='0'%20y='0'%20width='380'%20height='130'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dy='4'/%3e%3cfeGaussianBlur%20stdDeviation='7'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='out'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.15%200'/%3e%3cfeBlend%20mode='normal'%20in2='BackgroundImageFix'%20result='effect1_dropShadow_30_1933'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='effect1_dropShadow_30_1933'%20result='shape'/%3e%3c/filter%3e%3cclipPath%20id='clip0_30_1933'%3e%3crect%20width='352'%20height='102'%20fill='white'%20transform='translate(14%2010)'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='738'%20height='346'%20viewBox='0%200%20738%20346'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M166.531%20110.373V111.304L158.082%20116.188L158.071%20115.256L166.531%20110.373Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M162.346%20110.647V111.578L158.071%20114.043V113.123L162.346%20110.647Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M159.716%20109.501L159.727%20110.433L158.06%20111.387V110.455L159.716%20109.501Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M158.648%20121.324C158.485%20121.68%20158.4%20122.067%20158.399%20122.459V134.554C158.399%20135.508%20159.079%20135.894%20159.907%20135.406L177.916%20124.992C178.352%20124.709%20178.714%20124.326%20178.974%20123.877C179.234%20123.427%20179.385%20122.922%20179.413%20122.403V110.319C179.423%20110.026%20179.335%20109.739%20179.164%20109.501L168.957%20122.437L158.648%20121.324Z'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M159.894%20119.821C159.346%20120.197%20158.911%20120.715%20158.635%20121.32L168.921%20122.387L179.128%20109.452C179.006%20109.325%20178.848%20109.238%20178.675%20109.206C178.502%20109.173%20178.323%20109.196%20178.164%20109.271L159.894%20119.821Z'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M182.85%20117.448L217.621%2097.3806V115.551'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M368.923%20155.802C382.01%20163.366%20382.078%20175.642%20369.07%20183.206L307.977%20218.741C294.969%20226.315%20273.818%20226.315%20260.72%20218.741L199.264%20183.206C186.176%20175.642%20186.108%20163.366%20199.116%20155.802L260.175%20120.268C273.183%20112.693%20294.334%20112.693%20307.421%20120.268L368.923%20155.802Z'%20fill='%2379AEF5'/%3e%3cpath%20d='M369.066%20150.158L307.973%20185.693C294.965%20193.268%20273.814%20193.268%20260.715%20185.693L199.259%20150.158C192.67%20146.354%20189.381%20141.357%20189.393%20136.36V143.435C189.393%20148.421%20192.67%20153.429%20199.259%20157.234L260.738%20192.78C273.825%20200.343%20294.987%20200.343%20307.995%20192.78L369.054%20157.245C375.507%20153.486%20378.751%20148.568%20378.762%20143.617V136.542C378.762%20141.482%20375.53%20146.399%20369.066%20150.158Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M368.923%20122.754C382.01%20130.317%20382.078%20142.594%20369.07%20150.157L307.977%20185.692C294.969%20193.267%20273.818%20193.267%20260.72%20185.692L199.264%20150.157C186.176%20142.594%20186.108%20130.317%20199.116%20122.754L260.175%2087.2192C273.183%2079.6444%20294.334%2079.6444%20307.421%2087.2192L368.923%20122.754Z'%20fill='white'/%3e%3cpath%20d='M179.53%20276.419C192.617%20283.983%20192.685%20296.259%20179.677%20303.834L118.584%20339.358C105.576%20346.932%2084.4257%20346.932%2071.3384%20339.358L9.87097%20303.834C-3.21637%20296.259%20-3.28442%20283.994%209.72354%20276.419L70.7827%20240.885C83.7906%20233.321%20104.941%20233.321%20118.04%20240.885L179.53%20276.419Z'%20fill='%2379AEF5'/%3e%3cpath%20d='M179.673%20270.775L118.58%20306.344C105.572%20313.919%2084.4213%20313.919%2071.334%20306.344L9.86657%20270.821C3.27754%20267.005%20-0.0113116%20262.008%202.9229e-05%20257.011V264.086C2.9229e-05%20269.083%203.27754%20274.08%209.85523%20277.884L71.3226%20313.419C84.41%20320.994%20105.572%20320.994%20118.58%20313.419L179.639%20277.884C186.092%20274.125%20189.336%20269.208%20189.347%20264.256V257.181C189.381%20262.053%20186.137%20267.016%20179.673%20270.775Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M179.525%20243.37C192.613%20250.933%20192.681%20263.21%20179.673%20270.773L118.58%20306.342C105.572%20313.917%2084.4209%20313.917%2071.3336%20306.342L9.86621%20270.819C-3.18711%20263.187%20-3.25515%20250.933%209.70744%20243.37L70.7666%20207.835C83.7745%20200.26%20104.925%20200.26%20118.024%20207.835L179.525%20243.37Z'%20fill='white'/%3e%3cpath%20d='M561.71%20254.942C574.798%20262.506%20574.866%20274.782%20561.858%20282.357L500.765%20317.881C487.757%20325.456%20466.606%20325.456%20453.519%20317.881L392.051%20282.357C378.964%20274.782%20378.896%20262.517%20391.904%20254.942L452.963%20219.408C465.971%20211.844%20487.122%20211.844%20500.22%20219.408L561.71%20254.942Z'%20fill='%2379AEF5'/%3e%3cpath%20d='M561.861%20249.299L500.768%20284.834C487.76%20292.409%20466.609%20292.409%20453.522%20284.834L392.054%20249.311C385.465%20245.495%20382.176%20240.498%20382.188%20235.501V242.576C382.188%20247.573%20385.465%20252.57%20392.043%20256.375L453.51%20291.909C466.598%20299.484%20487.76%20299.484%20500.768%20291.909L561.849%20256.375C568.302%20252.616%20571.546%20247.698%20571.557%20242.747V235.672C571.557%20240.623%20568.325%20245.54%20561.861%20249.299Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M561.71%20221.895C574.798%20229.459%20574.866%20241.735%20561.858%20249.299L500.765%20284.833C487.757%20292.408%20466.606%20292.408%20453.519%20284.833L392.051%20249.31C378.964%20241.735%20378.896%20229.459%20391.904%20221.895L452.963%20186.36C465.971%20178.785%20487.122%20178.785%20500.22%20186.36L561.71%20221.895Z'%20fill='white'/%3e%3cpath%20opacity='0.43'%20d='M499.163%20269.382L514.995%20269.268L547.963%20250.666L529.681%20241.66L499.163%20269.382Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M727.582%20144.647C740.669%20152.21%20740.749%20164.487%20727.741%20172.05L666.636%20207.539C653.628%20215.114%20632.478%20215.114%20619.39%20207.539L557.923%20172.005C544.836%20164.441%20544.768%20152.165%20557.775%20144.601L618.835%20109.066C631.843%20101.492%20652.993%20101.492%20666.092%20109.066L727.582%20144.647Z'%20fill='%2379AEF5'/%3e%3cpath%20d='M727.709%20139.004L666.639%20174.538C653.631%20182.113%20632.48%20182.113%20619.393%20174.538L557.925%20139.004C551.336%20135.199%20548.048%20130.202%20548.059%20125.205V132.28C548.059%20137.266%20551.336%20142.263%20557.925%20146.079L619.382%20181.614C632.469%20189.177%20653.631%20189.177%20666.639%20181.614L727.698%20146.079C734.162%20142.32%20737.394%20137.391%20737.406%20132.451V125.387C737.406%20130.316%20734.162%20135.245%20727.709%20139.004Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M727.585%20111.591C740.673%20119.166%20740.752%20131.443%20727.744%20139.006L666.674%20174.541C653.666%20182.116%20632.515%20182.116%20619.428%20174.541L557.96%20139.006C544.873%20131.443%20544.805%20119.166%20557.813%20111.603L618.872%2076.0681C631.88%2068.4933%20653.031%2068.4933%20666.129%2076.0681L727.585%20111.591Z'%20fill='white'/%3e%3cpath%20d='M188.892%20167.791L116.878%20126.158C114.281%20124.659%20111.922%20124.511%20110.209%20125.511L106.002%20128.043C107.703%20127.055%20110.062%20127.191%20112.67%20128.702L184.673%20170.335C189.845%20173.322%20194.018%20180.556%20194.007%20186.507L193.882%20228.924C193.882%20231.876%20192.839%20233.955%20191.149%20234.931L195.379%20232.467C197.058%20231.49%20198.101%20229.412%20198.112%20226.459L198.226%20184.042C198.248%20178.069%20194.075%20170.823%20188.892%20167.791Z'%20fill='%23C8F3FF'/%3e%3cpath%20d='M184.677%20170.305C189.848%20173.292%20194.022%20180.526%20194.01%20186.477L193.886%20228.894C193.886%20234.833%20189.667%20237.229%20184.495%20234.242L112.492%20192.609C107.321%20189.622%20103.136%20182.388%20103.159%20176.437L103.272%20134.021C103.272%20128.07%20107.502%20125.685%20112.674%20128.672L184.677%20170.305Z'%20fill='%235C6BC0'/%3e%3cpath%20d='M114.142%20165.041L121.426%20150.951L123.13%20151.834L119.886%20158.109L127.389%20161.998L130.632%20155.723L132.336%20156.606L125.053%20170.697L123.349%20169.813L126.607%20163.511L119.104%20159.622L115.846%20165.925L114.142%20165.041Z'%20fill='white'/%3e%3cpath%20d='M137.451%20159.257L130.168%20173.348L128.464%20172.465L135.747%20158.374L137.451%20159.257Z'%20fill='white'/%3e%3cpath%20d='M133.585%20175.119L140.868%20161.028L145.622%20163.493C146.722%20164.062%20147.527%20164.718%20148.038%20165.46C148.551%20166.197%20148.809%20166.979%20148.811%20167.806C148.813%20168.633%20148.6%20169.462%20148.171%20170.292C147.742%20171.122%20147.192%20171.77%20146.521%20172.237C145.85%20172.703%20145.069%20172.938%20144.179%20172.942C143.291%20172.941%20142.302%20172.658%20141.212%20172.093L137.364%20170.099L138.161%20168.558L141.953%20170.524C142.704%20170.913%20143.366%20171.116%20143.938%20171.134C144.514%20171.153%20145.01%20171.015%20145.424%20170.718C145.846%20170.419%20146.203%20169.987%20146.494%20169.423C146.786%20168.859%20146.936%20168.311%20146.943%20167.78C146.95%20167.249%20146.782%20166.749%20146.438%20166.279C146.096%20165.806%20145.545%20165.372%20144.785%20164.978L141.789%20163.425L135.288%20176.002L133.585%20175.119ZM143.48%20172.222L143.671%20180.347L141.692%20179.321L141.556%20171.225L143.48%20172.222Z'%20fill='white'/%3e%3cpath%20d='M154.947%20168.326L147.664%20182.417L145.96%20181.533L153.243%20167.443L154.947%20168.326Z'%20fill='white'/%3e%3cpath%20d='M169.522%20175.88L162.238%20189.971L160.589%20189.116L158.64%20174.079L158.503%20174.007L152.784%20185.071L151.081%20184.187L158.364%20170.097L160.013%20170.952L161.975%20186.031L162.113%20186.102L167.845%20175.011L169.522%20175.88Z'%20fill='white'/%3e%3cpath%20d='M180.274%20187.036C180.362%20186.495%20180.378%20185.977%20180.32%20185.481C180.269%20184.984%20180.142%20184.517%20179.938%20184.08C179.739%20183.645%20179.462%20183.248%20179.107%20182.89C178.752%20182.531%20178.321%20182.221%20177.812%20181.957C176.978%20181.525%20176.109%20181.348%20175.204%20181.425C174.298%20181.502%20173.427%20181.856%20172.59%20182.487C171.753%20183.117%20171.02%20184.042%20170.389%20185.263C169.758%20186.483%20169.43%20187.618%20169.404%20188.669C169.377%20189.719%20169.601%20190.641%20170.074%20191.433C170.548%20192.225%20171.219%20192.846%20172.09%20193.297C172.896%20193.715%20173.695%20193.911%20174.486%20193.885C175.285%20193.857%20176.02%20193.616%20176.69%20193.161C177.368%20192.704%20177.93%20192.044%20178.375%20191.182L178.841%20191.562L174.608%20189.369L175.391%20187.855L180.75%20190.633L179.967%20192.146C179.368%20193.307%20178.599%20194.188%20177.661%20194.789C176.727%20195.393%20175.705%20195.707%20174.596%20195.73C173.493%20195.752%20172.382%20195.473%20171.265%20194.894C170.019%20194.248%20169.076%20193.387%20168.436%20192.311C167.8%20191.237%20167.499%20190.022%20167.532%20188.667C167.569%20187.314%20167.972%20185.894%20168.74%20184.408C169.316%20183.293%20169.983%20182.368%20170.741%20181.633C171.505%20180.895%20172.325%20180.354%20173.199%20180.011C174.074%20179.667%20174.973%20179.523%20175.897%20179.577C176.822%20179.632%20177.735%20179.893%20178.637%20180.361C179.379%20180.745%20180.013%20181.216%20180.538%20181.773C181.07%20182.328%20181.482%20182.94%20181.775%20183.61C182.075%20184.277%20182.249%20184.981%20182.296%20185.72C182.346%20186.456%20182.258%20187.198%20182.033%20187.948L180.274%20187.036Z'%20fill='white'/%3e%3cpath%20d='M291.119%20297.896C292.922%20298.941%20292.934%20300.633%20291.119%20301.678L279.619%20308.39C278.614%20308.905%20277.5%20309.174%20276.37%20309.174C275.24%20309.174%20274.127%20308.905%20273.121%20308.39L261.474%20301.678C259.671%20300.633%20259.659%20298.941%20261.474%20297.896L273.019%20291.184C274.025%20290.669%20275.138%20290.4%20276.268%20290.4C277.398%20290.4%20278.512%20290.669%20279.517%20291.184L291.119%20297.896Z'%20fill='white'/%3e%3cg%20opacity='0.29'%3e%3cpath%20d='M266.168%20283.475C267.971%20284.519%20267.982%20286.2%20266.168%20287.245L254.668%20293.968C253.662%20294.483%20252.549%20294.752%20251.419%20294.752C250.289%20294.752%20249.176%20294.483%20248.17%20293.968L236.523%20287.245C234.72%20286.2%20234.708%20284.519%20236.523%20283.475L248.045%20276.82C249.051%20276.304%20250.165%20276.036%20251.294%20276.036C252.424%20276.036%20253.538%20276.304%20254.543%20276.82L266.168%20283.475Z'%20fill='white'/%3e%3c/g%3e%3cpath%20d='M265.479%20260.52C267.282%20261.565%20267.282%20263.257%20265.479%20264.29L253.934%20271.013C252.926%20271.529%20251.811%20271.797%20250.679%20271.797C249.548%20271.797%20248.432%20271.529%20247.424%20271.013L235.834%20264.324C234.031%20263.291%20234.019%20261.599%20235.834%20260.554L247.379%20253.842C248.385%20253.327%20249.498%20253.058%20250.628%20253.058C251.758%20253.058%20252.871%20253.327%20253.877%20253.842L265.479%20260.52Z'%20fill='%2358AFFB'/%3e%3cpath%20d='M330.119%20297.896C331.922%20298.94%20331.933%20300.633%20330.119%20301.677L318.574%20308.389C317.568%20308.904%20316.454%20309.173%20315.325%20309.173C314.195%20309.173%20313.081%20308.904%20312.075%20308.389L300.451%20301.666C298.648%20300.632%20298.637%20298.94%20300.451%20297.896L311.996%20291.172C313.003%20290.662%20314.116%20290.397%20315.245%20290.397C316.374%20290.397%20317.487%20290.662%20318.494%20291.172L330.119%20297.896Z'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M266.328%20312.022C268.131%20313.067%20268.142%20314.747%20266.328%20315.792L254.783%20322.504C253.777%20323.019%20252.663%20323.288%20251.534%20323.288C250.404%20323.288%20249.29%20323.019%20248.284%20322.504L236.66%20315.792C234.857%20314.747%20234.857%20313.055%20236.66%20312.022L248.205%20305.299C249.212%20304.789%20250.325%20304.523%20251.454%20304.523C252.583%20304.523%20253.696%20304.789%20254.703%20305.299L266.328%20312.022Z'%20fill='%2358AFFB'/%3e%3cpath%20d='M473.363%20111.794C475.177%20112.839%20475.177%20114.52%20473.363%20115.565L461.818%20122.288C460.811%20122.8%20459.698%20123.068%20458.569%20123.068C457.439%20123.068%20456.326%20122.8%20455.319%20122.288L443.718%20115.553C441.926%20114.508%20441.915%20112.828%20443.718%20111.783L455.263%20105.06C456.271%20104.547%20457.386%20104.28%20458.518%20104.28C459.649%20104.28%20460.764%20104.547%20461.772%20105.06L473.363%20111.794Z'%20fill='white'/%3e%3cg%20opacity='0.29'%3e%3cpath%20d='M448.416%2097.3849C450.219%2098.4184%20450.23%20100.111%20448.416%20101.155L436.871%20107.878C435.863%20108.388%20434.751%20108.654%20433.622%20108.654C432.493%20108.654%20431.38%20108.388%20430.373%20107.878L418.748%20101.155C416.945%20100.111%20416.945%2098.4184%20418.748%2097.3849L430.293%2090.6618C431.301%2090.1464%20432.416%2089.8777%20433.548%2089.8777C434.68%2089.8777%20435.795%2090.1464%20436.803%2090.6618L448.416%2097.3849Z'%20fill='white'/%3e%3c/g%3e%3cpath%20d='M447.727%2074.4206C449.53%2075.4654%20449.542%2077.1462%20447.727%2078.191L436.205%2084.8913C435.199%2085.4067%20434.085%2085.6754%20432.956%2085.6754C431.826%2085.6754%20430.712%2085.4067%20429.706%2084.8913L418.082%2078.1796C416.279%2077.1348%20416.268%2075.454%20418.082%2074.4092L429.627%2067.6861C430.634%2067.1761%20431.747%2066.9104%20432.876%2066.9104C434.005%2066.9104%20435.118%2067.1761%20436.125%2067.6861L447.727%2074.4206Z'%20fill='%2358AFFB'/%3e%3cg%20opacity='0.26'%3e%3cpath%20d='M512.378%20111.797C514.17%20112.842%20514.182%20114.522%20512.378%20115.567L500.833%20122.29C499.825%20122.803%20498.71%20123.07%20497.579%20123.07C496.448%20123.07%20495.332%20122.803%20494.324%20122.29L482.722%20115.556C480.919%20114.511%20480.908%20112.83%20482.722%20111.785L494.267%20105.062C495.273%20104.547%20496.386%20104.278%20497.516%20104.278C498.646%20104.278%20499.76%20104.547%20500.765%20105.062L512.378%20111.797Z'%20fill='white'/%3e%3c/g%3e%3cpath%20d='M448.598%20125.885C450.413%20126.929%20450.413%20128.622%20448.598%20129.655L437.053%20136.378C436.048%20136.893%20434.934%20137.162%20433.804%20137.162C432.674%20137.162%20431.561%20136.893%20430.555%20136.378L418.931%20129.655C417.139%20128.622%20417.128%20126.929%20418.931%20125.885L430.453%20119.173C431.459%20118.658%20432.572%20118.389%20433.702%20118.389C434.832%20118.389%20435.946%20118.658%20436.951%20119.173L448.598%20125.885Z'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M659.707%20269.092C661.511%20270.137%20661.522%20271.817%20659.707%20272.862L648.196%20279.574C647.189%20280.089%20646.073%20280.358%20644.942%20280.358C643.81%20280.358%20642.695%20280.089%20641.687%20279.574L630.051%20272.862C628.248%20271.817%20628.237%20270.125%20630.051%20269.092L641.596%20262.369C642.602%20261.853%20643.715%20261.585%20644.845%20261.585C645.975%20261.585%20647.089%20261.853%20648.094%20262.369L659.707%20269.092Z'%20fill='white'/%3e%3cg%20opacity='0.29'%3e%3cpath%20d='M634.761%20254.66C636.564%20255.705%20636.576%20257.397%20634.761%20258.442L623.25%20265.154C622.244%20265.669%20621.131%20265.938%20620.001%20265.938C618.871%20265.938%20617.758%20265.669%20616.752%20265.154L605.105%20258.442C603.302%20257.397%20603.29%20255.705%20605.105%20254.66L616.65%20247.949C617.655%20247.433%20618.769%20247.165%20619.899%20247.165C621.029%20247.165%20622.142%20247.433%20623.148%20247.949L634.761%20254.66Z'%20fill='white'/%3e%3c/g%3e%3cpath%20d='M634.071%20231.709C635.874%20232.754%20635.874%20234.446%20634.071%20235.48L622.526%20242.203C621.518%20242.718%20620.403%20242.987%20619.271%20242.987C618.139%20242.987%20617.024%20242.718%20616.016%20242.203L604.426%20235.48C602.623%20234.446%20602.611%20232.754%20604.426%20231.709L615.971%20224.997C616.977%20224.482%20618.09%20224.213%20619.22%20224.213C620.35%20224.213%20621.463%20224.482%20622.469%20224.997L634.071%20231.709Z'%20fill='%2358AFFB'/%3e%3cg%20opacity='0.26'%3e%3cpath%20d='M698.708%20269.094C700.511%20270.127%20700.523%20271.819%20698.708%20272.864L687.163%20279.576C686.157%20280.091%20685.044%20280.36%20683.914%20280.36C682.784%20280.36%20681.671%20280.091%20680.665%20279.576L669.041%20272.853C667.237%20271.819%20667.215%20270.127%20669.041%20269.082L680.586%20262.371C681.591%20261.855%20682.705%20261.587%20683.835%20261.587C684.964%20261.587%20686.078%20261.855%20687.084%20262.371L698.708%20269.094Z'%20fill='white'/%3e%3c/g%3e%3cpath%20d='M634.916%20283.189C636.72%20284.234%20636.731%20285.914%20634.916%20286.959L623.371%20293.682C622.364%20294.192%20621.251%20294.458%20620.122%20294.458C618.993%20294.458%20617.881%20294.192%20616.873%20293.682L605.249%20286.959C603.446%20285.914%20603.446%20284.222%20605.249%20283.189L616.794%20276.466C617.801%20275.956%20618.914%20275.69%20620.043%20275.69C621.172%20275.69%20622.285%20275.956%20623.292%20276.466L634.916%20283.189Z'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M561.176%2037.9307L561.232%2058.3498L558.919%2059.6899L558.885%2050.1163L550.311%2055.0791L550.334%2064.6527L548.043%2065.9814L547.986%2045.5623L550.277%2044.2336L550.3%2052.7737L558.885%2047.8109L558.862%2039.2708L561.176%2037.9307Z'%20fill='white'/%3e%3cpath%20d='M567.436%2034.321L567.493%2054.7288L565.213%2056.0462L565.145%2035.6384L567.436%2034.321Z'%20fill='white'/%3e%3cpath%20d='M581.673%2040.9289C581.954%2042.5768%20582.418%2044.1881%20583.057%2045.7328L580.686%2047.1069C580.127%2045.7614%20579.728%2044.355%20579.496%2042.9163C578.951%2040.4065%20577.999%2039.8955%20575.923%2040.9971L573.769%2042.2463V51.0931L571.5%2052.4104V32.2752C572.892%2031.1793%20574.362%2030.1885%20575.901%2029.3111C578.35%2027.8916%20579.927%2027.4941%20581.027%2028.0051C581.934%2028.4026%20582.433%2029.5042%20582.433%2031.0714C582.362%2032.4286%20582.024%2033.7584%20581.438%2034.9843C580.852%2036.2102%20580.03%2037.308%20579.019%2038.2147V38.3283C580.426%2038.0671%20581.288%2039.0437%20581.673%2040.9289ZM576.105%2038.8961C577.26%2038.2922%20578.239%2037.3999%20578.948%2036.3056C579.658%2035.2113%20580.073%2033.9521%20580.153%2032.65C580.153%2030.0152%20578.486%2029.8335%20576.059%2031.1963C575.256%2031.6417%20574.496%2032.1626%20573.791%2032.7522V40.2021L576.139%2038.8507'%20fill='white'/%3e%3cpath%20d='M595.179%2018.2722L595.19%2020.4868L587.898%2024.7001L587.92%2031.1506L594.816%2027.1644V29.3449L587.932%2033.3311L587.943%2040.6901L595.632%2036.2497V38.4642L585.664%2044.222L585.596%2023.8142L595.179%2018.2722Z'%20fill='white'/%3e%3cpath%20d='M610.61%2011.7433C612.198%2012.5042%20613.128%2014.3326%20613.128%2017.6374C613.14%2020.9419%20612.266%2024.1891%20610.599%2027.0406C608.677%2030.172%20605.977%2032.7507%20602.762%2034.5246C601.141%2035.4559%20599.768%2036.16%20598.612%2036.6824V16.6039C600.166%2015.4264%20601.79%2014.3455%20603.477%2013.3673C606.709%2011.4594%20609.057%2010.9824%20610.61%2011.7433ZM603.205%2032.1852C605.54%2030.9088%20607.48%2029.0148%20608.814%2026.7098C610.148%2024.4048%20610.824%2021.7773%20610.769%2019.1137C610.769%2014.2758%20608.41%2012.5951%20603.568%2015.3888C602.626%2015.9243%20601.728%2016.5318%20600.88%2017.2058V33.3208C601.663%2032.9985%20602.421%2032.6189%20603.148%2032.1852'%20fill='white'/%3e%3cpath%20d='M58.2918%20176.574V178.152C58.2937%20178.364%2058.3509%20178.572%2058.4576%20178.755C58.5644%20178.938%2058.717%20179.09%2058.9004%20179.195C59.0838%20179.301%2059.2915%20179.357%2059.5031%20179.357C59.7146%20179.357%2059.9226%20179.302%2060.1064%20179.197L67.5573%20174.905C67.7404%20174.799%2067.8924%20174.646%2067.9979%20174.463C68.1034%20174.279%2068.1588%20174.071%2068.1584%20173.86V172.338C68.166%20172.128%2068.1192%20171.92%2068.0225%20171.733C67.9258%20171.547%2067.7825%20171.389%2067.6066%20171.274C67.4307%20171.16%2067.2281%20171.093%2067.0187%20171.081C66.8094%20171.068%2066.6003%20171.11%2066.4119%20171.202L58.961%20175.506C58.7626%20175.606%2058.5954%20175.758%2058.4774%20175.947C58.3594%20176.135%2058.2952%20176.352%2058.2918%20176.574Z'%20fill='%23F2F9FF'/%3e%3cpath%20d='M34.6559%20197.957V199.592C34.6569%20199.803%2034.7128%20200.01%2034.8182%20200.193C34.9235%20200.376%2035.0746%20200.528%2035.2566%20200.635C35.4387%20200.742%2035.6453%20200.799%2035.8561%20200.801C36.067%20200.804%2036.2748%20200.751%2036.459%20200.648L67.5443%20182.762C67.7274%20182.656%2067.8794%20182.503%2067.9849%20182.32C68.0904%20182.136%2068.1458%20181.928%2068.1454%20181.717V180.138C68.1478%20179.926%2068.094%20179.716%2067.9895%20179.531C67.8849%20179.347%2067.7334%20179.193%2067.5503%20179.085C67.3671%20178.978%2067.1589%20178.921%2066.9467%20178.921C66.7345%20178.92%2066.5259%20178.976%2066.3422%20179.082L35.2909%20196.912C35.1015%20197.013%2034.9427%20197.164%2034.831%20197.347C34.7193%20197.531%2034.6588%20197.742%2034.6559%20197.957Z'%20fill='%23F2F9FF'/%3e%3cg%20opacity='0.53'%3e%3cpath%20d='M47.4966%20206.339V207.917C47.4962%20208.129%2047.5515%20208.336%2047.6568%20208.52C47.7622%20208.703%2047.9139%20208.855%2048.0967%20208.961C48.2795%20209.067%2048.487%20209.123%2048.6982%20209.123C48.9094%20209.123%2049.1169%20209.068%2049.2998%20208.962L67.5472%20198.457C67.7374%20198.359%2067.8958%20198.208%2068.0042%20198.023C68.1126%20197.838%2068.1665%20197.626%2068.1597%20197.412V195.822C68.1601%20195.611%2068.1048%20195.403%2067.9995%20195.22C67.8941%20195.036%2067.7424%20194.884%2067.5596%20194.778C67.3768%20194.672%2067.1693%20194.616%2066.9581%20194.616C66.7469%20194.616%2066.5394%20194.672%2066.3565%20194.778L48.0977%20205.271C47.9112%20205.379%2047.7571%20205.535%2047.6513%20205.722C47.5456%20205.91%2047.4922%20206.123%2047.4966%20206.339Z'%20fill='%23F2F9FF'/%3e%3c/g%3e%3cpath%20d='M39.5103%20203.054V204.633C39.5113%20204.844%2039.5672%20205.051%2039.6726%20205.234C39.7779%20205.417%2039.929%20205.569%2040.1111%20205.676C40.2931%20205.782%2040.4997%20205.84%2040.7105%20205.842C40.9214%20205.844%2041.1292%20205.791%2041.3135%20205.689L67.5448%20190.63C67.7288%20190.522%2067.8812%20190.368%2067.9867%20190.183C68.0923%20189.997%2068.1471%20189.787%2068.1459%20189.574V187.995C68.1449%20187.784%2068.089%20187.577%2067.9836%20187.394C67.8783%20187.211%2067.7271%20187.059%2067.5451%20186.952C67.3631%20186.846%2067.1565%20186.788%2066.9456%20186.786C66.7348%20186.784%2066.527%20186.836%2066.3427%20186.939L40.1113%20202.009C39.9282%20202.115%2039.7763%20202.267%2039.6707%20202.451C39.5652%20202.634%2039.5099%20202.842%2039.5103%20203.054Z'%20fill='%23F2F9FF'/%3e%3cpath%20d='M8.80978%20208.234V229.448L24.8004%20239.851'%20stroke='white'%20stroke-width='0.53'%20stroke-miterlimit='10'/%3e%3cpath%20d='M8.71457%20208.631C9.76055%20208.631%2010.6085%20207.782%2010.6085%20206.735C10.6085%20205.687%209.76055%20204.838%208.71457%20204.838C7.66858%20204.838%206.82065%20205.687%206.82065%20206.735C6.82065%20207.782%207.66858%20208.631%208.71457%20208.631Z'%20stroke='white'%20stroke-width='1.06'%20stroke-miterlimit='10'/%3e%3cpath%20d='M386.505%20197.436V218.638L402.484%20229.052'%20stroke='white'%20stroke-width='0.53'%20stroke-miterlimit='10'/%3e%3cpath%20d='M386.406%20197.821C387.452%20197.821%20388.3%20196.972%20388.3%20195.925C388.3%20194.877%20387.452%20194.028%20386.406%20194.028C385.36%20194.028%20384.512%20194.877%20384.512%20195.925C384.512%20196.972%20385.36%20197.821%20386.406%20197.821Z'%20stroke='white'%20stroke-width='1.06'%20stroke-miterlimit='10'/%3e%3cpath%20opacity='0.35'%20d='M249.201%20154.586C259.943%20154.586%20268.651%20149.044%20268.651%20142.208C268.651%20135.371%20259.943%20129.829%20249.201%20129.829C238.46%20129.829%20229.752%20135.371%20229.752%20142.208C229.752%20149.044%20238.46%20154.586%20249.201%20154.586Z'%20fill='%23A6D0F4'/%3e%3cpath%20opacity='0.35'%20d='M258.559%20155.143C258.559%20158.959%20263.424%20162.048%20269.412%20162.048C275.4%20162.048%20280.265%20158.959%20280.265%20155.143C280.265%20151.327%20275.411%20148.238%20269.412%20148.238C263.413%20148.238%20258.559%20151.327%20258.559%20155.143Z'%20fill='%23A6D0F4'/%3e%3cpath%20opacity='0.35'%20d='M302.642%20131.248C302.642%20135.064%20307.507%20138.153%20313.495%20138.153C319.483%20138.153%20324.348%20135.064%20324.348%20131.248C324.348%20127.432%20319.494%20124.332%20313.495%20124.332C307.496%20124.332%20302.642%20127.432%20302.642%20131.248Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M260.79%20140.663C260.564%20143.218%20258.171%20144.944%20256.005%20145.875C253.633%20146.854%20251.084%20147.329%20248.52%20147.272C245.889%20147.278%20243.29%20146.7%20240.91%20145.58C238.857%20144.569%20236.691%20142.741%20236.691%20140.242C236.594%20141.088%20236.671%20141.944%20236.916%20142.758C237.162%20143.573%20237.572%20144.328%20238.12%20144.978C239.93%20146.723%20242.229%20147.872%20244.709%20148.272C249.359%20149.225%20255.676%20148.771%20259.203%20145.183C259.806%20144.534%20260.263%20143.764%20260.543%20142.923C260.823%20142.083%20260.919%20141.192%20260.824%20140.311L260.79%20140.663Z'%20fill='%23ADCDFC'/%3e%3cpath%20d='M257.252%20135.994C261.981%20138.731%20262.015%20143.16%20257.32%20145.897C254.682%20147.231%20251.769%20147.926%20248.814%20147.926C245.859%20147.926%20242.946%20147.231%20240.308%20145.897C235.579%20143.16%20235.557%20138.731%20240.308%20135.994C242.936%20134.667%20245.837%20133.976%20248.78%20133.976C251.723%20133.976%20254.624%20134.667%20257.252%20135.994Z'%20fill='white'/%3e%3cpath%20d='M250.044%20132.339L250.021%20142.401L248.762%20143.139L248.774%20133.077L250.044%20132.339Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M248.775%20133.077L248.764%20143.139L247.493%20142.401L247.505%20132.339L248.775%20133.077Z'%20fill='%237BAEFF'/%3e%3cpath%20d='M250.634%20130.51L248.786%20131.577L246.926%20130.51L248.774%20129.431L250.634%20130.51Z'%20fill='%234DA5DC'/%3e%3cpath%20d='M236.786%2096.247C236.786%2096.247%20232.987%2098.5183%20231.978%20100.79C230.968%20103.061%20231.24%20118.96%20236.514%20126.069C241.787%20133.179%20251.631%20134.144%20253.911%20133.133C256.19%20132.122%20269.278%20125.558%20270.287%20122.276C271.296%20118.994%20266.261%20116.473%20263.483%20115.212C260.704%20113.952%20258.946%20112.18%20257.438%20107.638C255.93%20103.095%20255.17%2095.2703%20253.401%2094.0097C251.631%2092.7491%20247.379%2090.7163%20236.786%2096.247Z'%20fill='%2325437F'/%3e%3cpath%20d='M255.614%20130.875C257.462%20130.057%20266.512%20125.537%20270.357%20122.119C271.162%20118.916%20266.252%20116.44%20263.552%20115.203C260.853%20113.965%20259.016%20112.17%20257.508%20107.628C255.999%20103.085%20255.24%2095.2604%20253.47%2093.9998C251.701%2092.7392%20247.426%2090.7177%20236.833%2096.2711C235.702%2096.9583%20234.642%2097.7572%20233.669%2098.656C232.717%20101.302%20233.057%20116.827%20238.262%20123.811C243.468%20130.795%20253.346%20131.885%20255.614%20130.875Z'%20fill='%23254DA1'/%3e%3cpath%20d='M245.804%2084.3226C245.594%2085.0765%20245.562%2085.8687%20245.71%2086.6372C245.857%2087.4056%20246.181%2088.1294%20246.654%2088.7517C248.129%2090.512%20247.845%2091.023%20247.562%2091.6363C247.278%2092.2495%20245.532%2094.2369%20245.736%2096.9739C245.94%2099.7108%20253.595%2098.4502%20254.298%2096.5537C255.001%2094.6571%20252.2%2091.5%20252.03%2089.1038C251.86%2086.7075%20253.504%2083.6185%20251.474%2082.8463C249.444%2082.074%20246.791%2081.4835%20245.804%2084.3226Z'%20fill='%23BB543E'/%3e%3cpath%20d='M267.259%20149.509C267.259%20149.509%20266.556%20151.428%20266.987%20151.996C267.317%20152.802%20267.505%20153.659%20267.542%20154.529L268.245%20154.949L268.529%20153.541C268.678%20154.157%20268.965%20154.732%20269.368%20155.221C270.774%20156.172%20272.348%20156.842%20274.007%20157.197C275.821%20157.618%20276.388%20157.481%20276.524%20156.777C276.66%20156.073%20274.562%20153.541%20273.303%20152.7C272.045%20151.86%20267.259%20149.509%20267.259%20149.509Z'%20fill='%23254DA1'/%3e%3cpath%20d='M271.375%20149.326C271.766%20150.155%20272.221%20150.952%20272.736%20151.711C273.303%20152.415%20274.845%20153.675%20274.698%20154.38C274.55%20155.084%20273.155%20154.947%20271.477%20154.38C269.798%20153.812%20269.367%20152.279%20268.528%20151.847C268.063%20151.686%20267.675%20151.357%20267.441%20150.924C267.206%20150.491%20267.14%20149.986%20267.258%20149.508C267.405%20148.054%20271.375%20149.326%20271.375%20149.326Z'%20fill='%23FF9554'/%3e%3cpath%20d='M263.743%20126.295C263.373%20125.609%20263.284%20124.805%20263.496%20124.054C263.708%20123.304%20264.203%20122.665%20264.877%20122.275C267.327%20120.901%20269.119%20123.036%20269.55%20124.035C270.549%20126.061%20271.157%20128.257%20271.342%20130.508C271.342%20133.166%20271.557%20149.701%20271.557%20149.701C271.268%20149.956%20270.93%20150.149%20270.563%20150.269C270.197%20150.389%20269.81%20150.434%20269.427%20150.4C269.043%20150.366%20268.67%20150.254%20268.33%20150.071C267.991%20149.889%20267.692%20149.639%20267.452%20149.337C267.452%20149.337%20265.047%20129.486%20264.991%20128.532C264.768%20127.694%20264.339%20126.925%20263.743%20126.295Z'%20fill='%23FF9554'/%3e%3cpath%20d='M263.141%20151.574C263.141%20151.574%20262.438%20153.493%20262.857%20154.05C263.195%20154.854%20263.387%20155.711%20263.424%20156.582L264.127%20157.003L264.411%20155.594C264.559%20156.215%20264.846%20156.793%20265.25%20157.287C266.651%20158.235%20268.223%20158.902%20269.877%20159.251C271.703%20159.671%20272.27%20159.535%20272.406%20158.831C272.542%20158.127%20270.444%20155.594%20269.174%20154.754C267.904%20153.914%20263.141%20151.574%20263.141%20151.574Z'%20fill='%23254DA1'/%3e%3cpath%20d='M256.94%20131.145C256.94%20131.145%20255.25%20128.703%20257.496%20127.011C259.741%20125.319%20261.805%20127.204%20262.361%20128.147C263.62%20130.024%20264.509%20132.125%20264.981%20134.336C265.355%20136.959%20267.249%20151.371%20267.249%20151.371C266.997%20151.662%20266.688%20151.9%20266.341%20152.068C265.994%20152.236%20265.617%20152.332%20265.232%20152.351C264.847%20152.369%20264.462%20152.308%20264.102%20152.173C263.741%20152.038%20263.411%20151.831%20263.132%20151.564C263.132%20151.564%20258.596%20134.132%20258.46%20133.189C258.13%20132.393%20257.608%20131.69%20256.94%20131.145Z'%20fill='%23FF9554'/%3e%3cpath%20d='M267.256%20151.383C267.642%20152.219%20268.097%20153.02%20268.617%20153.779C269.173%20154.472%20270.727%20155.744%20270.579%20156.448C270.432%20157.152%20269.037%20157.005%20267.358%20156.448C265.68%20155.892%20265.249%20154.336%20264.41%20153.916C263.945%20153.754%20263.557%20153.425%20263.322%20152.992C263.087%20152.56%20263.022%20152.055%20263.14%20151.576C263.287%20150.123%20267.256%20151.383%20267.256%20151.383Z'%20fill='%23FF9554'/%3e%3cpath%20d='M267.077%20120.46C266.397%20119.813%20258.47%20113.055%20258.47%20113.055L245.36%20115.111C245.36%20115.111%20245.553%20121.119%20248.762%20125.048C250.535%20127.298%20252.616%20129.286%20254.943%20130.953C255.65%20131.527%20256.487%20131.917%20257.381%20132.089C257.822%20131.055%20258.63%20130.221%20259.649%20129.75C261.611%20128.614%20268.212%20124.071%20269.051%20124.264C269.89%20124.457%20270.037%20124.821%20270.037%20124.821C269.41%20123.153%20268.395%20121.658%20267.077%20120.46Z'%20fill='%2362759A'/%3e%3cpath%20d='M257.026%2092.5215C257.026%2092.5215%20258.942%2092.6237%20260.054%2095.2471C261.165%2097.8704%20262.583%20104.548%20262.98%20105.161C263.377%20105.775%20262.889%20107.58%20260.462%20108.091C259.046%20106.268%20257.825%20104.3%20256.822%20102.22C255.313%2098.9947%20254.667%2093.9751%20257.026%2092.5215Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M249.241%2091.1594C249.241%2091.1594%20243.979%2094.9298%20243.458%2096.179C242.831%2098.5159%20242.991%20100.994%20243.911%20103.231C245.045%20105.503%20244.603%20114.088%20244.989%20115.724C245.374%20117.359%20249.876%20117.927%20252.666%20117.393C255.456%20116.859%20258.813%20114.827%20258.711%20111.579C258.609%20108.331%20258.144%20106.536%20259.845%2098.8592C260.163%2097.4169%20258.813%2095.668%20258.133%2093.1809C257.985%2092.6698%20256.239%2092.1247%20256.239%2092.1247C256.239%2092.1247%20254.413%2090.9436%20249.241%2091.1594Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M247.341%2094.2955C247.341%2094.2955%20242.805%2093.3869%20240.865%20100.383C239.663%20105.198%20238.518%20109.298%20239.187%20110.183C239.856%20111.069%20241.829%20111.875%20243.088%20110.853C244.347%20109.831%20248.101%2098.2589%20248.01%2097.1119C247.919%2095.9649%20248.305%2095.1131%20247.341%2094.2955Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M259.453%20100.109C259.453%20100.109%20257.537%20104.754%20248.351%20102.937C246.536%20102.835%20244.812%20106.98%20245.924%20109.206C247.119%20111.81%20247.866%20114.597%20248.135%20117.451C249.637%20117.696%20251.169%20117.696%20252.672%20117.451C255.45%20116.906%20258.818%20114.884%20258.716%20111.636C258.363%20107.83%20258.65%20103.991%20259.567%20100.279L259.453%20100.109Z'%20fill='%23A9C9E6'/%3e%3cpath%20d='M249.114%2090.9548C248.966%2091.0754%20248.852%2091.2312%20248.781%2091.4078C248.709%2091.5845%20248.683%2091.7762%20248.705%2091.9655C249.335%2093.4506%20250.325%2094.7545%20251.586%2095.7586C252.391%2096.1561%20253.242%2093.7825%20253.242%2093.7825C253.242%2093.7825%20254.966%2094.498%20255.567%2093.987C256.168%2093.4759%20254.512%2091.5567%20254.058%2091.2046C252.449%2090.7577%20250.76%2090.6724%20249.114%2090.9548Z'%20fill='white'/%3e%3cpath%20d='M253.811%2090.4542C253.797%2090.5101%20253.797%2090.5687%20253.811%2090.6246C253.868%2091.0107%20254.061%2091.9987%20254.095%2092.4076C254.129%2092.8164%20253.675%2093.4865%20252.62%2093.4637C251.566%2093.441%20249.74%2092.9981%20249.139%2091.7262C249.165%2090.4746%20249.109%2089.2225%20248.969%2087.9785L253.811%2090.4542Z'%20fill='%23FF8654'/%3e%3cpath%20d='M255.328%2084.0166C254.829%2081.3592%20252.731%2079.8488%20250.349%2080.4052C249.573%2080.5081%20248.832%2080.7905%20248.185%2081.2301C247.537%2081.6697%20247.001%2082.2544%20246.618%2082.9378C245.484%2085.2091%20247.162%2087.117%20248.24%2088.3208C248.693%2088.8091%20249.033%2089.1952%20249.249%2089.4564L249.487%2089.729C250.104%2090.3499%20250.863%2090.81%20251.699%2091.0691C252.194%2091.2405%20252.726%2091.2773%20253.24%2091.1755C253.754%2091.0737%20254.232%2090.8371%20254.624%2090.4899C255.305%2089.7858%20255.804%2086.6854%20255.328%2084.0166Z'%20fill='%23FF9554'/%3e%3cpath%20d='M248.186%2087.036C248.186%2087.036%20247.403%2085.9685%20246.825%2086.2524C246.246%2086.5363%20247.607%2088.8985%20248.481%2088.853C249.354%2088.8076%20248.186%2087.036%20248.186%2087.036Z'%20fill='%23FF9554'/%3e%3cpath%20d='M257.244%20114.688L266.657%20123.683L259.353%20127.76L249.952%20118.765L257.244%20114.688Z'%20fill='white'/%3e%3cpath%20d='M258.933%20116.767C258.6%20117.311%20258.312%20117.881%20258.071%20118.471C257.912%20118.993%20257.425%20119.981%20257.629%20120.254C257.833%20120.526%20258.525%20120.083%20258.661%20119.765C258.759%20119.577%20258.908%20119.419%20259.092%20119.311L259.183%20120.254C259.183%20120.833%20259.455%20122.071%20259.92%20122.298C260.385%20122.525%20261.054%20121.628%20261.383%20121.094C261.678%20120.306%20261.725%20119.446%20261.519%20118.63C261.337%20118.266%20260.85%20117.437%20260.85%20117.437L258.933%20116.767Z'%20fill='%23FF9554'/%3e%3cpath%20d='M259.208%20105.559C259.255%20105.191%20259.413%20104.845%20259.661%20104.569C259.908%20104.292%20260.234%20104.098%20260.595%20104.012C260.956%20103.925%20261.335%20103.951%20261.68%20104.086C262.026%20104.22%20262.323%20104.457%20262.531%20104.764C262.966%20105.401%20263.277%20106.114%20263.45%20106.865C263.949%20109.137%20261.646%20117.086%20261.42%20117.79C261.193%20118.495%20259.809%20118.824%20258.732%20117.927C257.654%20117.03%20259.174%20108.047%20259.174%20106.945C259.159%20106.483%20259.17%20106.02%20259.208%20105.559Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M252.571%20117.199C253.201%20117.287%20253.823%20117.424%20254.431%20117.608C254.93%20117.812%20256.008%20118.062%20256.087%20118.392C256.166%20118.721%20255.384%20118.982%20255.055%20118.891C254.851%20118.833%20254.635%20118.833%20254.431%20118.891L255.1%20119.55C255.509%20119.97%20256.336%20120.924%20256.234%20121.413C256.132%20121.901%20254.998%20121.867%20254.374%20121.787C253.582%20121.52%20252.89%20121.016%20252.39%20120.345C252.22%20119.97%20251.891%20119.05%20251.891%20119.05L252.571%20117.199Z'%20fill='%23FF9554'/%3e%3cpath%20d='M241.843%20108.207C241.53%20108.011%20241.165%20107.915%20240.796%20107.93C240.427%20107.945%20240.071%20108.071%20239.775%20108.292C239.479%20108.512%20239.256%20108.817%20239.135%20109.167C239.015%20109.516%20239.002%20109.894%20239.099%20110.251C239.306%20110.995%20239.652%20111.692%20240.12%20112.306C241.526%20114.135%20250.927%20119.336%20251.63%20119.609C252.334%20119.881%20253.456%20119.052%20253.456%20117.644C253.456%20116.236%20243.771%20109.774%20242.932%20109.07C242.585%20108.763%20242.221%20108.475%20241.843%20108.207Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M252.752%2082.6185C252.752%2082.6185%20252.049%2082.3345%20251.698%2083.3226C251.346%2084.3106%20251.142%2085.5939%20249.872%2086.1276C248.602%2086.6614%20248.261%2086.8999%20247.354%2086.8318C246.869%2086.7941%20246.416%2086.572%20246.089%2086.2109C245.763%2085.8498%20245.586%2085.3771%20245.596%2084.8898C245.655%2083.7529%20246.063%2082.6621%20246.766%2081.7673C247.468%2080.8725%20248.431%2080.2176%20249.52%2079.8929C250.153%2079.6834%20250.823%2079.6063%20251.487%2079.6662C252.151%2079.726%20252.796%2079.9217%20253.382%2080.241C253.967%2080.5603%20254.481%2080.9965%20254.892%2081.5226C255.303%2082.0487%20255.601%2082.6536%20255.769%2083.2999C256.189%2085.0488%20255.497%2085.1964%20255.497%2085.1964C255.497%2085.1964%20255.417%2082.2891%20252.752%2082.6185Z'%20fill='%23BB543E'/%3e%3cpath%20opacity='0.35'%20d='M292.625%20129.105C303.367%20129.105%20312.075%20123.563%20312.075%20116.726C312.075%20109.89%20303.367%20104.347%20292.625%20104.347C281.884%20104.347%20273.176%20109.89%20273.176%20116.726C273.176%20123.563%20281.884%20129.105%20292.625%20129.105Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M304.215%20115.181C303.988%20117.725%20301.595%20119.451%20299.441%20120.382C297.068%20121.37%20294.513%20121.846%20291.944%20121.779C289.314%20121.784%20286.716%20121.206%20284.335%20120.087C282.293%20119.076%20280.116%20117.248%20280.116%20114.761C280.02%20115.604%20280.097%20116.458%20280.343%20117.271C280.588%20118.083%20280.998%20118.837%20281.545%20119.485C283.355%20121.23%20285.654%20122.379%20288.134%20122.778C292.784%20123.744%20299.1%20123.278%20302.627%20119.701C303.23%20119.052%20303.686%20118.281%20303.966%20117.441C304.245%20116.601%20304.342%20115.71%20304.249%20114.829C304.238%20114.942%20304.238%20115.056%20304.215%20115.181Z'%20fill='%23ADCDFC'/%3e%3cpath%20d='M300.688%20110.535C305.406%20113.272%20305.44%20117.701%20300.745%20120.438C298.102%20121.787%20295.177%20122.49%20292.211%20122.49C289.244%20122.49%20286.32%20121.787%20283.677%20120.438C278.947%20117.701%20278.936%20113.271%20283.677%20110.546C286.312%20109.205%20289.225%20108.506%20292.181%20108.504C295.137%20108.502%20298.051%20109.197%20300.688%20110.535Z'%20fill='white'/%3e%3cpath%20d='M293.463%20106.859L293.44%20116.909L292.181%20117.648L292.204%20107.586L293.463%20106.859Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M292.205%20107.586L292.183%20117.648L290.912%20116.909L290.935%20106.859L292.205%20107.586Z'%20fill='%237BAEFF'/%3e%3cpath%20d='M294.053%20105.018L292.205%20106.097L290.345%20105.018L292.193%20103.951L294.053%20105.018Z'%20fill='%234DA5DC'/%3e%3cpath%20d='M280.209%2070.7737C280.209%2070.7737%20276.41%2073.045%20275.401%2075.3163C274.392%2077.5876%20274.664%2093.4869%20279.937%20100.596C285.211%20107.705%20295.066%20108.671%20297.334%20107.66C299.602%20106.649%20312.712%20100.096%20313.722%2096.8143C314.731%2093.5323%20309.684%2090.9998%20306.917%2089.7392C304.15%2088.4786%20302.381%2086.7183%20300.872%2082.1643C299.364%2077.6103%20298.604%2069.797%20296.835%2068.5364C295.066%2067.2758%20290.802%2065.2203%20280.209%2070.7737Z'%20fill='%2325437F'/%3e%3cpath%20d='M299.036%20105.333C300.885%20104.515%20309.946%2099.9953%20313.78%2096.5769C314.596%2093.3744%20309.674%2090.8987%20306.975%2089.6608C304.276%2088.4229%20302.439%2086.6399%20300.93%2082.0859C299.422%2077.532%20298.662%2069.7186%20296.893%2068.458C295.124%2067.1975%20290.848%2065.176%20280.256%2070.7294C279.124%2071.4166%20278.064%2072.2155%20277.092%2073.1142C276.139%2075.7603%20276.479%2091.2848%20281.696%2098.2691C286.913%20105.253%20296.768%20106.389%20299.036%20105.333Z'%20fill='%23254DA1'/%3e%3cpath%20d='M303.153%2071.151C303.153%2071.151%20304.287%2071.5371%20305.115%2074.3422C305.943%2077.1473%20308.347%2082.2237%20307.508%2084.4723C306.669%2086.7209%20304.106%2085.4489%20303.437%2083.7682C302.768%2082.0874%20299.932%2074.2627%20300.488%2073.1157C301.044%2071.9687%20302.03%2070.7649%20303.153%2071.151Z'%20fill='%23113569'/%3e%3cpath%20d='M310.014%20128.657C310.183%20129.275%20310.419%20129.873%20310.717%20130.44C311.586%20131.532%20312.606%20132.496%20313.745%20133.302C314.505%20133.949%20315.435%20135.153%20315.344%20135.721C315.253%20136.288%20313.428%20136.425%20311.999%20136.118C310.57%20135.811%20309.311%20134.21%20308.891%20134.244C308.472%20134.278%20306.907%20133.972%20306.623%20133.427C306.339%20132.881%20306.838%20130.735%20306.838%20130.735V129.179L310.014%20128.657Z'%20fill='%23232839'/%3e%3cpath%20d='M317.044%20124.16C317.213%20124.775%20317.449%20125.369%20317.748%20125.932C318.613%20127.031%20319.633%20127.998%20320.776%20128.805C321.535%20129.452%20322.465%20130.645%20322.375%20131.224C322.284%20131.803%20320.458%20131.928%20319.029%20131.621C317.6%20131.315%20316.341%20129.714%20315.922%20129.748C315.502%20129.782%20313.937%20129.475%20313.654%20128.93C313.37%20128.385%20313.869%20126.238%20313.869%20126.238V124.683L317.044%20124.16Z'%20fill='%23232839'/%3e%3cpath%20d='M290.43%2093.2273C290.37%2095.1503%20290.892%2097.0465%20291.927%2098.6671C293.606%20101.109%20300.535%20107.287%20301.283%20107.855C302.032%20108.422%20302.225%20112.534%20302.973%20114.407C303.722%20116.281%20305.967%20128.467%20306.375%20129.409C306.375%20129.409%20306.75%20130.341%20309.369%20129.784C310.866%20129.591%20311.048%20129.035%20311.048%20129.035C311.048%20129.035%20310.118%20115.35%20309.369%20112.159C308.621%20108.968%20308.428%20105.413%20307.101%20104.107C305.774%20102.801%20299.423%2094.5447%20299.423%2094.5447L297.927%2092.103L290.43%2093.2273Z'%20fill='%23113C7A'/%3e%3cpath%20d='M302.03%2090.2268C302.03%2090.2268%20312.135%2095.9051%20313.541%2097.1203C314.897%2098.3056%20315.832%2099.8997%20316.206%20101.663C316.32%20102.276%20317.34%20124.013%20317.76%20125.001C317.896%20125.841%20315.231%20126.409%20313.961%20125.989C313.466%20125.646%20313.039%20125.215%20312.702%20124.717C312.702%20124.717%20310.173%20111.645%20310.173%20109.817C309.937%20107.359%20309.558%20104.917%20309.039%20102.503L297.392%2095.8938L296.541%2092.941L302.03%2090.2268Z'%20fill='%23113C7A'/%3e%3cpath%20d='M290.807%2095.1093C290.807%2095.1093%20291.782%2097.9144%20295.853%2097.4942L297.26%2097.2103L297.543%2094.939C298.96%2094.7497%20300.31%2094.2198%20301.479%2093.3945C302.034%2093.6784%20302.182%2095.0866%20302.737%2095.2229C303.293%2095.3592%20304.28%2093.3945%20303.996%2091.9863C303.713%2090.5781%20303.021%2091.1459%20303.021%2091.1459C303.021%2091.1459%20291.51%2094.0305%20290.807%2095.1093Z'%20fill='%23112C5C'/%3e%3cpath%20d='M295.1%2069.6954C295.1%2069.6954%20290.292%2073.1024%20289.815%2074.2381C289.244%2076.376%20289.391%2078.643%20290.235%2080.6886C291.222%2082.801%20290.859%2090.6143%20291.222%2092.1361C291.584%2093.6579%20295.69%2094.1462%20298.23%2093.6579C300.771%2093.1695%20303.901%2091.3184%20303.753%2088.343C303.606%2085.3675%20303.753%2079.8369%20303.889%2078.4968C304.024%2076.1613%20303.81%2073.8188%20303.254%2071.5466C303.118%2071.0696%20301.519%2070.5699%20301.519%2070.5699C301.519%2070.5699%20299.829%2069.491%20295.1%2069.6954Z'%20fill='white'/%3e%3cpath%20d='M299.272%2069.0491C299.265%2069.0981%20299.265%2069.1478%20299.272%2069.1968C299.329%2069.5488%20299.51%2070.4573%20299.533%2070.8321C299.556%2071.2069%20299.159%2071.8201%20298.183%2071.7974C297.564%2071.8184%20296.949%2071.684%20296.394%2071.4063C295.839%2071.1286%20295.363%2070.7165%20295.008%2070.2075C295.027%2069.0696%20294.974%2067.9317%20294.849%2066.8005L299.272%2069.0491Z'%20fill='%23E16B40'/%3e%3cpath%20d='M294.976%2069.4673C295.233%2070.1558%20295.7%2070.7458%20296.31%2071.1536C296.921%2071.5613%20297.645%2071.766%20298.378%2071.7386H298.56L297.233%2073.8736C296.292%2073.3206%20295.403%2072.6819%20294.579%2071.9657C294.19%2071.4984%20293.984%2070.9048%20294.001%2070.2963L294.976%2069.4673Z'%20fill='white'/%3e%3cpath%20d='M298.55%2071.7878L299.933%2073.1165C300.275%2072.7255%20300.494%2072.2428%20300.565%2071.7281C300.635%2071.2134%20300.554%2070.6893%20300.33%2070.2206L299.468%2069.8799C299.481%2070.2487%20299.405%2070.6152%20299.245%2070.9476C299.084%2071.2801%20298.846%2071.5684%20298.55%2071.7878Z'%20fill='white'/%3e%3cpath%20d='M301.33%2062.379C300.809%2059.6421%20298.642%2058.0862%20296.193%2058.6541C295.393%2058.7607%20294.63%2059.0523%20293.963%2059.5057C293.295%2059.959%20292.743%2060.5617%20292.348%2061.2661C291.214%2063.6055%20292.904%2065.5702%20294.015%2066.8195C294.48%2067.3191%20294.832%2067.7166%20295.059%2067.9551C295.136%2068.0513%20295.219%2068.1424%20295.308%2068.2277C295.945%2068.8588%20296.723%2069.3297%20297.576%2069.6018C298.089%2069.777%20298.638%2069.8147%20299.169%2069.7111C299.7%2069.6075%20300.195%2069.3662%20300.604%2069.0113C301.308%2068.3299%20301.841%2065.1273%20301.33%2062.379Z'%20fill='%23FF8654'/%3e%3cpath%20d='M293.988%2070.3425C293.988%2070.3425%20293.274%2071.0353%20294.215%2072.7615C295.501%2075.2189%20296.211%2077.9377%20296.291%2080.7111C296.381%2083.9932%20296.812%2094.339%20296.381%2096.5535C295.519%2097.3258%20291.369%2096.633%20290.155%2094.5548C289.634%2091.5339%20289.894%2082.3464%20289.293%2080.4499C288.788%2078.3751%20288.757%2076.2128%20289.203%2074.1243C290.498%2072.5233%20292.132%2071.2314%20293.988%2070.3425Z'%20fill='%23113C7A'/%3e%3cpath%20d='M300.676%2070.2751C301.189%2072.3546%20301.421%2074.4935%20301.368%2076.6348C301.368%2080.0418%20302.343%2094.1807%20302.502%2094.4647C302.661%2094.7486%20304.702%2092.9656%20304.77%2090.8873C304.838%2088.8091%20304.078%2076.0557%20303.965%2074.7837C303.894%2073.5356%20303.618%2072.3077%20303.148%2071.1496C302.356%2070.7742%20301.528%2070.4812%20300.676%2070.2751Z'%20fill='%23113C7A'/%3e%3cpath%20d='M299.67%2072.4777L299.046%2073.795L297.742%2072.7616L298.547%2071.7849L299.67%2072.4777Z'%20fill='%23113C7A'/%3e%3cpath%20d='M299.333%2072.9654C299.333%2072.9654%20300.569%2088.7851%20300.569%2089.4778L299.741%2090.9315L298.607%2089.7958L298.199%2072.8745L299.333%2072.9654Z'%20fill='%23113C7A'/%3e%3cpath%20d='M289.442%2073.5905C288.618%2074.4566%20288.039%2075.5266%20287.764%2076.6908C287.015%2079.0303%20286.539%2087.1843%20286.539%2088.3995C286.539%2089.6146%20286.539%2091.0228%20287.571%2091.6815C287.794%2091.8623%20288.054%2091.9901%20288.333%2092.0553C288.613%2092.1206%20288.903%2092.1215%20289.182%2092.0581C289.462%2091.9947%20289.723%2091.8685%20289.947%2091.6892C290.171%2091.5099%20290.351%2091.282%20290.474%2091.0228C291.132%2089.8077%20291.608%2082.8688%20292.062%2080.7224C292.516%2078.576%20293.287%2076.4069%20292.345%2075.0441C292.079%2074.5241%20291.654%2074.1028%20291.131%2073.8414C290.609%2073.58%20290.018%2073.4921%20289.442%2073.5905Z'%20fill='%23113C7A'/%3e%3cpath%20d='M292.814%2059.0649C293.137%2058.5521%20293.577%2058.1231%20294.097%2057.8132C294.617%2057.5033%20295.204%2057.3212%20295.808%2057.282C297.963%2057.1002%20298.53%2057.8498%20299.46%2057.9406C300.39%2058.0315%20301.24%2057.5659%20301.898%2058.5993C302.556%2059.6328%20301.15%2061.5975%20301.15%2061.5975C301.15%2061.5975%20300.401%2061.4157%20299.653%2063.2896C298.904%2065.1634%20296.182%2064.6864%20295.626%2064.5047L295.162%2065.436V66.2877L294.504%2066.1855C294.504%2066.1855%20294.787%2065.1634%20294.13%2064.7887C293.472%2064.4139%20293.29%2065.1634%20293.381%2065.7199C293.705%2066.6813%20294.371%2067.4898%20295.252%2067.9912L294.969%2068.559L294.787%2068.9338C294.254%2068.5023%20293.754%2068.0316%20293.29%2067.5256C292.814%2066.9691%20292.156%2067.4347%20291.226%2065.3678C290.296%2063.3009%20290.569%2061.711%20291.408%2060.8252L292.258%2059.8826L292.814%2059.0649Z'%20fill='%2396432A'/%3e%3cpath%20d='M302.164%2090.5122L311.577%2099.5066L304.274%20103.584L294.872%2094.5892L302.164%2090.5122Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M300.032%2097.3015C300.032%2097.3015%20300.497%2097.6309%20300.735%2097.7785L302.277%2098.7552C302.687%2099.1897%20303.034%2099.6789%20303.309%20100.209C303.571%20100.636%20303.73%20101.118%20303.774%20101.617C303.684%20101.856%20303.4%20101.708%20303.4%20101.708C303.124%20102.018%20302.737%20102.206%20302.323%20102.23C301.767%20102.174%20301.291%20101.481%20301.291%20101.481L300.497%20100.777C300.174%20100.417%20299.92%20100.002%20299.748%2099.5501L299.193%2099.1754C299.193%2099.1754%20298.796%2098.7552%20300.032%2097.3015Z'%20fill='%23FF8654'/%3e%3cpath%20d='M298.31%2098.8821C298.31%2098.8821%20298.899%2097.2127%20299.603%2096.7925L300.396%2097.349C299.896%2097.9305%20299.542%2098.6237%20299.364%2099.3704L298.31%2098.8821Z'%20fill='white'/%3e%3cpath%20d='M298.311%2098.8837C297.811%2098.837%20297.33%2098.6736%20296.904%2098.4068C295.66%2097.4896%20294.357%2096.655%20293.003%2095.9083C291.184%2095.0735%20289.483%2094.0004%20287.945%2092.7171C287.077%2091.8788%20286.572%2090.733%20286.539%2089.5259C286.914%2089.0409%20287.44%2088.695%20288.034%2088.5428C288.627%2088.3906%20289.255%2088.4408%20289.816%2088.6855C291.66%2089.5661%20293.365%2090.7141%20294.875%2092.0925C296.553%2093.5007%20299.411%2096.2944%20299.411%2096.2944L299.898%2096.8736C299.51%2097.0812%20299.168%2097.3668%20298.895%2097.7127C298.622%2098.0586%20298.423%2098.4573%20298.311%2098.8837Z'%20fill='%23113C7A'/%3e%3cpath%20d='M304.84%2085.0278C304.766%2085.9753%20304.858%2086.9285%20305.113%2087.8442C305.543%2089.2524%20304.557%2094.0335%20304.976%2094.4537C305.302%2094.7787%20305.706%2095.0143%20306.149%2095.1376C306.592%2095.2609%20307.059%2095.2679%20307.505%2095.1578L308.345%2094.59C308.345%2094.59%20308.764%2089.8089%20308.764%2088.4007C308.764%2086.9925%20308.345%2083.0631%20307.369%2082.2227C306.394%2081.3823%20303.99%2082.0751%20304.84%2085.0278Z'%20fill='%23113569'/%3e%3cpath%20d='M305.328%2094.3081C305.687%2093.9832%20306.157%2093.809%20306.64%2093.8217C307.124%2093.8344%20307.584%2094.033%20307.925%2094.3762L307.993%2095.3643C307.993%2095.3643%20307.71%2096.2841%20305.396%2095.4324L305.328%2094.3081Z'%20fill='white'/%3e%3cpath%20d='M305.545%2095.1786C305.895%2094.9846%20306.292%2094.8905%20306.691%2094.9065C307.091%2094.9226%20307.479%2095.0481%20307.813%2095.2694L307.904%2095.6442C307.904%2095.6442%20308.21%2096.4846%20308.323%2096.8593C308.376%2097.182%20308.353%2097.5126%20308.255%2097.8247C308.236%2098.1817%20308.179%2098.5357%20308.085%2098.8808C307.994%2099.0398%20307.813%2098.9944%20307.643%2098.9717C307.141%2098.8111%20306.648%2098.6215%20306.168%2098.4038C305.794%2098.2448%20305.681%2097.4272%20305.613%2097.1432C305.567%2096.7129%20305.567%2096.2789%20305.613%2095.8486C305.62%2095.6232%20305.597%2095.3979%20305.545%2095.1786Z'%20fill='%23FF8654'/%3e%3cpath%20d='M329.925%2063.9153V65.4938C329.926%2065.7053%20329.871%2065.9132%20329.765%2066.0965C329.66%2066.2798%20329.508%2066.4321%20329.325%2066.5381C329.143%2066.644%20328.935%2066.6998%20328.724%2066.6999C328.513%2066.7%20328.305%2066.6444%20328.122%2066.5386L320.671%2062.2345C320.487%2062.1292%20320.333%2061.9773%20320.226%2061.794C320.118%2061.6106%20320.061%2061.4023%20320.059%2061.1897V59.6111C320.061%2059.3993%20320.118%2059.1916%20320.225%2059.0087C320.331%2058.8258%20320.484%2058.6741%20320.667%2058.5685C320.851%2058.4629%20321.059%2058.4071%20321.27%2058.4067C321.482%2058.4064%20321.69%2058.4614%20321.874%2058.5663L329.324%2062.8591C329.509%2062.9659%20329.662%2063.12%20329.768%2063.3056C329.873%2063.4912%20329.928%2063.7016%20329.925%2063.9153Z'%20fill='%23F9FBFC'/%3e%3cpath%20d='M353.526%2085.2874V86.8773C353.526%2087.0888%20353.471%2087.2967%20353.366%2087.48C353.26%2087.6633%20353.109%2087.8156%20352.926%2087.9215C352.743%2088.0274%20352.535%2088.0833%20352.324%2088.0834C352.113%2088.0835%20351.906%2088.0278%20351.723%2087.9221L320.671%2070.1263C320.486%2070.0192%20320.332%2069.8653%20320.225%2069.68C320.117%2069.4947%20320.06%2069.2844%20320.059%2069.0702V67.4916C320.059%2067.2788%20320.115%2067.0697%20320.221%2066.8852C320.326%2066.7008%20320.479%2066.5474%20320.663%2066.4405C320.846%2066.3335%20321.055%2066.2768%20321.267%2066.2759C321.48%2066.275%20321.689%2066.33%20321.874%2066.4354L352.925%2084.2653C353.105%2084.3692%20353.254%2084.5179%20353.36%2084.697C353.465%2084.8761%20353.522%2085.0795%20353.526%2085.2874Z'%20fill='%23F9FBFC'/%3e%3cg%20opacity='0.53'%3e%3cpath%20d='M340.735%2093.6676V95.2462C340.735%2095.459%20340.679%2095.6681%20340.573%2095.8525C340.467%2096.037%20340.315%2096.1904%20340.131%2096.2973C339.948%2096.4043%20339.739%2096.461%20339.527%2096.4619C339.314%2096.4628%20339.105%2096.4078%20338.92%2096.3024L320.673%2085.8202C320.49%2085.7144%20320.338%2085.5621%20320.232%2085.3786C320.127%2085.1952%20320.072%2084.9871%20320.072%2084.7754V83.1969C320.073%2082.9857%20320.129%2082.7785%20320.234%2082.5956C320.34%2082.4127%20320.491%2082.2604%20320.673%2082.1538C320.855%2082.0472%20321.061%2081.9899%20321.272%2081.9876C321.483%2081.9853%20321.691%2082.0381%20321.875%2082.1407L340.123%2092.6228C340.307%2092.7281%20340.461%2092.88%20340.568%2093.0634C340.676%2093.2467%20340.733%2093.4551%20340.735%2093.6676Z'%20fill='%23F9FBFC'/%3e%3c/g%3e%3cpath%20d='M348.722%2090.3889V91.9789C348.72%2092.1907%20348.663%2092.3984%20348.556%2092.5813C348.449%2092.7641%20348.296%2092.9159%20348.113%2093.0215C347.93%2093.1271%20347.722%2093.1829%20347.51%2093.1832C347.299%2093.1836%20347.091%2093.1286%20346.907%2093.0237L320.676%2077.9648C320.493%2077.859%20320.341%2077.7067%20320.235%2077.5232C320.13%2077.3398%20320.074%2077.1317%20320.075%2076.92V75.3301C320.074%2075.1186%20320.129%2074.9107%20320.235%2074.7274C320.34%2074.5441%20320.492%2074.3918%20320.675%2074.2859C320.857%2074.1799%20321.065%2074.1241%20321.276%2074.124C321.487%2074.1239%20321.695%2074.1795%20321.878%2074.2853L348.109%2089.3441C348.294%2089.4494%20348.447%2089.6013%20348.555%2089.7847C348.662%2089.968%20348.72%2090.1764%20348.722%2090.3889Z'%20fill='%23F9FBFC'/%3e%3cpath%20d='M365.824%2091.1697V112.384L350.729%20121.287'%20stroke='white'%20stroke-width='0.53'%20stroke-miterlimit='10'/%3e%3cpath%20d='M367.61%2089.6723C367.607%2090.0469%20367.494%2090.4125%20367.285%2090.7229C367.076%2091.0332%20366.779%2091.2746%20366.433%2091.4164C366.086%2091.5582%20365.706%2091.5941%20365.339%2091.5197C364.973%2091.4452%20364.636%2091.2637%20364.373%2090.998C364.109%2090.7323%20363.93%2090.3944%20363.857%2090.0268C363.785%2089.6592%20363.823%2089.2785%20363.967%2088.9326C364.111%2088.5867%20364.354%2088.2912%20364.665%2088.0833C364.976%2087.8754%20365.342%2087.7644%20365.716%2087.7644C365.965%2087.7644%20366.213%2087.8138%20366.443%2087.9098C366.674%2088.0059%20366.883%2088.1466%20367.059%2088.3239C367.235%2088.5012%20367.374%2088.7116%20367.469%2088.943C367.563%2089.1745%20367.611%2089.4223%20367.61%2089.6723V89.6723Z'%20stroke='white'%20stroke-width='1.06'%20stroke-miterlimit='10'/%3e%3cpath%20d='M715.132%2070.3542V91.5684L700.048%20100.472'%20stroke='white'%20stroke-width='0.53'%20stroke-miterlimit='10'/%3e%3cpath%20d='M715.031%2070.7535C716.077%2070.7535%20716.925%2069.9044%20716.925%2068.857C716.925%2067.8096%20716.077%2066.9604%20715.031%2066.9604C713.985%2066.9604%20713.137%2067.8096%20713.137%2068.857C713.137%2069.9044%20713.985%2070.7535%20715.031%2070.7535Z'%20stroke='white'%20stroke-width='1.06'%20stroke-miterlimit='10'/%3e%3cpath%20opacity='0.35'%20d='M501.346%20238.069C501.346%20242.305%20495.959%20245.723%20489.313%20245.723C482.668%20245.723%20477.281%20242.316%20477.281%20238.069C477.281%20233.822%20482.668%20230.415%20489.313%20230.415C495.959%20230.415%20501.346%20233.844%20501.346%20238.069Z'%20fill='%23A6D0F4'/%3e%3cpath%20opacity='0.35'%20d='M512.446%20235.683C524.353%20235.683%20534.005%20229.541%20534.005%20221.964C534.005%20214.387%20524.353%20208.245%20512.446%20208.245C500.539%20208.245%20490.887%20214.387%20490.887%20221.964C490.887%20229.541%20500.539%20235.683%20512.446%20235.683Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M496.12%20218.762C496.369%20221.59%20499.023%20223.509%20501.416%20224.531C504.044%20225.625%20506.872%20226.151%20509.717%20226.076C512.634%20226.086%20515.516%20225.446%20518.155%20224.202C520.423%20223.066%20522.839%20221.056%20522.827%20218.297C522.827%20220.307%20522.691%20221.965%20521.251%20223.532C519.245%20225.467%20516.697%20226.743%20513.947%20227.189C508.799%20228.256%20501.79%20227.745%20497.877%20223.782C496.301%20222.192%20496.086%20220.511%20496.086%20218.387C496.087%20218.513%20496.098%20218.638%20496.12%20218.762Z'%20fill='%23ADCDFC'/%3e%3cpath%20d='M500.033%20213.627C494.793%20216.648%20494.759%20221.576%20499.965%20224.597C505.17%20227.618%20513.653%20227.618%20518.892%20224.597C524.132%20221.576%20524.143%20216.648%20518.892%20213.627C513.642%20210.606%20505.306%20210.595%20500.033%20213.627Z'%20fill='white'/%3e%3cpath%20d='M508.03%20209.526L508.053%20220.678L509.459%20221.495L509.425%20210.343L508.03%20209.526Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M509.424%20210.343L509.458%20221.495L510.864%20220.678L510.842%20209.526L509.424%20210.343Z'%20fill='%237BAEFF'/%3e%3cpath%20d='M507.375%20207.494L509.428%20208.687L511.48%20207.494L509.439%20206.313L507.375%20207.494Z'%20fill='%234DA5DC'/%3e%3cpath%20d='M522.735%20169.54C522.735%20169.54%20526.942%20172.016%20528.065%20174.537C529.188%20177.058%20528.881%20194.729%20523.007%20202.565C517.132%20210.401%20506.245%20211.514%20503.727%20210.401C501.21%20209.288%20486.716%20201.997%20485.582%20198.363C484.448%20194.729%20490.118%20191.924%20493.135%20190.527C496.152%20189.13%20498.159%20187.177%20499.837%20182.135C501.516%20177.092%20502.355%20168.427%20504.306%20167.019C506.256%20165.611%20510.974%20163.385%20522.735%20169.54Z'%20fill='black'/%3e%3cpath%20d='M501.9%20207.903C499.859%20206.994%20489.822%20201.986%20485.581%20198.204C484.673%20194.638%20490.117%20191.913%20493.156%20190.527C496.196%20189.142%20498.18%20187.177%20499.859%20182.135C501.537%20177.092%20502.376%20168.427%20504.327%20167.019C506.278%20165.611%20511.041%20163.385%20522.779%20169.54C524.031%20170.305%20525.204%20171.191%20526.283%20172.186C527.349%20175.116%20526.963%20192.356%20521.191%20200.067C515.418%20207.778%20504.372%20209.027%20501.9%20207.903Z'%20fill='%23232839'/%3e%3cpath%20d='M500.764%20171.451C500.764%20171.451%20499.517%20171.883%20498.587%20174.995C497.657%20178.106%20495.003%20183.728%20495.944%20186.215C496.885%20188.702%20499.675%20187.35%20500.48%20185.431C501.286%20183.512%20504.359%20174.904%20503.735%20173.62C503.112%20172.337%20502.012%20171.02%20500.764%20171.451Z'%20fill='%23113569'/%3e%3cpath%20d='M493.169%20235.204C492.983%20235.885%20492.725%20236.544%20492.398%20237.169C491.854%20238.225%20489.869%20239.633%20488.996%20240.349C488.123%20241.064%20487.125%20242.393%20487.238%20243.029C487.352%20243.665%20489.359%20243.824%20490.947%20243.472C492.534%20243.12%20493.918%20241.36%20494.349%20241.394C494.78%20241.428%20496.617%20241.098%20496.912%20240.497C497.207%20239.895%20496.674%20237.51%20496.674%20237.51V235.784L493.169%20235.204Z'%20fill='%23232839'/%3e%3cpath%20d='M485.391%20230.256C485.205%20230.937%20484.946%20231.596%20484.619%20232.221C484.075%20233.277%20482.09%20234.685%20481.217%20235.401C480.344%20236.116%20479.346%20237.445%20479.448%20238.081C479.55%20238.717%20481.58%20238.865%20483.168%20238.524C484.756%20238.183%20486.139%20236.412%20486.57%20236.446C487.001%20236.48%20488.782%20236.139%20489.133%20235.549C489.485%20234.958%20488.895%20232.562%20488.895%20232.562V230.836L485.391%20230.256Z'%20fill='%23232839'/%3e%3cpath%20d='M514.883%20195.924C514.944%20198.055%20514.368%20200.155%20513.227%20201.955C511.356%20204.658%20503.678%20211.517%20502.85%20212.176C502.022%20212.834%20501.807%20217.366%20500.979%20219.444C500.151%20221.522%20497.667%20235.025%20497.248%20236.07C497.248%20236.07%20496.828%20237.104%20493.925%20236.479C492.269%20236.274%20492.065%20235.65%20492.065%20235.65C492.065%20235.65%20493.097%20220.489%20493.925%20216.946C494.753%20213.402%20494.968%20209.473%20496.42%20208.019C497.871%20206.566%20504.925%20197.424%20504.925%20197.424L506.581%20194.721L514.883%20195.924Z'%20fill='%23113C7A'/%3e%3cpath%20d='M502.023%20192.609C502.023%20192.609%20490.818%20198.844%20489.253%20200.241C487.765%20201.546%20486.732%20203.292%20486.304%20205.226C486.179%20205.919%20485.057%20230.006%20484.592%20231.097C484.433%20232.039%20487.393%20232.652%20488.788%20232.232C489.34%20231.859%20489.817%20231.385%20490.194%20230.835C490.194%20230.835%20492.995%20216.344%20492.995%20214.312C493.253%20211.59%20493.67%20208.887%20494.243%20206.214L507.16%20198.889L508.09%20195.607L502.023%20192.609Z'%20fill='%23113C7A'/%3e%3cpath%20d='M514.479%20198.058C514.479%20198.058%20513.345%20201.181%20508.876%20200.704L507.311%20200.397L507.005%20197.899C505.435%20197.694%20503.939%20197.105%20502.65%20196.184C502.027%20196.502%20501.868%20198.058%20501.244%20198.217C500.62%20198.376%20499.532%20196.184%20499.849%20194.628C500.167%20193.073%20500.983%20193.697%20500.983%20193.697C500.983%20193.697%20513.696%20196.809%20514.479%20198.058Z'%20fill='%23112C5C'/%3e%3cpath%20d='M509.703%20169.839C509.703%20169.839%20515.033%20173.644%20515.555%20174.916C516.198%20177.281%20516.039%20179.794%20515.101%20182.059C513.967%20184.41%20514.409%20193.064%20513.967%20194.756C513.525%20196.448%20509.011%20197.027%20506.187%20196.436C503.363%20195.846%20499.961%20193.847%20500.063%20190.554C500.165%20187.26%20500.063%20181.116%20499.927%20179.64C499.769%20177.049%20500.006%20174.449%20500.63%20171.929C500.766%20171.407%20502.547%20170.85%20502.547%20170.85C502.547%20170.85%20504.452%20169.612%20509.703%20169.839Z'%20fill='%23C7BFCE'/%3e%3cpath%20d='M505.075%20169.122C505.082%20169.179%20505.082%20169.236%20505.075%20169.293C505.018%20169.679%20504.825%20170.678%20504.78%20171.098C504.734%20171.518%20505.199%20172.234%20506.277%20172.166C507.354%20172.098%20509.191%20171.689%20509.804%20170.406C509.776%20169.135%20509.837%20167.864%20509.985%20166.601L505.075%20169.122Z'%20fill='%23E16B40'/%3e%3cpath%20d='M509.84%20169.586C509.561%20170.356%20509.048%20171.018%20508.372%20171.479C507.696%20171.94%20506.892%20172.175%20506.075%20172.153H505.882L507.345%20174.515C508.388%20173.904%20509.371%20173.197%20510.282%20172.402C510.714%20171.884%20510.944%20171.226%20510.929%20170.551L509.84%20169.586Z'%20fill='white'/%3e%3cpath%20d='M505.891%20172.155L504.348%20173.62C504.348%20173.62%20503.214%20172.666%20503.906%20170.429L504.859%20170.043C504.842%20170.453%20504.928%20170.861%20505.108%20171.23C505.288%20171.598%20505.557%20171.916%20505.891%20172.155Z'%20fill='white'/%3e%3cpath%20d='M502.807%20161.739C503.374%20158.696%20505.778%20156.97%20508.478%20157.606C509.364%20157.723%20510.211%20158.046%20510.952%20158.549C511.692%20159.051%20512.305%20159.72%20512.742%20160.502C514.046%20163.091%20512.129%20165.271%20510.893%20166.646C510.372%20167.213%20509.975%20167.645%20509.759%20167.929L509.487%20168.235C508.783%20168.942%20507.919%20169.467%20506.969%20169.769C506.403%20169.963%20505.796%20170.005%20505.208%20169.889C504.621%20169.774%20504.074%20169.505%20503.624%20169.11C502.83%20168.326%20502.24%20164.772%20502.807%20161.739Z'%20fill='%23FF8654'/%3e%3cpath%20d='M510.973%20170.552C510.973%20170.552%20511.767%20171.313%20510.712%20173.244C509.301%20175.976%20508.525%20178.992%20508.444%20182.068C508.353%20185.713%20507.877%20197.138%20508.354%20199.636C509.306%20200.499%20513.911%20199.727%20515.249%20197.433C515.827%20194.026%20515.544%20183.896%20516.213%20181.784C516.77%20179.485%20516.801%20177.089%20516.303%20174.777C515.759%20173.72%20512.107%20170.836%20510.973%20170.552Z'%20fill='%23113C7A'/%3e%3cpath%20d='M503.521%20170.486C502.951%20172.788%20502.691%20175.156%20502.75%20177.527C502.75%20181.309%20501.673%20196.981%20501.48%20197.299C501.287%20197.617%20499.053%20195.641%20498.985%20193.336C498.917%20191.03%20499.756%20176.891%20499.881%20175.483C499.954%20174.099%20500.257%20172.736%20500.777%20171.452C501.655%20171.034%20502.575%20170.711%20503.521%20170.486Z'%20fill='%23113C7A'/%3e%3cpath%20d='M504.631%20172.927L505.323%20174.38L506.775%20173.233L505.89%20172.154L504.631%20172.927Z'%20fill='%23113C7A'/%3e%3cpath%20d='M505.02%20173.472C505.02%20173.472%20503.648%20191.018%20503.648%20191.779L504.566%20193.392L505.791%20192.086L506.245%20173.325L505.02%20173.472Z'%20fill='%23113C7A'/%3e%3cpath%20d='M429.925%20232.455L427.396%20230.979L427.327%20201.997L429.856%20203.473L429.925%20232.455Z'%20fill='%238750CA'/%3e%3cpath%20d='M429.857%20203.473L427.327%20201.997L461.77%20182.078L464.31%20183.554L429.857%20203.473Z'%20fill='%23DBDBDB'/%3e%3cpath%20d='M464.311%20183.557L464.379%20212.539L429.925%20232.458L429.857%20203.476L464.311%20183.557Z'%20fill='%239966D7'/%3e%3cpath%20d='M432.321%20197.968L432.253%20226.95L501.296%20266.562L501.364%20237.58L432.321%20197.968Z'%20fill='%23A478D9'/%3e%3cpath%20d='M432.28%20214.174L501.334%20253.785L501.368%20237.58L432.325%20197.968L432.28%20214.174Z'%20fill='%238750CA'/%3e%3cpath%20d='M499.169%20269.379L496.629%20267.903L496.561%20238.921L499.101%20240.397L499.169%20269.379Z'%20fill='%238750CA'/%3e%3cpath%20d='M499.101%20240.396L496.561%20238.92L531.014%20219L533.543%20220.477L499.101%20240.396Z'%20fill='%23DBDBDB'/%3e%3cpath%20d='M533.54%20220.477L533.62%20249.459L499.166%20269.379L499.098%20240.397L533.54%20220.477Z'%20fill='%23976EC9'/%3e%3cpath%20d='M538.269%20219.725L538.258%20222.45L499.2%20245.175L499.211%20242.449L538.269%20219.725Z'%20fill='%238C57CC'/%3e%3cpath%20d='M499.209%20242.452L499.198%20245.178L421.558%20200.296L421.57%20197.571L499.209%20242.452Z'%20fill='%238750CA'/%3e%3cpath%20d='M538.271%20219.725L499.213%20242.45L421.573%20197.569L460.631%20174.833L538.271%20219.725Z'%20fill='%23B59AD7'/%3e%3cpath%20d='M515.975%20174.164C516.891%20175.111%20517.537%20176.288%20517.846%20177.571C518.674%20180.171%20519.195%20189.2%20519.195%20190.551C519.195%20191.903%20519.195%20193.47%20518.061%20194.197C517.814%20194.394%20517.526%20194.533%20517.218%20194.603C516.91%20194.674%20516.591%20194.674%20516.283%20194.604C515.974%20194.534%20515.686%20194.396%20515.438%20194.2C515.191%20194.004%20514.99%20193.754%20514.852%20193.47C514.126%20192.118%20513.604%20184.385%20513.083%20182.034C512.561%20179.683%20511.733%20177.253%20512.777%20175.697C513.081%20175.137%20513.554%20174.688%20514.128%20174.412C514.702%20174.137%20515.348%20174.05%20515.975%20174.164Z'%20fill='%23113C7A'/%3e%3cpath%20d='M504.164%20200.444C504.164%20200.444%20503.643%20200.807%20503.382%20200.966L501.669%20202.102C501.213%20202.58%20500.831%20203.123%20500.535%20203.714C500.238%20204.183%20500.058%20204.717%20500.014%20205.27C500.116%20205.531%20500.433%20205.372%20500.433%20205.372C500.74%20205.713%20501.167%20205.921%20501.624%20205.952C502.248%20205.895%20502.758%20205.123%20502.758%20205.123L503.643%20204.339C503.999%20203.943%20504.279%20203.485%20504.471%20202.987L505.094%20202.567C505.094%20202.567%20505.593%20202.056%20504.164%20200.444Z'%20fill='%23FF8654'/%3e%3cpath%20d='M506.141%20202.194C506.141%20202.194%20505.495%20200.343%20504.723%20199.923L503.839%20200.548C504.394%20201.202%20504.783%20201.981%20504.973%20202.819L506.141%20202.194Z'%20fill='white'/%3e%3cpath%20d='M506.146%20202.194C506.701%20202.144%20507.236%20201.965%20507.711%20201.672C509.092%20200.65%20510.539%20199.72%20512.043%20198.89C514.059%20197.967%20515.943%20196.779%20517.645%20195.358C518.603%20194.428%20519.161%20193.161%20519.199%20191.826C518.785%20191.287%20518.202%20190.902%20517.545%20190.734C516.887%20190.565%20516.192%20190.622%20515.57%20190.895C513.527%20191.854%20511.639%20193.113%20509.967%20194.631C508.096%20196.187%20504.909%20199.287%20504.909%20199.287L504.365%20199.934C504.805%20200.164%20505.19%20200.484%20505.497%20200.873C505.804%20201.263%20506.025%20201.713%20506.146%20202.194Z'%20fill='%23113C7A'/%3e%3cpath%20d='M502.908%20161.207C502.625%20160.774%20502.43%20160.289%20502.337%20159.78C502.243%20159.271%20502.252%20158.748%20502.364%20158.243C502.794%20156.71%20504.768%20157.368%20505.868%20157.255C506.968%20157.141%20511.232%20157.255%20512.672%20159.117C514.113%20160.98%20513.444%20161.865%20513.444%20161.865C513.557%20162.754%20513.444%20163.656%20513.115%20164.489C512.559%20165.693%20509.78%20167.896%20509.78%20167.896C510.514%20167.003%20511.086%20165.988%20511.47%20164.898C511.584%20163.91%20511.028%20163.365%20510.699%20163.58C510.37%20163.796%20510.155%20165.659%20510.155%20165.659L510.007%20166.567C509.281%20166.317%20509.497%20164.784%20509.497%20164.784C509.153%20164.282%20508.896%20163.725%20508.737%20163.137C508.51%20162.263%20508.408%20161.831%20507.524%20161.389C506.859%20160.904%20506.065%20160.628%20505.243%20160.595C504.422%20160.563%20503.609%20160.776%20502.908%20161.207Z'%20fill='%23505E83'/%3e%3cpath%20d='M484.475%20177.56C484.475%20177.56%20483.92%20177.265%20483.659%20177.094C483.398%20176.924%20482.4%20176.333%20481.912%20176.061C481.282%20175.859%20480.624%20175.756%20479.962%20175.754C479.41%20175.706%20478.855%20175.788%20478.34%20175.993C478.158%20176.209%20478.442%20176.413%20478.442%20176.413C478.266%20176.838%20478.266%20177.316%20478.442%20177.742C478.763%20178.105%20479.208%20178.336%20479.689%20178.389L480.824%20178.821C481.335%20178.967%20481.871%20179.013%20482.4%20178.957L483.046%20179.332C483.046%20179.332%20483.659%20179.536%20484.475%20177.56Z'%20fill='%23FF8654'/%3e%3cpath%20d='M483.761%20180.083C483.761%20180.083%20485.111%20178.675%20485.179%20177.812L484.226%20177.301C483.899%20178.084%20483.394%20178.78%20482.752%20179.334L483.761%20180.083Z'%20fill='white'/%3e%3cpath%20d='M483.754%20180.082C484.039%20180.544%20484.427%20180.932%20484.888%20181.217C486.42%20181.998%20487.901%20182.875%20489.323%20183.841C491.051%20185.227%20492.958%20186.373%20494.993%20187.248C496.254%20187.688%20497.637%20187.619%20498.849%20187.055C499.143%20186.442%20499.225%20185.749%20499.081%20185.084C498.937%20184.42%20498.576%20183.822%20498.055%20183.387C496.274%20181.992%20494.299%20180.867%20492.192%20180.048C489.924%20179.082%20485.773%20177.617%20485.773%20177.617L484.956%20177.424C484.955%20177.927%20484.847%20178.424%20484.64%20178.882C484.433%20179.34%20484.131%20179.749%20483.754%20180.082Z'%20fill='%23113569'/%3e%3cpath%20d='M501.324%20223.795L509.206%20228.383L521.964%20221.002L514.082%20216.414L501.324%20223.795Z'%20fill='%238C57CC'/%3e%3cpath%20d='M499.872%20221.066V223.02L507.765%20227.608L507.754%20225.654L499.872%20221.066Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M507.752%20225.656L507.763%20227.609L520.521%20220.228V218.274L507.752%20225.656Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M499.872%20221.065L507.754%20225.653L520.523%20218.271L512.63%20213.683L499.872%20221.065Z'%20fill='white'/%3e%3cpath%20d='M447.361%20200.377L455.254%20204.965L468.013%20197.594L460.12%20192.995L447.361%20200.377Z'%20fill='%238C57CC'/%3e%3cpath%20d='M445.913%20197.652L445.924%20199.605L453.806%20204.193V202.24L445.913%20197.652Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M453.801%20202.236V204.189L466.571%20196.818L466.559%20194.854L453.801%20202.236Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M445.913%20197.654L453.806%20202.242L466.564%20194.86L458.682%20190.272L445.913%20197.654Z'%20fill='white'/%3e%3cpath%20d='M490.068%20214.659L497.961%20219.247L510.719%20211.865L502.837%20207.277L490.068%20214.659Z'%20fill='white'/%3e%3cpath%20d='M496.942%20205.938C498.746%20206.983%20498.746%20208.663%20496.942%20209.708L485.397%20216.42C484.39%20216.935%20483.274%20217.204%20482.142%20217.204C481.011%20217.204%20479.895%20216.935%20478.888%20216.42L467.275%20209.708C465.471%20208.663%20465.46%20206.971%20467.275%20205.938L478.82%20199.215C479.825%20198.699%20480.939%20198.431%20482.069%20198.431C483.199%20198.431%20484.312%20198.699%20485.318%20199.215L496.942%20205.938Z'%20fill='%238C57CC'/%3e%3cpath%20d='M486.649%20207.686C486.634%20207.719%20486.615%20207.749%20486.592%20207.777L486.512%20207.856H486.456L486.376%20207.913L481.591%20210.571L476.419%20207.584V207.947L481.591%20210.934L486.376%20208.265H486.433H486.49L486.547%20208.208C486.547%20208.208%20486.547%20208.208%20486.547%20208.152V208.061V207.538C486.594%20207.577%20486.629%20207.628%20486.649%20207.686Z'%20fill='%23BAC0D2'/%3e%3cpath%20d='M486.392%20207.21C486.767%20207.426%20486.755%20207.766%20486.392%20207.982L481.606%20210.64L476.435%20207.653L480.484%20204.575C480.69%20204.466%20480.92%20204.409%20481.153%20204.409C481.386%20204.409%20481.616%20204.466%20481.822%20204.575L486.392%20207.21Z'%20fill='white'/%3e%3cpath%20d='M493.476%20195.894C493.905%20196.175%20494.21%20196.61%20494.327%20197.109L496.799%20213.78C496.867%20214.212%20496.584%20214.382%20496.187%20214.144L470.931%20199.585C470.499%20199.307%20470.193%20198.871%20470.08%20198.37L467.608%20181.698C467.54%20181.267%20467.812%20181.096%20468.22%20181.335L493.476%20195.894Z'%20fill='%23C7C9D7'/%3e%3cpath%20d='M497.204%20213.625V213.5L494.72%20196.829V196.658V196.522V196.374L494.641%20196.272L469.385%20181.656H468.976H468.908L468.511%20181.952H468.591C468.628%20181.946%20468.667%20181.946%20468.704%20181.952H468.84C468.897%20181.964%20468.951%20181.987%20468.999%20182.02L494.255%20196.636L494.403%20196.738L494.55%20196.863L494.686%20197.01L494.8%20197.169L494.902%20197.34L494.992%20197.51C494.997%20197.571%20494.997%20197.631%20494.992%20197.692C494.997%20197.745%20494.997%20197.798%20494.992%20197.851L497.465%20214.522C497.47%20214.568%20497.47%20214.613%20497.465%20214.658C497.47%20214.696%20497.47%20214.734%20497.465%20214.772C497.47%20214.795%20497.47%20214.818%20497.465%20214.84C497.444%20214.875%20497.417%20214.906%20497.385%20214.931L497.794%20214.636C497.825%20214.614%20497.849%20214.582%20497.862%20214.545V214.454L497.204%20213.625Z'%20fill='white'/%3e%3cpath%20opacity='0.2'%20d='M479.477%20205.318L476.415%20207.658L481.587%20210.645L485.204%20208.634L479.477%20205.318Z'%20fill='%23777DB2'/%3e%3cpath%20d='M482.675%20200.386L481.586%20211.028L476.404%20208.029L478.422%20198.058L482.675%20200.386Z'%20fill='%23BAC0D2'/%3e%3cpath%20d='M497.444%20233.936L500.313%20232.346L496.264%20230.245L497.444%20233.936Z'%20fill='%238C57CC'/%3e%3cpath%20d='M498.329%20229.19L499.123%20228.906L498.238%20233.653L497.445%20233.937L498.329%20229.19Z'%20fill='%23656874'/%3e%3cpath%20d='M485.4%20221.944L486.182%20221.66L499.122%20228.905L498.328%20229.189L485.4%20221.944Z'%20fill='%239C9EA6'/%3e%3cpath%20d='M498.329%20229.189L497.444%20233.936L484.516%20226.69L485.4%20221.943L498.329%20229.189Z'%20fill='%23232839'/%3e%3cpath%20d='M452.76%20189.871C453.894%20190.507%20453.894%20191.529%20452.76%20192.143C452.147%20192.456%20451.469%20192.619%20450.781%20192.619C450.093%20192.619%20449.415%20192.456%20448.802%20192.143C448.572%20192.055%20448.374%20191.9%20448.235%20191.697C448.095%20191.494%20448.02%20191.253%20448.02%20191.007C448.02%20190.761%20448.095%20190.52%20448.235%20190.317C448.374%20190.115%20448.572%20189.959%20448.802%20189.871C449.414%20189.556%20450.093%20189.391%20450.781%20189.391C451.47%20189.391%20452.148%20189.556%20452.76%20189.871Z'%20fill='%238C57CC'/%3e%3cpath%20d='M453.137%20184.219V190.442C453.116%20190.67%20453.034%20190.888%20452.9%20191.074C452.767%20191.26%20452.586%20191.406%20452.377%20191.498C451.806%20191.789%20451.175%20191.941%20450.534%20191.941C449.893%20191.941%20449.262%20191.789%20448.691%20191.498C448.48%20191.405%20448.297%20191.257%20448.161%20191.069C448.026%20190.882%20447.942%20190.661%20447.92%20190.431V184.196C447.938%20184.429%20448.02%20184.653%20448.156%20184.843C448.291%20185.033%20448.477%20185.183%20448.691%20185.275C449.262%20185.566%20449.893%20185.718%20450.534%20185.718C451.175%20185.718%20451.806%20185.566%20452.377%20185.275C452.586%20185.183%20452.767%20185.036%20452.9%20184.85C453.034%20184.665%20453.116%20184.447%20453.137%20184.219Z'%20fill='white'/%3e%3cpath%20d='M452.321%20183.137C453.342%20183.727%20453.353%20184.681%20452.321%20185.272C451.751%20185.563%20451.119%20185.715%20450.479%20185.715C449.838%20185.715%20449.206%20185.563%20448.636%20185.272C447.615%20184.681%20447.604%20183.727%20448.636%20183.137C449.206%20182.846%20449.838%20182.694%20450.479%20182.694C451.119%20182.694%20451.751%20182.846%20452.321%20183.137Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M451.925%20183.375C452.098%20183.434%20452.249%20183.545%20452.356%20183.694C452.463%20183.842%20452.52%20184.021%20452.52%20184.204C452.52%20184.387%20452.463%20184.566%20452.356%20184.715C452.249%20184.864%20452.098%20184.975%20451.925%20185.033C451.479%20185.262%20450.986%20185.382%20450.485%20185.382C449.984%20185.382%20449.49%20185.262%20449.044%20185.033C448.871%20184.975%20448.72%20184.864%20448.613%20184.715C448.506%20184.566%20448.449%20184.387%20448.449%20184.204C448.449%20184.021%20448.506%20183.842%20448.613%20183.694C448.72%20183.545%20448.871%20183.434%20449.044%20183.375C449.489%20183.144%20449.983%20183.024%20450.485%20183.024C450.986%20183.024%20451.48%20183.144%20451.925%20183.375Z'%20fill='%238C57CC'/%3e%3cpath%20d='M448.471%20184.387C447.988%20182.685%20447.397%20181.016%20446.701%20179.39C446.701%20178.811%20447.904%20179.503%20448.357%20180.582C448.747%20181.722%20449.043%20182.892%20449.242%20184.08C449.242%20184.08%20449.162%20178.504%20450.126%20177.266C450.739%20177.425%20450.365%20183.546%20450.285%20184.012C450.285%20184.012%20452.202%20179.924%20453.472%20179.083C454.05%20179.151%20451.623%20184.194%20451.623%20184.194C451.917%20183.646%20452.317%20183.163%20452.8%20182.773C453.283%20182.383%20453.839%20182.094%20454.436%20181.922C453.824%20182.822%20453.158%20183.683%20452.44%20184.5C452.151%20184.839%20451.776%20185.092%20451.355%20185.234C450.933%20185.376%20450.481%20185.401%20450.047%20185.307C449.73%20185.292%20449.421%20185.2%20449.146%20185.04C448.872%20184.88%20448.64%20184.656%20448.471%20184.387Z'%20fill='%234CA15C'/%3e%3cpath%20d='M562.062%20231.844C564.762%20233.411%20564.773%20235.933%20562.062%20237.523C560.558%20238.292%20558.892%20238.693%20557.203%20238.693C555.513%20238.693%20553.848%20238.292%20552.343%20237.523C549.644%20235.978%20549.633%20233.446%20552.343%20231.844C553.848%20231.076%20555.514%20230.675%20557.203%20230.675C558.892%20230.675%20560.558%20231.076%20562.062%20231.844Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M562.872%20217.955V233.241C562.822%20233.8%20562.625%20234.335%20562.3%20234.792C561.975%20235.249%20561.534%20235.612%20561.023%20235.841C559.619%20236.56%20558.064%20236.935%20556.487%20236.935C554.91%20236.935%20553.355%20236.56%20551.95%20235.841C551.43%20235.609%20550.98%20235.241%20550.649%20234.775C550.318%20234.31%20550.117%20233.764%20550.068%20233.195V217.909C550.119%20218.478%20550.32%20219.023%20550.651%20219.488C550.982%20219.953%20551.43%20220.322%20551.95%20220.555C553.354%20221.276%20554.909%20221.652%20556.487%20221.652C558.064%20221.652%20559.619%20221.276%20561.023%20220.555C561.534%20220.325%20561.974%20219.962%20562.298%20219.505C562.623%20219.048%20562.821%20218.513%20562.872%20217.955Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M560.975%20215.31C563.493%20216.764%20563.504%20219.114%20560.975%20220.557C559.571%20221.277%20558.016%20221.653%20556.439%20221.653C554.861%20221.653%20553.306%20221.277%20551.902%20220.557C549.396%20219.103%20549.385%20216.752%20551.902%20215.31C553.306%20214.588%20554.861%20214.211%20556.439%20214.211C558.016%20214.211%20559.572%20214.588%20560.975%20215.31Z'%20fill='white'/%3e%3cpath%20d='M559.976%20215.889C561.938%20217.024%20561.949%20218.853%20559.976%20219.977C558.883%20220.532%20557.674%20220.821%20556.449%20220.821C555.223%20220.821%20554.015%20220.532%20552.922%20219.977C550.971%20218.841%20550.96%20217.013%20552.922%20215.889C554.015%20215.332%20555.223%20215.042%20556.449%20215.042C557.675%20215.042%20558.883%20215.332%20559.976%20215.889Z'%20fill='%23713336'/%3e%3cpath%20d='M551.538%20218.388C551.538%20218.388%20548.328%20207.701%20547.194%20206.1C547.194%20204.68%20550.12%20206.384%20551.254%20209.03C552.211%20211.836%20552.939%20214.715%20553.432%20217.638C553.432%20217.638%20553.239%20203.92%20555.598%20200.899C557.106%20201.273%20556.165%20216.31%20555.983%20217.445C555.983%20217.445%20560.701%20207.417%20563.82%20205.339C565.226%20205.532%20559.284%20217.911%20559.284%20217.911C559.284%20217.911%20561.733%20213.289%20566.179%20212.437C564.671%20214.643%20563.031%20216.755%20561.268%20218.763C561.268%20218.763%20559.658%20221.227%20555.416%20220.75C555.416%20220.75%20552.479%20220.568%20551.538%20218.388Z'%20fill='%234CA15C'/%3e%3cpath%20opacity='0.35'%20d='M428.648%20256.795C428.648%20263.609%20437.358%20269.173%20448.097%20269.173C458.837%20269.173%20467.547%20263.631%20467.547%20256.795C467.547%20249.958%20458.837%20244.427%20448.097%20244.427C437.358%20244.427%20428.648%20249.958%20428.648%20256.795Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M456.241%20259.475C456.241%20259.475%20455.47%20262.564%20455.935%20263.189C456.315%20263.558%20456.784%20263.824%20457.297%20263.959C457.809%20264.094%20458.348%20264.095%20458.861%20263.961C459.652%20263.615%20460.306%20263.016%20460.721%20262.258C461.912%20261.589%20463.004%20260.755%20463.964%20259.782C464.143%20259.534%20464.239%20259.236%20464.239%20258.93C464.239%20258.624%20464.143%20258.326%20463.964%20258.078C463.084%20257.992%20462.196%20258.046%20461.333%20258.237C460.284%20258.536%20459.254%20258.896%20458.248%20259.316L456.241%20259.475Z'%20fill='%23232839'/%3e%3cpath%20d='M448.361%20255.136C448.361%20255.136%20447.59%20258.237%20448.055%20258.85C448.433%20259.223%20448.902%20259.491%20449.415%20259.627C449.929%20259.762%20450.469%20259.761%20450.981%20259.622C451.772%20259.276%20452.426%20258.677%20452.841%20257.919C454.033%20257.25%20455.125%20256.417%20456.085%20255.443C456.264%20255.195%20456.36%20254.897%20456.36%20254.591C456.36%20254.285%20456.264%20253.987%20456.085%20253.74C455.205%20253.66%20454.318%20253.714%20453.453%20253.899C452.403%20254.213%20451.373%20254.592%20450.369%20255.034L448.361%20255.136Z'%20fill='%23232839'/%3e%3cpath%20d='M472.03%20209.904L462.31%20219.841L452.864%20217.388L462.583%20207.451L472.03%20209.904Z'%20fill='white'/%3e%3cpath%20d='M461.593%20210.515L462.523%20210.867C462.912%20210.584%20463.363%20210.398%20463.838%20210.323C464.313%20210.248%20464.799%20210.286%20465.256%20210.435L466.027%20209.799C465.284%20209.561%20464.495%20209.501%20463.725%20209.625C462.954%20209.75%20462.224%20210.054%20461.593%20210.515Z'%20fill='%23E2EDFF'/%3e%3cpath%20d='M461.47%20210.605C460.563%20211.412%20460.62%20212.365%20461.538%20212.933L462.332%20212.275C461.913%20211.923%20461.924%20211.412%20462.4%20210.957L461.47%20210.605Z'%20fill='%23E2EDFF'/%3e%3cpath%20d='M461.661%20213.004L461.967%20213.141C462.702%20213.372%20463.48%20213.431%20464.241%20213.313C465.002%20213.195%20465.726%20212.903%20466.356%20212.459L465.426%20212.107C465.037%20212.373%20464.593%20212.547%20464.128%20212.616C463.662%20212.685%20463.187%20212.647%20462.738%20212.505L462.443%20212.357L461.661%20213.004Z'%20fill='%233EABFF'/%3e%3cpath%20d='M465.441%20210.516C466.099%20210.857%20466.156%20211.493%20465.555%20212.015L466.485%20212.367C467.505%20211.493%20467.381%20210.414%20466.224%20209.869L465.441%20210.516Z'%20fill='%233EABFF'/%3e%3cpath%20d='M454.053%20241.784C453.679%20244.838%20452.148%20252.856%20451.898%20255.65C451.898%20255.65%20451.263%20256.672%20449.358%20256.422L448.451%20256.036C448.273%20255.966%20448.124%20255.839%20448.027%20255.674C447.93%20255.509%20447.892%20255.317%20447.918%20255.128C448.277%20252.562%20448.417%20249.971%20448.337%20247.382C448.152%20245.793%20448.326%20244.182%20448.848%20242.669C448.779%20241.715%20448.655%20238.411%20450.56%20237.525C450.56%20237.525%20455.232%20236.662%20454.053%20241.784Z'%20fill='%23113569'/%3e%3cpath%20d='M450.171%20238.92L450.681%20239.93C450.681%20239.93%20458.495%20240.316%20460.593%20242.611C461.338%20242.936%20461.951%20243.506%20462.33%20244.226C462.709%20244.946%20462.833%20245.774%20462.68%20246.574C462.294%20249.629%20459.709%20256.988%20459.448%20259.793C459.448%20259.793%20458.813%20260.804%20456.907%20260.554L456.011%20260.179C455.833%20260.106%20455.683%20259.977%20455.585%20259.811C455.487%20259.645%20455.445%20259.451%20455.467%20259.259C455.825%20256.694%20455.969%20254.103%20455.898%20251.514C455.707%20249.928%20455.881%20248.32%20456.408%20246.812C453.973%20247.309%20451.588%20248.032%20449.286%20248.97C445.601%20250.503%20442.425%20248.72%20441.03%20247.948C440.34%20247.607%20439.696%20247.18%20439.114%20246.676C437.859%20246.591%20436.665%20246.101%20435.711%20245.279C434.056%20243.882%20433.806%20240.192%20435.587%20238.022C437.367%20235.853%20450.171%20238.92%20450.171%20238.92Z'%20fill='%23113C7A'/%3e%3cpath%20d='M447.385%20219.567C447.385%20219.567%20447.147%20219.567%20447.226%20217.898C447.333%20217.17%20447.575%20216.469%20447.941%20215.831C447.941%20215.831%20445.287%20214.003%20443.155%20214.514C442.456%20215.949%20441.503%20217.246%20440.342%20218.341C440.342%20218.341%20441.533%20221.487%20447.385%20219.567Z'%20fill='%23FF8654'/%3e%3cpath%20d='M444.618%20220.518C444.618%20220.518%20439.946%20216.611%20438.948%20216.52C438.305%20216.397%20437.64%20216.527%20437.091%20216.882C436.542%20217.238%20436.151%20217.791%20435.999%20218.428C435.83%20219.054%20435.868%20219.717%20436.107%20220.319C436.347%20220.921%20436.774%20221.429%20437.326%20221.767C438.188%20222.244%20445.718%20225.867%20447.056%20225.867C447.366%20225.894%20447.676%20225.828%20447.948%20225.678C448.22%20225.528%20448.441%20225.3%20448.583%20225.024C448.725%20224.747%20448.782%20224.435%20448.747%20224.126C448.711%20223.817%20448.585%20223.526%20448.383%20223.289C447.578%20221.858%20444.618%20220.518%20444.618%20220.518Z'%20fill='%23113569'/%3e%3cpath%20d='M443.189%20217.922C443.189%20217.922%20448.144%20219.569%20449.539%20221.863C450.934%20224.157%20450.673%20226.701%20449.675%20230.267C448.677%20233.832%20450.685%20237.012%20450.174%20238.92C449.664%20240.828%20446.114%20242.611%20440.898%20241.714C435.681%20240.817%20435.307%20238.795%20434.932%20237.648C434.558%20236.501%20435.942%20231.027%20434.672%20226.576C434.209%20225.124%20434.176%20223.569%20434.579%20222.099C434.982%20220.63%20435.802%20219.309%20436.94%20218.297C437.983%20217.536%20440.013%20216.525%20443.189%20217.922Z'%20fill='%23113C7A'/%3e%3cpath%20d='M447.931%20220.036C447.931%20220.036%20446.593%20220.899%20443.259%20220.422C439.924%20219.945%20439.732%20217.561%20440.015%20217.368C440.333%20217.079%20440.622%20216.759%20440.877%20216.414C440.877%20216.414%20444.404%20218.038%20445.64%20218.515C446.876%20218.992%20447.546%20219.275%20447.546%20219.275L447.931%20220.036Z'%20fill='white'/%3e%3cpath%20d='M433.505%20262.056C433.675%20263.975%20435.489%20265.292%20437.122%20265.997C438.92%20266.735%20440.851%20267.091%20442.793%20267.041C444.784%20267.049%20446.751%20266.615%20448.554%20265.769C450.108%20265.008%20451.752%20263.623%20451.741%20261.738C451.815%20262.376%20451.758%20263.023%20451.572%20263.638C451.387%20264.254%20451.078%20264.824%20450.663%20265.315C449.293%20266.629%20447.557%20267.497%20445.685%20267.802C442.169%20268.529%20437.383%20268.177%20434.718%20265.531C434.262%20265.04%20433.916%20264.456%20433.705%20263.819C433.493%20263.182%20433.421%20262.507%20433.493%20261.84C433.493%20261.84%20433.493%20261.931%20433.505%20262.056Z'%20fill='%23ADCDFC'/%3e%3cpath%20d='M436.181%20257.981C432.609%20260.048%20432.586%20263.398%20436.181%20265.465C438.18%20266.484%20440.391%20267.015%20442.634%20267.015C444.877%20267.015%20447.088%20266.484%20449.087%20265.465C452.659%20263.398%20452.671%20260.048%20449.087%20257.981C447.089%20256.96%20444.877%20256.427%20442.634%20256.427C440.391%20256.427%20438.179%20256.96%20436.181%20257.981Z'%20fill='white'/%3e%3cpath%20d='M440.983%20253.808L441.005%20261.791L442.4%20262.598L442.378%20254.614L440.983%20253.808Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M442.377%20254.614L442.4%20262.598L443.806%20261.791L443.784%20253.808L442.377%20254.614Z'%20fill='%237BAEFF'/%3e%3cpath%20d='M440.983%20253.808L442.378%20254.614L443.784%20253.808L442.389%20252.99L440.983%20253.808Z'%20fill='%234DA5DC'/%3e%3cpath%20d='M424.542%20224.136C424.549%20223.878%20424.616%20223.626%20424.739%20223.399C424.862%20223.172%20425.037%20222.977%20425.249%20222.831C425.462%20222.685%20425.706%20222.591%20425.961%20222.557C426.217%20222.524%20426.477%20222.551%20426.719%20222.637C431.256%20224.238%20441.905%20230.439%20442.597%20231.722C443.288%20233.006%20445.307%20240.16%20446.316%20243.749C446.386%20243.991%20446.509%20244.213%20446.677%20244.4C446.846%20244.586%20447.055%20244.732%20447.288%20244.825C447.521%20244.918%20447.772%20244.957%20448.023%20244.938C448.273%20244.918%20448.516%20244.842%20448.732%20244.714L455.049%20240.989C455.317%20240.828%20455.626%20240.748%20455.938%20240.757C456.251%20240.766%20456.554%20240.866%20456.812%20241.043C457.07%20241.22%20457.272%20241.467%20457.394%20241.756C457.516%20242.044%20457.552%20242.362%20457.499%20242.67L456.489%20248.769C456.448%20249.006%20456.354%20249.231%20456.214%20249.427C456.075%20249.624%20455.894%20249.787%20455.684%20249.904L448.88%20253.8C447.018%20254.868%20444.922%20255.459%20442.777%20255.521C440.632%20255.582%20438.505%20255.112%20436.586%20254.152L431.381%20251.54C426.844%20249.268%20424.02%20243.056%20424.202%20237.912L424.542%20224.136Z'%20fill='%233278CC'/%3e%3cpath%20d='M442.574%20231.776C443.209%20233.06%20445.285%20240.214%20446.294%20243.803C446.363%20244.045%20446.487%20244.267%20446.655%20244.454C446.824%20244.64%20447.032%20244.786%20447.266%20244.879C447.499%20244.972%20447.75%20245.011%20448%20244.991C448.251%20244.972%20448.493%20244.896%20448.71%20244.768L455.027%20241.043C455.295%20240.882%20455.604%20240.801%20455.916%20240.811C456.229%20240.82%20456.532%20240.919%20456.79%20241.096C457.048%20241.273%20457.25%20241.521%20457.372%20241.809C457.493%20242.098%20457.53%20242.415%20457.476%20242.724L456.467%20248.822C456.443%20248.96%20456.401%20249.093%20456.342%20249.22L456.093%20249.606C455.971%20249.751%20455.825%20249.874%20455.662%20249.969L448.857%20253.865C447.456%20254.668%20445.918%20255.203%20444.321%20255.443C438.843%20251.185%20439.535%20233.412%20441.52%20231.913C441.758%20231.731%20442.022%20231.586%20442.302%20231.481C442.407%20231.565%20442.499%20231.665%20442.574%20231.776Z'%20fill='%233AAEEF'/%3e%3cpath%20d='M455.052%20225.713C455.052%20225.713%20449.619%20221.068%20448.667%20220.966C447.533%20220.875%20446.591%20222.635%20446.206%20224.259C446.038%20224.886%20446.078%20225.55%20446.319%20226.152C446.56%20226.754%20446.99%20227.261%20447.544%20227.598C448.406%20228.075%20455.936%20231.709%20457.263%20231.709C457.625%20231.697%20457.978%20231.596%20458.29%20231.415C458.603%20231.233%20458.867%20230.977%20459.056%20230.669C459.246%20230.361%20459.357%20230.01%20459.378%20229.648C459.4%20229.287%20459.332%20228.926%20459.18%20228.597C458.318%20227.189%20455.052%20225.713%20455.052%20225.713Z'%20fill='%23113C7A'/%3e%3cpath%20d='M461.368%20220.179C461.498%20219.92%20461.593%20219.645%20461.652%20219.362C461.581%20218.857%20461.581%20218.345%20461.652%20217.84C461.844%20217.079%20462.173%20216.409%20462.321%20215.875C462.695%20215.398%20463.035%20216.261%20462.752%20217.011C462.468%20217.76%20462.559%20218.146%20462.842%20218.203C463.523%20218.007%20464.145%20217.648%20464.657%20217.158C464.986%20216.772%20466.925%20214.887%20467.084%20215.148C467.243%20215.409%20467.277%20215.625%20466.608%20216.341C466.21%20216.689%20465.886%20217.114%20465.655%20217.59C465.625%20217.918%20465.545%20218.24%20465.417%20218.544C465.179%20219.112%20465.417%20219.498%20464.94%20220.02C464.464%20220.543%20463.704%20220.633%20463.319%20220.974L462.933%20221.304L461.368%20220.179Z'%20fill='%23FFAA83'/%3e%3cpath%20d='M457.265%20231.727C457.911%20231.803%20458.564%20231.662%20459.122%20231.327C459.68%20230.992%20460.111%20230.482%20460.35%20229.876C461.427%20227.605%20463.276%20221.665%20463.525%20221.097C463.317%20220.678%20462.992%20220.329%20462.59%20220.091C462.187%20219.853%20461.724%20219.737%20461.257%20219.757C461.257%20219.757%20459.477%20223.255%20458.456%20224.857C457.435%20226.458%20453.863%20231.091%20457.265%20231.727Z'%20fill='%23113C7A'/%3e%3cpath%20d='M450.551%20210.085C450.551%20211.163%20450.232%20212.217%20449.634%20213.113C449.036%20214.01%20448.186%20214.709%20447.191%20215.121C446.196%20215.534%20445.102%20215.642%20444.046%20215.431C442.99%20215.221%20442.02%20214.702%20441.259%20213.94C440.497%20213.177%20439.979%20212.206%20439.769%20211.148C439.559%20210.091%20439.667%20208.995%20440.079%20207.999C440.491%20207.003%20441.188%20206.151%20442.083%20205.552C442.979%20204.953%20444.031%20204.634%20445.108%20204.634C445.823%20204.632%20446.532%20204.772%20447.193%20205.046C447.854%20205.319%20448.455%20205.721%20448.96%20206.227C449.466%20206.734%20449.867%20207.335%20450.14%20207.997C450.413%20208.659%20450.553%20209.369%20450.551%20210.085Z'%20fill='%23FF8654'/%3e%3cpath%20d='M450.553%20210.449C450.553%20210.449%20450.621%20215.911%20449.419%20217.013C448.217%20218.114%20446.402%20215.979%20443.488%20215.298C440.573%20214.617%20445.847%20208.87%20445.847%20208.87L450.553%20210.449Z'%20fill='%23FF8654'/%3e%3cpath%20d='M440.533%20205.61C440.533%20205.61%20446.351%20202.203%20449.605%20205.031C452.86%20207.859%20449.14%20208.983%20448.562%20209.801C447.984%20210.619%20448.562%20211.277%20448.256%20211.868C447.95%20212.458%20447.859%20212.561%20447.859%20212.561L448.063%20213.265L447.711%20213.571C447.711%20213.571%20447.246%20212.254%20446.815%20212.288C446.385%20212.322%20446.044%20213.185%20446.192%20213.685C446.339%20214.185%20446.781%20214.741%20446.702%20215.093C446.623%20215.445%20446.158%20216.41%20445.727%20216.444C444.688%20216.361%20443.67%20216.112%20442.71%20215.706C441.201%20214.78%20439.998%20213.429%20439.251%20211.822C439.028%20211.25%20438.94%20210.633%20438.993%20210.021C439.046%20209.408%20439.239%20208.816%20439.557%20208.29C439.413%20207.798%20439.43%20207.272%20439.606%20206.79C439.781%20206.308%20440.106%20205.895%20440.533%20205.61Z'%20fill='%2396432A'/%3e%3cpath%20opacity='0.43'%20d='M668.681%20149.759L684.513%20149.656L717.481%20131.043L699.2%20122.037L668.681%20149.759Z'%20fill='%23A6D0F4'/%3e%3cpath%20opacity='0.35'%20d='M688.581%20112.949C698.196%20112.949%20705.99%20107.991%20705.99%20101.876C705.99%2095.7606%20698.196%2090.8032%20688.581%2090.8032C678.967%2090.8032%20671.173%2095.7606%20671.173%20101.876C671.173%20107.991%20678.967%20112.949%20688.581%20112.949Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M675.418%2099.2895C675.623%20101.561%20677.766%20103.117%20679.694%20103.957C681.817%20104.836%20684.1%20105.258%20686.396%20105.195C688.748%20105.202%20691.072%20104.686%20693.201%20103.685C695.027%20102.787%20696.977%20101.141%20696.977%2098.9148C697.064%2099.6711%20696.995%20100.437%20696.774%20101.166C696.554%20101.894%20696.187%20102.57%20695.696%20103.151C694.076%20104.711%20692.018%20105.737%20689.799%20106.092C685.637%20106.955%20679.977%20106.535%20676.825%20103.333C676.293%20102.748%20675.893%20102.057%20675.65%20101.304C675.408%20100.552%20675.329%2099.7568%20675.418%2098.9716V99.2895Z'%20fill='%23ADCDFC'/%3e%3cpath%20d='M678.556%2095.1075C674.326%2097.5491%20674.292%20101.513%20678.556%20103.966C680.923%20105.17%20683.54%20105.797%20686.194%20105.797C688.849%20105.797%20691.466%20105.17%20693.832%20103.966C698.063%20101.513%20698.074%2097.5491%20693.832%2095.1075C691.468%2093.8964%20688.85%2093.2649%20686.194%2093.2649C683.539%2093.2649%20680.921%2093.8964%20678.556%2095.1075Z'%20fill='white'/%3e%3cpath%20d='M685.004%2091.8394L685.026%20100.845L686.16%20101.504L686.138%2092.498L685.004%2091.8394Z'%20fill='%23C7D8F2'/%3e%3cpath%20d='M686.144%2092.498L686.166%20101.504L687.3%20100.845L687.278%2091.8394L686.144%2092.498Z'%20fill='%237BAEFF'/%3e%3cpath%20d='M684.482%2090.2053L686.138%2091.1593L687.793%2090.2053L686.149%2089.24L684.482%2090.2053Z'%20fill='%234DA5DC'/%3e%3cpath%20d='M696.881%2059.5533C696.881%2059.5533%20700.283%2061.5521%20701.179%2063.5849C702.075%2065.6177%20701.837%2079.893%20697.096%2086.2186C692.356%2092.5442%20683.567%2093.4414%20681.537%2092.5442C679.507%2091.647%20667.769%2085.7302%20666.873%2082.823C665.977%2079.9157%20670.479%2077.633%20672.963%2076.4974C675.447%2075.3617%20677.023%2073.7831%20678.373%2069.6834C679.722%2065.5837%20680.403%2058.6107%20681.99%2057.4864C683.578%2056.3621%20687.4%2054.5791%20696.881%2059.5533Z'%20fill='%2325437F'/%3e%3cpath%20d='M680.029%2090.57C678.374%2089.8318%20670.265%2085.8002%20666.84%2082.734C666.114%2079.8608%20670.514%2077.6576%20672.964%2076.5446C675.414%2075.4317%20677.024%2073.8304%20678.374%2069.7307C679.723%2065.6309%20680.404%2058.658%20681.991%2057.5337C683.579%2056.4094%20687.401%2054.5923%20696.882%2059.5665C697.895%2060.1825%20698.845%2060.8977%20699.717%2061.7016C700.568%2064.0751%20700.261%2077.9869%20695.589%2084.2103C690.917%2090.4337%20682.059%2091.4331%20680.029%2090.57Z'%20fill='%23254DA1'/%3e%3cpath%20d='M609.514%20118.378L606.985%20116.902L606.917%2087.9197L609.446%2089.396L609.514%20118.378Z'%20fill='%23CB6A50'/%3e%3cpath%20d='M609.446%2089.395L606.917%2087.9186L641.359%2068.0105L643.899%2069.4869L609.446%2089.395Z'%20fill='%23DBDBDB'/%3e%3cpath%20d='M643.9%2069.4895L643.968%2098.4715L609.515%20118.38L609.447%2089.3976L643.9%2069.4895Z'%20fill='%239966D7'/%3e%3cpath%20d='M611.92%2083.8906L611.852%20112.873L670.768%20146.886L670.836%20117.904L611.92%2083.8906Z'%20fill='%23A478D9'/%3e%3cpath%20d='M611.887%20100.108L670.791%20134.121L670.837%20117.904L611.921%2083.8906L611.887%20100.108Z'%20fill='%238C57CC'/%3e%3cpath%20d='M668.621%20149.703L666.092%20148.238L666.024%20119.256L668.553%20120.732L668.621%20149.703Z'%20fill='%238C57CC'/%3e%3cpath%20d='M668.553%20120.731L666.024%20119.254L700.466%2099.335L703.007%20100.811L668.553%20120.731Z'%20fill='%23DBDBDB'/%3e%3cpath%20d='M703.008%20100.814L703.076%20129.796L668.622%20149.704L668.554%20120.733L703.008%20100.814Z'%20fill='%23976EC9'/%3e%3cpath%20d='M707.733%20100.052L707.722%20102.778L668.664%20125.513V122.788L707.733%20100.052Z'%20fill='%238C57CC'/%3e%3cpath%20d='M668.663%20122.79V125.515L601.151%2086.2214L601.163%2083.4958L668.663%20122.79Z'%20fill='%238C57CC'/%3e%3cpath%20d='M707.738%20100.054L668.669%20122.79L601.168%2083.496L640.226%2060.7715L707.738%20100.054Z'%20fill='%23B195D2'/%3e%3cpath%20d='M670.777%20104.115L678.67%20108.703L691.429%20101.332L683.535%2096.7441L670.777%20104.115Z'%20fill='%238C57CC'/%3e%3cpath%20d='M669.325%20101.393L669.336%20103.358L677.229%20107.946L677.218%20105.981L669.325%20101.393Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M677.216%20105.977L677.227%20107.942L689.985%20100.56L689.974%2098.6069L677.216%20105.977Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M669.325%20101.392L677.218%20105.98L689.976%2098.6096L682.094%2094.0215L669.325%20101.392Z'%20fill='white'/%3e%3cpath%20d='M659.536%2094.9864L667.429%2099.5858L680.188%2092.204L672.294%2087.616L659.536%2094.9864Z'%20fill='white'/%3e%3cpath%20d='M666.398%2086.2649C668.212%2087.3097%20668.212%2089.0018%20666.398%2090.0353L654.853%2096.7584C653.847%2097.2737%20652.733%2097.5424%20651.604%2097.5424C650.474%2097.5424%20649.36%2097.2737%20648.355%2096.7584L636.73%2090.0353C634.938%2089.0018%20634.927%2087.3097%20636.73%2086.2649L648.275%2079.5532C649.283%2079.0378%20650.398%2078.769%20651.53%2078.769C652.662%2078.769%20653.777%2079.0378%20654.785%2079.5532L666.398%2086.2649Z'%20fill='%238C57CC'/%3e%3cpath%20d='M656.133%2088.0245C656.135%2088.0548%20656.135%2088.0852%20656.133%2088.1154L656.065%2088.1949H655.997H655.929L651.131%2090.8637L645.926%2087.9905V88.2971L651.086%2091.2839L655.883%2088.6264H655.94L656.008%2088.5583C656.01%2088.5243%20656.01%2088.4902%20656.008%2088.4561V88.0927C656.044%2088.0612%20656.087%2088.0379%20656.133%2088.0245Z'%20fill='%23BAC0D2'/%3e%3cpath%20d='M655.849%2087.5369C655.929%2087.5648%20655.999%2087.617%20656.048%2087.6861C656.097%2087.7553%20656.123%2087.8381%20656.123%2087.923C656.123%2088.0079%20656.097%2088.0907%20656.048%2088.1599C655.999%2088.2291%20655.929%2088.2812%20655.849%2088.3091L651.052%2090.9779L645.926%2087.9912L649.963%2084.9022C650.169%2084.7928%20650.399%2084.7356%20650.632%2084.7356C650.866%2084.7356%20651.095%2084.7928%20651.302%2084.9022L655.849%2087.5369Z'%20fill='white'/%3e%3cpath%20d='M662.942%2076.2336C663.158%2076.369%20663.344%2076.5463%20663.49%2076.755C663.636%2076.9637%20663.739%2077.1996%20663.793%2077.4488L666.276%2094.1202C666.333%2094.5518%20666.061%2094.7108%20665.653%2094.4836L640.396%2079.8564C640.183%2079.7221%20639.999%2079.5464%20639.855%2079.3396C639.711%2079.1329%20639.61%2078.8992%20639.557%2078.6526L637.074%2061.9811C637.006%2061.5382%20637.289%2061.3792%20637.686%2061.6177L662.942%2076.2336Z'%20fill='%23C7C9D7'/%3e%3cpath%20d='M666.672%2093.9753V93.8504L664.2%2077.1789V76.9404V76.8382V76.736L664.12%2076.6338L638.864%2062.0179H637.991H637.64C637.631%2062.0129%20637.621%2062.0103%20637.611%2062.0103C637.601%2062.0103%20637.592%2062.0129%20637.583%2062.0179L637.175%2062.3131C637.205%2062.307%20637.235%2062.307%20637.265%2062.3131H637.39H637.526L637.674%2062.3926L662.941%2076.2363L663.1%2076.3385L663.236%2076.4634L663.372%2076.6111C663.42%2076.659%20663.462%2076.7124%20663.497%2076.7701C663.535%2076.8243%20663.569%2076.8812%20663.599%2076.9404L663.678%2077.1108L663.746%2077.2811C663.752%2077.3378%20663.752%2077.3948%20663.746%2077.4515L666.23%2094.1229C666.236%2094.1682%20666.236%2094.214%20666.23%2094.2592C666.236%2094.2968%20666.236%2094.3352%20666.23%2094.3728V94.4409C666.218%2094.4777%20666.194%2094.5096%20666.162%2094.5318L666.559%2094.2365C666.594%2094.21%20666.621%2094.1748%20666.638%2094.1343V93.9753H666.672Z'%20fill='white'/%3e%3cpath%20opacity='0.2'%20d='M648.944%2085.6511L645.882%2087.9906L651.042%2090.9774L654.671%2088.9559L648.944%2085.6511Z'%20fill='%23777DB2'/%3e%3cpath%20d='M652.132%2080.7118L651.044%2091.3642L645.861%2088.3548L647.891%2078.395L652.132%2080.7118Z'%20fill='%23BAC0D2'/%3e%3cpath%20d='M606.644%20113.464C606.644%20113.464%20607.846%20115.349%20607.676%20116.031C607.506%20116.712%20606.644%20115.69%20606.644%20115.69C606.644%20115.69%20606.905%20117.961%20606.304%20118.438C605.703%20118.915%20605.442%20117.496%20605.442%20117.496C605.2%20117.659%20604.905%20117.723%20604.618%20117.674C604.331%20117.625%20604.074%20117.468%20603.899%20117.234C603.593%20116.631%20603.448%20115.958%20603.478%20115.281C603.507%20114.605%20603.711%20113.948%20604.07%20113.373C604.761%20112.26%20606.644%20113.464%20606.644%20113.464Z'%20fill='%23FF9554'/%3e%3cpath%20d='M610.772%2081.4148C610.772%2081.4148%20607.574%2081.3013%20606.089%2085.7644C604.603%2090.2275%20604.036%2097.2118%20603.82%2099.2674C603.605%20101.323%20603.503%20112.804%20603.616%20113.372C603.787%20113.662%20604.025%20113.906%20604.311%20114.083C604.597%20114.259%20604.922%20114.363%20605.257%20114.386C605.593%20114.408%20605.928%20114.348%20606.235%20114.211C606.542%20114.074%20606.811%20113.864%20607.019%20113.599C607.937%20111.544%20607.914%20102.583%20608.935%2099.1538C609.956%2095.7241%20612.485%2087.025%20612.598%2084.6174C612.652%2083.9614%20612.507%2083.3043%20612.181%2082.7326C611.855%2082.161%20611.364%2081.7016%20610.772%2081.4148Z'%20fill='%23113569'/%3e%3cpath%20d='M631.99%2074.4519C632%2073.9354%20632.084%2073.4229%20632.239%2072.9302C632.5%2072.2033%20631.729%2071.0563%20631.525%2070.3977C631.321%2069.739%20631.525%2069.5005%20631.979%2069.5459C632.432%2069.5913%20633.305%2071.5333%20633.498%2071.8172C633.691%2072.1011%20634.984%2070.2273%20635.381%2070.1592C635.778%2070.091%20636.152%2070.7043%20636.118%2071.1926C636.084%2071.6809%20637.105%2072.862%20636.628%2074.0318C636.152%2075.2015%20634.882%2076.1214%20634.36%2075.8715C633.838%2075.6217%20631.99%2074.4519%20631.99%2074.4519Z'%20fill='%23FF9554'/%3e%3cpath%20opacity='0.35'%20d='M595.057%20146.604C595.057%20153.895%20604.345%20159.812%20615.822%20159.812C627.299%20159.812%20636.575%20153.895%20636.575%20146.604C636.575%20139.313%20627.287%20133.396%20615.822%20133.396C604.356%20133.396%20595.057%20139.302%20595.057%20146.604Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M609.731%20143.59C609.312%20143.793%20608.966%20144.119%20608.738%20144.525C608.511%20144.932%20608.414%20145.398%20608.461%20145.861C608.471%20146.284%20608.551%20146.703%20608.699%20147.099C609.058%20147.392%20609.5%20147.564%20609.962%20147.59C610.424%20147.617%20610.883%20147.497%20611.273%20147.247C612.257%20146.565%20613.04%20145.632%20613.541%20144.544C614.141%20143.727%20614.657%20142.852%20615.084%20141.932C615.197%20141.285%20614.471%20140.796%20613.802%20140.887C612.512%20141.591%20611.29%20142.412%20610.15%20143.34C610.031%20143.434%20609.902%20143.514%20609.765%20143.579L609.731%20143.59Z'%20fill='%23232839'/%3e%3cpath%20d='M608.507%20106.594C608.507%20106.594%20608.235%20115.679%20608.575%20121.187C608.881%20126.093%20608.45%20140.3%20608.348%20143.457C608.321%20143.895%20608.429%20144.331%20608.655%20144.706C608.882%20145.082%20609.218%20145.379%20609.618%20145.558C609.952%20145.679%20610.31%20145.719%20610.663%20145.675C611.016%20145.632%20611.353%20145.506%20611.648%20145.308C611.902%20145.155%20612.121%20144.949%20612.289%20144.704C612.457%20144.459%20612.571%20144.181%20612.624%20143.889C613.236%20140.936%20615.277%20130.874%20615.572%20125.775C615.912%20119.767%20616.219%20112.261%20616.559%20109.876C616.899%20107.491%20608.507%20106.594%20608.507%20106.594Z'%20fill='%23113569'/%3e%3cpath%20d='M621.192%20146.817C620.742%20146.924%20620.336%20147.167%20620.028%20147.512C619.72%20147.857%20619.525%20148.288%20619.468%20148.747C619.399%20149.165%20619.399%20149.591%20619.468%20150.008C619.764%20150.36%20620.16%20150.614%20620.604%20150.736C621.047%20150.858%20621.517%20150.841%20621.952%20150.689C623.07%20150.245%20624.047%20149.502%20624.775%20148.543C625.538%20147.857%20626.23%20147.096%20626.839%20146.272C626.881%20146.117%20626.885%20145.954%20626.851%20145.797C626.818%20145.64%20626.748%20145.493%20626.648%20145.368C626.547%20145.243%20626.419%20145.144%20626.273%20145.078C626.127%20145.012%20625.968%20144.981%20625.807%20144.988C624.401%20145.401%20623.034%20145.941%20621.725%20146.601C621.586%20146.666%20621.442%20146.719%20621.294%20146.76L621.192%20146.817Z'%20fill='%23232839'/%3e%3cpath%20d='M623.76%20108.367C623.76%20108.367%20624.225%20136.213%20623.216%20146.298C623.212%20146.63%20623.135%20146.958%20622.991%20147.258C622.847%20147.557%20622.638%20147.821%20622.381%20148.032C622.123%20148.242%20621.823%20148.393%20621.501%20148.474C621.179%20148.555%20620.843%20148.564%20620.517%20148.501C620.347%20148.501%20619.201%20148.785%20619.008%20148.705C618.101%20148.365%20617.137%20121.449%20616.332%20118.326C615.527%20115.203%20613.134%20112.943%20613.361%20108.367C613.588%20103.79%20620.449%20106.084%20623.76%20108.367Z'%20fill='%23113C7A'/%3e%3cpath%20d='M624.303%20110.578C623.906%20112.599%20618.077%20113.121%20614.72%20112.576C611.363%20112.031%20607.405%20111.27%20607.518%20107.375C607.518%20107.375%20607.836%2089.92%20607.836%2086.8537C607.882%2084.9035%20608.554%2083.0201%20609.752%2081.482C609.752%2081.482%20611.635%2079.3356%20617.544%2080.5394C617.544%2080.5394%20622.352%2081.5842%20624.575%2085.1502C624.575%2085.1502%20626.423%2088.5572%20625.913%2096.6885C625.647%20101.346%20625.11%20105.983%20624.303%20110.578Z'%20fill='%23113C7A'/%3e%3cpath%20d='M612.926%2076.2691C613.196%2077.7025%20613.196%2079.1739%20612.926%2080.6073C612.846%2081.2887%20615.817%2083.5827%20618.448%2082.9808C619.98%2082.6401%20619.9%2081.8452%20619.9%2081.8452C619.153%2080.5839%20618.761%2079.1436%20618.766%2077.6773C618.959%2075.6672%20614.717%2075.8035%20612.926%2076.2691Z'%20fill='%23FF7C40'/%3e%3cpath%20d='M621.268%2082.0607L619.442%2081.0273C619.442%2081.0273%20614.758%2080.5957%20613.08%2079.4941L612.207%2080.7434C612.646%2081.4711%20613.254%2082.0829%20613.978%2082.5274C614.702%2082.972%20615.522%2083.2364%20616.369%2083.2986C617.889%2083.572%20619.457%2083.2596%20620.758%2082.4241L621.268%2082.0607Z'%20fill='%23E1E8F2'/%3e%3cpath%20d='M622.655%2084.6527C622.293%2084.6577%20621.937%2084.7455%20621.614%2084.9091C621.291%2085.0728%20621.009%2085.3081%20620.79%2085.5972C620.572%2085.8863%20620.422%2086.2215%20620.352%2086.5774C620.282%2086.9332%20620.294%2087.3003%20620.387%2087.6508C620.61%2088.525%20621.1%2089.3074%20621.79%2089.888C622.48%2090.4685%20623.334%2090.8181%20624.232%2090.8874C629.029%2091.6029%20638.362%2087.4805%20639.451%2085.3795C640.54%2083.2785%20637.036%2075.4766%20635.425%2074.2841C634.064%2073.4324%20631.807%2074.7384%20632.023%2075.8627C632.238%2076.987%20634.2%2082.5631%20634.291%2082.8583C634.382%2083.1536%20634.11%2083.165%20634.11%2083.165L624.504%2084.5164C623.89%2084.593%20623.273%2084.6385%20622.655%2084.6527Z'%20fill='%23113C7A'/%3e%3cpath%20d='M621.512%2071.262C621.525%2072.4014%20621.2%2073.519%20620.578%2074.4729C619.955%2075.4269%20619.064%2076.174%20618.017%2076.6194C616.969%2077.0648%20615.814%2077.1884%20614.696%2076.9744C613.578%2076.7604%20612.55%2076.2186%20611.74%2075.4177C610.931%2074.6168%20610.377%2073.5931%20610.15%2072.4765C609.923%2071.36%20610.033%2070.2011%20610.465%2069.1471C610.898%2068.0931%20611.633%2067.1916%20612.578%2066.5571C613.523%2065.9226%20614.635%2065.5838%20615.773%2065.5837C617.282%2065.5866%20618.73%2066.1836%20619.804%2067.2459C620.877%2068.3083%20621.491%2069.7508%20621.512%2071.262Z'%20fill='%23FF8654'/%3e%3cpath%20d='M621.513%2071.6276C621.513%2071.6276%20621.581%2077.374%20620.379%2078.5437C619.177%2079.7134%20617.204%2077.4081%20614.13%2076.738C611.057%2076.068%20616.625%2069.9241%20616.625%2069.9241L621.513%2071.6276Z'%20fill='%23FF8654'/%3e%3cpath%20d='M610.956%2066.5292C610.956%2066.5292%20617.091%2062.9746%20620.516%2065.916C623.941%2068.8573%20620.028%2070.0952%20619.382%2070.947C618.735%2071.7987%20619.382%2072.5028%20619.053%2073.1161C618.724%2073.7293%20618.645%2073.8542%20618.645%2073.8542L618.849%2074.5924L618.486%2074.9218C618.486%2074.9218%20618.021%2073.5363%20617.579%2073.5363C617.136%2073.5363%20616.762%2074.4789%20616.921%2075.0126C617.08%2075.5464%20617.533%2076.1483%20617.454%2076.4776C617.375%2076.8069%20616.887%2077.8745%20616.433%2077.9199C615.337%2077.8264%20614.261%2077.562%20613.246%2077.1363C611.663%2076.1551%20610.399%2074.7349%20609.606%2073.0479C609.371%2072.4436%20609.278%2071.793%20609.335%2071.1469C609.392%2070.5008%20609.597%2069.8766%20609.935%2069.323C609.789%2068.809%20609.809%2068.262%20609.992%2067.7602C610.176%2067.2584%20610.513%2066.8275%20610.956%2066.5292Z'%20fill='%2396432A'/%3e%3cpath%20d='M236.658%20220.478L247.715%20223.442L236.703%20239.171L236.692%20235.049L213.886%20248.234L213.863%20238.444L236.669%20225.259L236.658%20220.478Z'%20fill='white'/%3e%3cpath%20d='M607.506%20199.468L618.564%20202.432L607.552%20218.161L607.54%20214.039L584.734%20227.223L584.711%20217.434L607.518%20204.249L607.506%20199.468Z'%20fill='white'/%3e%3cpath%20d='M361.999%20210.934L372.898%20226.061L361.954%20228.559L361.965%20224.596L337.537%20210.48L337.56%20200.781L361.988%20214.898L361.999%20210.934Z'%20fill='white'/%3e%3cpath%20d='M84.669%20223.126C84.669%20223.126%2085.8712%20225.011%2085.7011%20225.704C85.5309%20226.396%2084.669%20225.352%2084.669%20225.352C84.669%20225.352%2084.9299%20227.623%2084.3288%20228.1C83.7277%20228.577%2083.4783%20227.157%2083.4783%20227.157C83.2359%20227.324%2082.9385%20227.39%2082.6487%20227.341C82.3589%20227.292%2082.0993%20227.133%2081.9246%20226.896C81.6177%20226.292%2081.4731%20225.618%2081.505%20224.941C81.5368%20224.264%2081.7439%20223.607%2082.106%20223.035C82.7865%20221.922%2084.669%20223.126%2084.669%20223.126Z'%20fill='%23FF9554'/%3e%3cpath%20d='M88.7642%20191.074C88.7642%20191.074%2085.5547%20190.961%2084.0691%20195.424C82.5834%20199.887%2082.0164%20206.872%2081.8009%20208.927C81.5854%20210.983%2081.4834%20222.464%2081.5968%20223.032C81.7673%20223.322%2082.0059%20223.566%2082.292%20223.742C82.578%20223.919%2082.9027%20224.023%2083.238%20224.045C83.5733%20224.068%2083.9089%20224.008%2084.2158%20223.871C84.5227%20223.734%2084.7916%20223.524%2084.999%20223.259C85.9063%20221.204%2085.8836%20212.255%2086.9043%20208.813C87.925%20205.372%2090.454%20196.685%2090.5674%20194.277C90.6235%20193.624%2090.4815%20192.968%2090.1598%20192.397C89.8381%20191.826%2089.3517%20191.365%2088.7642%20191.074Z'%20fill='%23113569'/%3e%3cpath%20opacity='0.35'%20d='M93.849%20269.47C105.317%20269.47%20114.614%20263.556%20114.614%20256.262C114.614%20248.967%20105.317%20243.054%2093.849%20243.054C82.3808%20243.054%2073.0839%20248.967%2073.0839%20256.262C73.0839%20263.556%2082.3808%20269.47%2093.849%20269.47Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M87.7696%20253.262C87.3488%20253.462%2087%20253.788%2086.7707%20254.195C86.5414%20254.601%2086.4427%20255.068%2086.4881%20255.533C86.501%20255.956%2086.5814%20256.374%2086.7262%20256.771C87.0908%20257.053%2087.5323%20257.216%2087.9922%20257.241C88.452%20257.265%2088.9084%20257.149%2089.3006%20256.907C90.2813%20256.227%2091.064%20255.298%2091.5688%20254.216C92.1687%20253.395%2092.6854%20252.516%2093.1111%20251.592C93.2359%20250.956%2092.4987%20250.457%2091.8296%20250.559C90.5388%20251.261%2089.3163%20252.082%2088.1778%20253.012C88.0587%20253.102%2087.9292%20253.179%2087.7923%20253.239L87.7696%20253.262Z'%20fill='%23232839'/%3e%3cpath%20d='M86.4744%20216.253C86.4744%20216.253%2086.2022%20225.339%2086.5424%20230.847C86.8486%20235.753%2086.4177%20249.96%2086.327%20253.117C86.2944%20253.554%2086.3979%20253.991%2086.6233%20254.367C86.8487%20254.744%2087.1849%20255.041%2087.5858%20255.218C87.9192%20255.34%2088.2766%20255.382%2088.6291%20255.341C88.9817%20255.299%2089.3197%20255.175%2089.6158%20254.979C89.8692%20254.822%2090.0869%20254.614%2090.2549%20254.367C90.4229%20254.121%2090.5374%20253.842%2090.5911%20253.548C91.2035%20250.607%2093.2562%20240.534%2093.5397%20235.435C93.88%20229.427%2094.1862%20221.92%2094.5264%20219.535C94.8666%20217.151%2086.4744%20216.253%2086.4744%20216.253Z'%20fill='%23113569'/%3e%3cpath%20d='M99.222%20256.476C98.7745%20256.585%2098.371%20256.829%2098.0651%20257.173C97.7592%20257.518%2097.5654%20257.948%2097.5095%20258.406C97.4369%20258.823%2097.4369%20259.25%2097.5095%20259.667C97.8043%20260.021%2098.1998%20260.277%2098.6435%20260.401C99.0871%20260.525%2099.5579%20260.51%2099.9931%20260.359C101.11%20259.911%20102.085%20259.169%20102.817%20258.213C103.58%20257.528%20104.271%20256.767%20104.881%20255.942C105.142%20255.34%20104.541%20254.658%20103.849%20254.658C102.44%20255.071%20101.073%20255.614%2099.7663%20256.282C99.627%20256.344%2099.4828%20256.393%2099.3354%20256.43L99.222%20256.476Z'%20fill='%23232839'/%3e%3cpath%20d='M101.785%20218.026C101.785%20218.026%20102.25%20245.873%20101.24%20255.969C101.235%20256.3%20101.157%20256.627%20101.012%20256.925C100.867%20257.223%20100.658%20257.486%20100.401%20257.695C100.144%20257.904%2099.8439%20258.054%2099.5226%20258.134C99.2013%20258.215%2098.8663%20258.224%2098.5411%20258.161C98.371%20258.161%2097.2256%20258.444%2097.0441%20258.365C96.1255%20258.024%2095.1616%20231.109%2094.3564%20227.986C93.5512%20224.863%2091.1582%20222.603%2091.3851%20218.026C91.6119%20213.45%2098.4731%20215.744%20101.785%20218.026Z'%20fill='%23113C7A'/%3e%3cpath%20d='M102.342%20220.236C101.934%20222.258%2096.1044%20222.78%2092.7475%20222.246C89.3906%20221.713%2085.4326%20220.94%2085.546%20217.034C85.546%20217.034%2085.8636%20199.579%2085.8636%20196.524C85.9205%20194.584%2086.5961%20192.714%2087.7915%20191.186C87.7915%20191.186%2089.6628%20189.04%2095.5713%20190.244C95.5713%20190.244%20100.391%20191.3%20102.603%20194.854C102.603%20194.854%20104.451%20198.261%20103.941%20206.393C103.673%20211.034%20103.139%20215.656%20102.342%20220.236Z'%20fill='%23113C7A'/%3e%3cpath%20d='M90.952%20185.964C91.2221%20187.397%2091.2221%20188.868%2090.952%20190.302C90.8726%20190.983%2093.8439%20193.277%2096.475%20192.687C98.006%20192.346%2097.9266%20191.551%2097.9266%20191.551C97.1797%20190.29%2096.7878%20188.849%2096.7925%20187.383C97.0307%20185.328%2092.7438%20185.498%2090.952%20185.964Z'%20fill='%23FF7C40'/%3e%3cpath%20d='M99.2954%20191.722L97.4695%20190.7C97.4695%20190.7%2092.7858%20190.257%2091.1073%20189.156L90.2341%20190.405C90.6738%20191.134%2091.2808%20191.747%2092.0047%20192.193C92.7287%20192.639%2093.5485%20192.906%2094.3962%20192.972C95.9183%20193.242%2097.4862%20192.925%2098.7851%20192.086L99.2954%20191.722Z'%20fill='%23E1E8F2'/%3e%3cpath%20d='M99.5354%20180.913C99.5354%20182.049%2099.1988%20183.16%2098.5683%20184.105C97.9377%20185.05%2097.0415%20185.787%2095.9929%20186.222C94.9444%20186.657%2093.7905%20186.77%2092.6774%20186.549C91.5642%20186.327%2090.5417%20185.78%2089.7392%20184.976C88.9367%20184.172%2088.3901%20183.148%2088.1687%20182.034C87.9473%20180.919%2088.0609%20179.764%2088.4953%20178.714C88.9296%20177.664%2089.6651%20176.766%2090.6088%20176.135C91.5525%20175.503%2092.6619%20175.166%2093.7969%20175.166C95.3188%20175.166%2096.7785%20175.772%2097.8546%20176.849C98.9308%20177.927%2099.5354%20179.389%2099.5354%20180.913Z'%20fill='%23FF8654'/%3e%3cpath%20d='M99.5445%20181.286C99.5445%20181.286%2099.6125%20187.043%2098.4104%20188.202C97.2083%20189.36%2095.2349%20187.066%2092.1616%20186.396C89.0882%20185.726%2094.6566%20179.582%2094.6566%20179.582L99.5445%20181.286Z'%20fill='%23FF8654'/%3e%3cpath%20d='M88.9823%20176.191C88.9823%20176.191%2095.1177%20172.636%2098.5426%20175.578C101.968%20178.519%2098.055%20179.757%2097.4086%20180.62C96.7621%20181.483%2097.4085%20182.176%2097.0797%20182.789C96.7508%20183.402%2096.6714%20183.516%2096.6714%20183.516L96.8755%20184.254L96.5126%20184.583C96.5126%20184.583%2096.025%20183.198%2095.5713%20183.232C95.1177%20183.266%2094.7548%20184.175%2094.9136%20184.708C95.0723%20185.242%2095.526%20185.844%2095.4466%20186.185C95.3672%20186.525%2094.8795%20187.57%2094.4259%20187.616C93.3294%20187.522%2092.2542%20187.258%2091.2391%20186.832C89.6561%20185.851%2088.3914%20184.431%2087.5987%20182.744C87.3635%20182.139%2087.2708%20181.489%2087.3279%20180.843C87.3849%20180.196%2087.5902%20179.572%2087.9276%20179.019C87.7789%20178.496%2087.8011%20177.94%2087.9908%20177.431C88.1806%20176.922%2088.5281%20176.488%2088.9823%20176.191Z'%20fill='%2396432A'/%3e%3cpath%20d='M109.698%20224.2L104.028%20227.607L104.776%20237.635L117.161%20229.969L116.684%20220.407L109.698%20224.2Z'%20fill='%2394C3FF'/%3e%3cpath%20d='M110.776%20221.454C110.776%20221.454%20112.126%20222.873%20112.409%20223.305C112.693%20223.737%20112.84%20225.928%20112.477%20226.212C111.69%20226.714%20110.789%20227.007%20109.858%20227.064C109.291%20226.916%20108.939%20226.632%20108.939%20226.417C108.939%20226.201%20108.803%20224.793%20108.803%20224.793C108.803%20224.793%20107.805%20224.077%20107.737%20223.657C107.707%20223.3%20107.73%20222.94%20107.805%20222.59L110.776%20221.454Z'%20fill='%23FF9554'/%3e%3cpath%20d='M100.629%20192.584C101.648%20193.135%20102.542%20193.89%20103.257%20194.802C103.971%20195.715%20104.489%20196.765%20104.78%20197.888C105.539%20201.488%20107.048%20210.755%20107.048%20210.755L111.21%20221.237C111.111%20221.644%20110.917%20222.022%20110.645%20222.34C110.372%20222.658%20110.028%20222.907%20109.641%20223.067C109.254%20223.226%20108.835%20223.292%20108.418%20223.258C108%20223.224%20107.597%20223.092%20107.241%20222.872C107.241%20222.872%20102.704%20214.162%20101.57%20211.709C100.436%20209.256%2099.302%20197.888%2099.1092%20195.616C99.0222%20195.016%2099.1212%20194.403%2099.393%20193.861C99.6647%20193.319%20100.096%20192.873%20100.629%20192.584Z'%20fill='%23113C7A'/%3e%3cpath%20d='M364.359%20134.939C367.058%20136.495%20367.069%20139.016%20364.359%20140.617C362.853%20141.384%20361.188%20141.784%20359.499%20141.784C357.81%20141.784%20356.145%20141.384%20354.639%20140.617C351.952%20139.062%20351.94%20136.54%20354.639%20134.939C356.145%20134.172%20357.81%20133.772%20359.499%20133.772C361.188%20133.772%20362.853%20134.172%20364.359%20134.939Z'%20fill='%23A6D0F4'/%3e%3cpath%20d='M365.159%20121.041V136.338C365.107%20136.898%20364.908%20137.434%20364.581%20137.891C364.254%20138.348%20363.812%20138.709%20363.299%20138.939C361.894%20139.654%20360.34%20140.027%20358.763%20140.027C357.186%20140.027%20355.632%20139.654%20354.227%20138.939C353.706%20138.706%20353.256%20138.338%20352.925%20137.872C352.594%20137.407%20352.394%20136.862%20352.344%20136.293V121.007C352.393%20121.574%20352.594%20122.119%20352.925%20122.582C353.256%20123.046%20353.706%20123.411%20354.227%20123.641C355.631%20124.359%20357.186%20124.733%20358.763%20124.733C360.34%20124.733%20361.895%20124.359%20363.299%20123.641C363.811%20123.411%20364.253%20123.049%20364.58%20122.592C364.906%20122.135%20365.106%20121.6%20365.159%20121.041Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M363.266%20118.394C365.773%20119.848%20365.795%20122.199%20363.266%20123.652C361.862%20124.37%20360.307%20124.744%20358.73%20124.744C357.153%20124.744%20355.598%20124.37%20354.194%20123.652C351.687%20122.21%20351.676%20119.859%20354.194%20118.406C355.598%20117.689%20357.152%20117.314%20358.728%20117.312C360.305%20117.31%20361.86%20117.681%20363.266%20118.394Z'%20fill='white'/%3e%3cpath%20d='M362.267%20118.962C364.229%20120.097%20364.229%20121.914%20362.267%20123.05C361.175%20123.607%20359.966%20123.898%20358.74%20123.898C357.514%20123.898%20356.306%20123.607%20355.213%20123.05C353.263%20121.914%20353.251%20120.097%20355.213%20118.973C356.303%20118.409%20357.512%20118.114%20358.739%20118.112C359.966%20118.11%20361.175%20118.402%20362.267%20118.962Z'%20fill='%23713336'/%3e%3cpath%20d='M353.838%20121.482C353.838%20121.482%20350.629%20110.795%20349.495%20109.183C349.495%20107.774%20352.421%20109.467%20353.555%20112.124C354.509%20114.926%20355.233%20117.801%20355.721%20120.721C355.721%20120.721%20355.539%20107.014%20357.898%20103.993C359.406%20104.367%20358.465%20119.404%20358.272%20120.539C358.272%20120.539%20362.99%20110.511%20366.109%20108.433C367.527%20108.626%20361.573%20121.005%20361.573%20121.005C361.573%20121.005%20364.022%20116.371%20368.456%20115.52C366.949%20117.729%20365.309%20119.846%20363.546%20121.857C363.546%20121.857%20361.947%20124.321%20357.694%20123.844C357.705%20123.844%20354.779%20123.651%20353.838%20121.482Z'%20fill='%234CA15C'/%3e%3cpath%20d='M231.058%2046.2549L231.069%2048.4808L225.864%2051.4903L225.875%2056.2941L223.732%2057.532L223.721%2050.5023L231.058%2046.2549Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M231.075%2048.4773L251.965%2036.4053V49.6471V55.632L248.2%2057.8125L225.881%2070.7135V56.2907V51.4868L231.075%2048.4773ZM251.398%2055.2913L251.341%2037.4614L226.482%2051.8389V69.6687L251.353%2055.2913'%20fill='%23E6F4FF'/%3e%3cpath%20d='M254.342%2048.2988L254.364%2056.7481L248.24%2060.28V57.8157L252.006%2055.6352L251.994%2049.6503L254.342%2048.2988Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M252.028%2045.9031L273.95%2033.4109V54.9884L291.336%2066.7198'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M243.33%2056.6934H243.398H243.466L243.545%2056.6366H243.613H243.67L243.738%2056.5798V56.523H243.806L243.874%2056.4662L244.01%2056.33L244.067%2056.2732L244.124%2056.205H244.192V56.1369L244.248%2056.0687C244.319%2056.0064%20244.383%2055.938%20244.441%2055.8643L244.498%2055.7962V55.7281L244.555%2055.6599L244.611%2055.5918L244.679%2055.5236L244.906%2055.2284V55.1602L244.963%2055.0807V55.0126L245.224%2054.6265V54.547L245.28%2054.4788L245.564%2054.0019V53.9224V53.8315C245.643%2053.6952%20245.711%2053.5589%20245.779%2053.4227C244.948%2053.3118%20244.111%2053.2511%20243.273%2053.241C243.251%2053.2815%20243.224%2053.3195%20243.194%2053.3545C242.873%2053.8563%20242.447%2054.2825%20241.946%2054.6038C241.758%2054.7243%20241.547%2054.8047%20241.327%2054.8399C241.106%2054.8751%20240.881%2054.8643%20240.665%2054.8082H240.585C240.517%2054.899%20239.043%2056.6366%20238.215%2057.7268L238.295%2057.8063L238.431%2057.8972H238.487L238.646%2057.9653H238.703H238.873H239.882H240.018H240.268H240.415H240.472H240.744H240.824H240.88H240.971H241.062H241.152H241.22L243.33%2056.6934Z'%20fill='%234B5CC0'/%3e%3cpath%20d='M242.196%2053.4647C242.141%2053.5833%20242.076%2053.6972%20242.003%2053.8054C242.219%2053.8615%20242.445%2053.8723%20242.665%2053.8371C242.886%2053.802%20243.096%2053.7216%20243.284%2053.601C243.786%2053.2798%20244.211%2052.8536%20244.532%2052.3518C244.45%2052.3375%20244.375%2052.2977%20244.317%2052.2382C244.215%2051.9725%20244.154%2051.6931%20244.135%2051.4092L243.602%2052.1587C243.52%2052.2863%20243.412%2052.3948%20243.284%2052.4767C243.179%2052.5179%20243.061%2052.5179%20242.956%2052.4767L242.411%2052.3291C242.375%2052.7136%20242.303%2053.0938%20242.196%2053.4647Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M242.081%2050.0277C242.009%2050.0798%20241.928%2050.1183%20241.843%2050.1413L241.718%2051.0839V51.4019C241.712%2051.4623%20241.712%2051.5232%20241.718%2051.5836C241.737%2051.7642%20241.807%2051.9357%20241.919%2052.0783C242.032%2052.221%20242.182%2052.3289%20242.353%2052.3899L242.897%2052.5375C243.003%2052.5787%20243.12%2052.5787%20243.226%2052.5375C243.354%2052.4556%20243.462%2052.3471%20243.544%2052.2195L244.077%2051.47C244.405%2051.009%20244.63%2050.482%20244.734%2049.9255V49.6757V49.051L244.292%2047.6655C244.292%2047.6655%20244.224%2047.5633%20244.065%2047.6655C243.922%2047.7614%20243.798%2047.8849%20243.702%2048.0289C243.283%2048.6308%20243.238%2049.1646%20242.512%2049.6984C242.373%2049.8145%20242.229%2049.9244%20242.081%2050.0277Z'%20fill='%23CBDCEB'/%3e%3cpath%20d='M242.723%2046.82C242.015%2047.47%20241.55%2048.344%20241.408%2049.2958C241.369%2049.7306%20241.407%2050.169%20241.521%2050.5904C241.567%2050.784%20241.628%2050.9738%20241.703%2051.1582V51.0787L241.828%2050.1361C241.913%2050.1132%20241.994%2050.0747%20242.066%2050.0226C242.278%2049.8989%20242.482%2049.7623%20242.678%2049.6137C243.404%2049.0913%20243.449%2048.5462%20243.869%2047.9443C243.965%2047.8003%20244.088%2047.6768%20244.232%2047.5809C244.391%2047.4787%20244.459%2047.5809%20244.459%2047.5809L244.901%2048.9664C244.901%2048.9664%20244.901%2048.7847%20245.003%2048.5462C245.105%2048.3077%20245.128%2047.9784%20245.162%2047.7626C245.21%2047.2124%20245.057%2046.6633%20244.731%2046.2181C244.493%2045.991%20243.858%2046.0478%20243.222%2046.4112C243.043%2046.5301%20242.875%2046.6671%20242.723%2046.82Z'%20fill='%2396432A'/%3e%3cpath%20d='M244.567%2052.3549C244.597%2052.3199%20244.624%2052.2818%20244.647%2052.2413C245.489%2052.2518%20246.329%2052.3124%20247.164%2052.4231C247.842%2051.1363%20248.21%2049.7094%20248.242%2048.2552C248.242%2045.1776%20246.064%2043.9283%20243.376%2045.4842C241.967%2046.3993%20240.794%2047.6361%20239.954%2049.093C239.114%2050.5499%20238.632%2052.1854%20238.545%2053.8653C238.506%2054.4056%20238.587%2054.948%20238.783%2055.4528C238.979%2055.9577%20239.285%2056.4124%20239.679%2056.784L239.6%2056.7045C240.428%2055.5688%20241.868%2053.8767%20241.97%2053.7858H242.049C242.123%2053.6777%20242.187%2053.5637%20242.242%2053.4451C242.338%2053.0731%20242.399%2052.6929%20242.424%2052.3095C242.253%2052.2485%20242.103%2052.1405%20241.99%2051.9979C241.878%2051.8553%20241.808%2051.6838%20241.789%2051.5032C241.771%2051.5374%20241.743%2051.5652%20241.709%2051.5827C241.301%2051.7303%20241.085%2050.9581%20241.346%2050.6514L241.46%2050.5492H241.539C241.425%2050.1278%20241.387%2049.6894%20241.426%2049.2546C241.568%2048.3028%20242.033%2047.4289%20242.741%2046.7788C242.902%2046.6365%20243.077%2046.5109%20243.263%2046.4041C243.898%2046.0406%20244.533%2045.9839%20244.771%2046.211C245.098%2046.6562%20245.251%2047.2053%20245.202%2047.7555C245.202%2047.9713%20245.1%2048.2893%20245.043%2048.5391C245.068%2048.5068%20245.099%2048.4798%20245.134%2048.4596C245.171%2048.4482%20245.211%2048.4482%20245.248%2048.4596C245.508%2048.4596%20245.304%2049.493%20244.919%2049.7883H244.851C244.746%2050.3448%20244.521%2050.8718%20244.193%2051.3328C244.2%2051.6244%20244.258%2051.9126%20244.363%2052.1846C244.409%2052.2631%20244.482%2052.3233%20244.567%2052.3549Z'%20fill='%2358AFFB'/%3e%3cpath%20d='M237.782%2056.8159V57.7358L229.333%2062.6191V61.6993L237.782%2056.8159Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M233.597%2057.0879V58.0078L229.322%2060.4835V59.5523L233.597%2057.0879Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M230.977%2055.9329V56.8641L229.322%2057.8294V56.8868L230.977%2055.9329Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M237.782%2071.5825V72.5024L229.333%2077.3857V76.4659L237.782%2071.5825Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M233.597%2071.8525V72.7724L229.322%2075.2481V74.3169L233.597%2071.8525Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M230.977%2070.6956V71.6268L229.322%2072.5921V71.6495L230.977%2070.6956Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M237.782%2080.6665V81.5864L229.333%2086.4697V85.5498L237.782%2080.6665Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M233.597%2080.9365V81.8564L229.322%2084.3321V83.4009L233.597%2080.9365Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M230.977%2079.7815V80.7127L229.322%2081.678V80.7354L230.977%2079.7815Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M310.242%2026.2321L310.162%2053.4197L294.694%2044.4821L294.773%2017.2944L310.242%2026.2321Z'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M308.224%2027.3716L308.757%2027.0649L308.677%2054.2526L308.144%2054.5592L308.224%2027.3716Z'%20fill='%23BDC5CB'/%3e%3cpath%20d='M292.754%2018.4301L293.287%2018.1121L308.756%2027.0611L308.223%2027.3677L292.754%2018.4301Z'%20fill='white'/%3e%3cpath%20d='M308.222%2027.3698L308.143%2054.5574L292.674%2045.6198L292.753%2018.4321L308.222%2027.3698Z'%20fill='%23EAF1F7'/%3e%3cpath%20d='M297.045%2028.5267V28.7653C297.045%2028.7974%20297.037%2028.829%20297.021%2028.8568C297.005%2028.8847%20296.983%2028.9079%20296.955%2028.924C296.927%2028.9402%20296.896%2028.9487%20296.864%2028.9488C296.832%2028.9489%20296.8%2028.9405%20296.773%2028.9244L295.638%2028.2767C295.611%2028.2598%20295.588%2028.2364%20295.572%2028.2086C295.557%2028.1809%20295.548%2028.1496%20295.547%2028.1176V27.879C295.547%2027.847%20295.555%2027.8154%20295.571%2027.7875C295.587%2027.7597%20295.61%2027.7365%20295.637%2027.7203C295.665%2027.7042%20295.696%2027.6956%20295.728%2027.6956C295.76%2027.6955%20295.792%2027.7039%20295.819%2027.7199L296.954%2028.3676C296.982%2028.3837%20297.005%2028.4069%20297.021%2028.4349C297.037%2028.4628%20297.045%2028.4945%20297.045%2028.5267Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M300.612%2031.7523V31.9908C300.612%2032.0228%20300.604%2032.0544%20300.588%2032.0822C300.573%2032.1101%20300.55%2032.1332%20300.522%2032.1494C300.494%2032.1655%20300.463%2032.174%20300.431%2032.1741C300.399%2032.1742%20300.368%2032.1658%20300.34%2032.1498L295.645%2029.4583C295.617%2029.4422%20295.594%2029.419%20295.578%2029.391C295.562%2029.3631%20295.554%2029.3314%20295.554%2029.2993V29.0608C295.554%2029.0287%20295.562%2028.9972%20295.578%2028.9694C295.594%2028.9415%20295.616%2028.9183%20295.644%2028.9022C295.672%2028.8861%20295.703%2028.8775%20295.735%2028.8774C295.767%2028.8774%20295.799%2028.8858%20295.826%2028.9018L300.521%2031.5933C300.548%2031.6102%20300.571%2031.6336%20300.587%2031.6613C300.603%2031.6891%20300.611%2031.7204%20300.612%2031.7523Z'%20fill='%2394A3C0'/%3e%3cg%20opacity='0.53'%3e%3cpath%20d='M298.667%2033.0225V33.261C298.667%2033.293%20298.659%2033.3246%20298.643%2033.3524C298.627%2033.3803%20298.604%2033.4035%20298.576%2033.4196C298.549%2033.4357%20298.517%2033.4443%20298.485%2033.4444C298.453%2033.4444%20298.422%2033.436%20298.394%2033.42L295.639%2031.8301C295.61%2031.815%20295.586%2031.792%20295.57%2031.7638C295.554%2031.7357%20295.546%2031.7035%20295.548%2031.6711V31.4326C295.547%2031.4006%20295.556%2031.369%20295.571%2031.3412C295.587%2031.3133%20295.61%2031.2902%20295.638%2031.274C295.665%2031.2579%20295.697%2031.2493%20295.729%2031.2493C295.761%2031.2492%20295.792%2031.2576%20295.82%2031.2736L298.576%2032.8635C298.604%2032.8796%20298.627%2032.9028%20298.643%2032.9308C298.659%2032.9587%20298.667%2032.9904%20298.667%2033.0225Z'%20fill='%2394A3C0'/%3e%3c/g%3e%3cpath%20d='M299.875%2032.5257V32.7642C299.875%2032.7962%20299.867%2032.8278%20299.851%2032.8556C299.835%2032.8835%20299.813%2032.9066%20299.785%2032.9228C299.757%2032.9389%20299.726%2032.9475%20299.694%2032.9475C299.662%2032.9476%20299.63%2032.9392%20299.603%2032.9232L295.645%2030.6519C295.617%2030.6358%20295.594%2030.6126%20295.578%2030.5847C295.562%2030.5567%20295.554%2030.525%20295.554%2030.4929V30.2544C295.554%2030.2223%20295.562%2030.1908%20295.578%2030.163C295.594%2030.1351%20295.616%2030.1119%20295.644%2030.0958C295.672%2030.0797%20295.703%2030.0711%20295.735%2030.071C295.767%2030.071%20295.799%2030.0794%20295.826%2030.0954L299.784%2032.3667C299.812%2032.3828%20299.835%2032.406%20299.851%2032.4339C299.867%2032.4619%20299.875%2032.4935%20299.875%2032.5257Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M297.045%2034.4908V34.7295C297.045%2034.7615%20297.037%2034.7931%20297.021%2034.8209C297.005%2034.8488%20296.983%2034.872%20296.955%2034.8881C296.927%2034.9043%20296.896%2034.9128%20296.864%2034.9129C296.832%2034.913%20296.8%2034.9046%20296.773%2034.8885L295.638%2034.2408C295.611%2034.2239%20295.588%2034.2005%20295.572%2034.1727C295.557%2034.145%20295.548%2034.1137%20295.547%2034.0817V33.8431C295.547%2033.8111%20295.555%2033.7795%20295.571%2033.7516C295.587%2033.7238%20295.61%2033.7006%20295.637%2033.6844C295.665%2033.6683%20295.696%2033.6597%20295.728%2033.6597C295.76%2033.6596%20295.792%2033.668%20295.819%2033.684L296.954%2034.3317C296.982%2034.3478%20297.005%2034.371%20297.021%2034.399C297.037%2034.4269%20297.045%2034.4586%20297.045%2034.4908Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M300.612%2037.7145V37.9529C300.612%2037.985%20300.604%2038.0165%20300.588%2038.0444C300.573%2038.0722%20300.55%2038.0954%20300.522%2038.1115C300.494%2038.1277%20300.463%2038.1362%20300.431%2038.1363C300.399%2038.1363%20300.368%2038.128%20300.34%2038.1119L295.645%2035.4204C295.617%2035.4043%20295.594%2035.3811%20295.578%2035.3532C295.562%2035.3253%20295.554%2035.2936%20295.554%2035.2614V35.0229C295.554%2034.9909%20295.562%2034.9594%20295.578%2034.9315C295.594%2034.9037%20295.616%2034.8805%20295.644%2034.8644C295.672%2034.8482%20295.703%2034.8397%20295.735%2034.8396C295.767%2034.8395%20295.799%2034.8479%20295.826%2034.8639L300.521%2037.5555C300.548%2037.5724%20300.571%2037.5958%20300.587%2037.6235C300.603%2037.6513%20300.611%2037.6825%20300.612%2037.7145Z'%20fill='%2394A3C0'/%3e%3cg%20opacity='0.53'%3e%3cpath%20d='M298.667%2038.9906V39.229C298.667%2039.2611%20298.659%2039.2926%20298.643%2039.3205C298.627%2039.3483%20298.604%2039.3715%20298.576%2039.3876C298.549%2039.4038%20298.517%2039.4123%20298.485%2039.4124C298.453%2039.4125%20298.422%2039.404%20298.394%2039.388L295.639%2037.7981C295.61%2037.783%20295.586%2037.76%20295.57%2037.7319C295.554%2037.7037%20295.546%2037.6715%20295.548%2037.6391V37.4006C295.547%2037.3686%20295.556%2037.3371%20295.571%2037.3092C295.587%2037.2814%20295.61%2037.2582%20295.638%2037.242C295.665%2037.2259%20295.697%2037.2174%20295.729%2037.2173C295.761%2037.2172%20295.792%2037.2256%20295.82%2037.2416L298.576%2038.8316C298.604%2038.8477%20298.627%2038.8708%20298.643%2038.8988C298.659%2038.9267%20298.667%2038.9584%20298.667%2038.9906Z'%20fill='%2394A3C0'/%3e%3c/g%3e%3cpath%20d='M299.875%2038.4879V38.7264C299.875%2038.7584%20299.867%2038.7899%20299.851%2038.8178C299.835%2038.8456%20299.813%2038.8688%20299.785%2038.8849C299.757%2038.9011%20299.726%2038.9096%20299.694%2038.9097C299.662%2038.9098%20299.63%2038.9014%20299.603%2038.8853L295.645%2036.614C295.617%2036.5979%20295.594%2036.5747%20295.578%2036.5468C295.562%2036.5189%20295.554%2036.4872%20295.554%2036.455V36.2165C295.554%2036.1845%20295.562%2036.153%20295.578%2036.1251C295.594%2036.0973%20295.616%2036.0741%20295.644%2036.0579C295.672%2036.0418%20295.703%2036.0333%20295.735%2036.0332C295.767%2036.0331%20295.799%2036.0415%20295.826%2036.0576L299.784%2038.3289C299.812%2038.345%20299.835%2038.3682%20299.851%2038.3961C299.867%2038.424%20299.875%2038.4557%20299.875%2038.4879Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M316.193%2026.9705H314.492V28.6739H316.193V26.9705Z'%20fill='white'/%3e%3cpath%20d='M321.292%2029.8127H317.323V33.7876H321.292V29.8127Z'%20fill='white'/%3e%3cpath%20d='M525.999%20135.142H524.298V136.845H525.999V135.142Z'%20fill='white'/%3e%3cpath%20d='M531.102%20137.982H527.133V141.957H531.102V137.982Z'%20fill='white'/%3e%3cpath%20d='M625.797%200H624.096V1.70349H625.797V0Z'%20fill='white'/%3e%3cpath%20d='M630.903%202.83838H626.934V6.81319H630.903V2.83838Z'%20fill='white'/%3e%3cpath%20d='M541.221%20108.171H539.52V109.875H541.221V108.171Z'%20fill='white'/%3e%3cpath%20d='M546.324%20111.01H542.354V114.984H546.324V111.01Z'%20fill='white'/%3e%3cpath%20d='M394.448%20207.254H392.747V208.958H394.448V207.254Z'%20fill='white'/%3e%3cpath%20d='M399.547%20210.095H395.578V214.07H399.547V210.095Z'%20fill='white'/%3e%3cpath%20d='M81.4377%20163.34H79.7366V165.044H81.4377V163.34Z'%20fill='white'/%3e%3cpath%20d='M86.5408%20166.177H82.5715V170.152H86.5408V166.177Z'%20fill='white'/%3e%3cpath%20d='M195.978%20272.556H194.277V274.26H195.978V272.556Z'%20fill='white'/%3e%3cpath%20d='M201.082%20275.397H197.112V279.372H201.082V275.397Z'%20fill='white'/%3e%3cpath%20d='M609.762%20152.212V153.132L601.313%20158.016V157.096L609.762%20152.212Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M605.581%20152.484V153.404L601.306%20155.88V154.949L605.581%20152.484Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M602.957%20151.329V152.26L601.301%20153.226L601.29%20152.283L602.957%20151.329Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M401.858%20174.723V175.654L393.409%20180.537V179.606L401.858%20174.723Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M397.677%20174.997V175.928L393.401%20178.392V177.472L397.677%20174.997Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M395.057%20173.847V174.779L393.402%20175.733L393.39%20174.801L395.057%20173.847Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M518.674%20137.212C520.036%20138.1%20521.17%20139.297%20521.984%20140.706C522.797%20142.115%20523.268%20143.696%20523.358%20145.321V152.35C523.358%20155.326%20521.237%20156.53%20518.651%20155.031L512.255%20151.34L509.431%20153.679V149.716L504.804%20147.036C503.443%20146.148%20502.31%20144.95%20501.498%20143.541C500.687%20142.132%20500.218%20140.551%20500.132%20138.927V131.897C500.132%20128.922%20502.252%20127.718%20504.838%20129.217L518.674%20137.212ZM522.904%20152.101V145.082C522.828%20143.603%20522.402%20142.163%20521.663%20140.88C520.924%20139.597%20519.892%20138.507%20518.651%20137.7L504.815%20129.751C502.468%20128.388%20500.551%20129.49%20500.54%20132.192V139.222C500.623%20140.698%20501.051%20142.135%20501.789%20143.415C502.528%20144.695%20503.557%20145.784%20504.793%20146.593L509.851%20149.511V152.589L512.051%20150.783L518.64%20154.588C520.999%20155.95%20522.915%20154.86%20522.915%20152.146'%20fill='white'/%3e%3cpath%20d='M509.963%20136.258V136.86C509.962%20136.94%20509.939%20137.019%20509.898%20137.088C509.857%20137.157%20509.799%20137.215%20509.73%20137.255C509.66%20137.295%20509.581%20137.316%20509.501%20137.316C509.421%20137.317%20509.341%20137.296%20509.271%20137.257L506.436%20135.622C506.367%20135.582%20506.309%20135.524%20506.269%20135.454C506.229%20135.384%20506.209%20135.305%20506.209%20135.224V134.622C506.211%20134.542%20506.233%20134.463%20506.274%20134.394C506.315%20134.325%20506.373%20134.268%20506.443%20134.228C506.513%20134.187%20506.591%20134.166%20506.672%20134.166C506.752%20134.165%20506.831%20134.186%20506.901%20134.225L509.725%20135.86C509.797%20135.899%20509.857%20135.956%20509.899%20136.026C509.94%20136.096%20509.963%20136.176%20509.963%20136.258Z'%20fill='%23F9FBFC'/%3e%3cpath%20d='M518.915%20144.377V144.979C518.914%20145.059%20518.891%20145.138%20518.85%20145.207C518.809%20145.276%20518.751%20145.334%20518.682%20145.374C518.612%20145.414%20518.533%20145.435%20518.453%20145.436C518.373%20145.436%20518.293%20145.416%20518.223%20145.376L506.44%20138.563C506.368%20138.525%20506.307%20138.468%20506.265%20138.397C506.223%20138.327%20506.201%20138.247%20506.202%20138.165V137.563C506.204%20137.483%20506.226%20137.404%20506.267%20137.335C506.308%20137.266%20506.366%20137.208%20506.436%20137.168C506.505%20137.128%20506.584%20137.107%20506.664%20137.106C506.745%20137.106%20506.824%20137.126%20506.894%20137.166L518.688%20143.98C518.756%20144.021%20518.813%20144.08%20518.852%20144.149C518.892%20144.219%20518.914%20144.297%20518.915%20144.377Z'%20fill='%23F9FBFC'/%3e%3cg%20opacity='0.53'%3e%3cpath%20d='M514.066%20147.566V148.168C514.066%20148.248%20514.046%20148.327%20514.006%20148.396C513.967%20148.466%20513.91%20148.524%20513.841%20148.564C513.772%20148.605%20513.693%20148.626%20513.613%20148.626C513.533%20148.626%20513.454%20148.605%20513.385%20148.565L506.445%20144.579C506.372%20144.541%20506.312%20144.484%20506.269%20144.414C506.227%20144.344%20506.206%20144.263%20506.206%20144.182V143.58C506.208%20143.499%20506.23%20143.421%20506.271%20143.351C506.312%20143.282%20506.37%20143.225%20506.44%20143.185C506.51%20143.145%20506.588%20143.124%20506.669%20143.123C506.749%20143.123%20506.828%20143.143%20506.898%20143.182L513.828%20147.157C513.9%20147.198%20513.96%20147.257%20514.002%20147.329C514.044%20147.401%20514.066%20147.483%20514.066%20147.566Z'%20fill='%23F9FBFC'/%3e%3c/g%3e%3cpath%20d='M517.097%20146.319V146.921C517.095%20147.001%20517.073%20147.08%20517.032%20147.149C516.991%20147.218%20516.933%20147.276%20516.863%20147.316C516.793%20147.356%20516.715%20147.377%20516.634%20147.377C516.554%20147.378%20516.475%20147.357%20516.405%20147.318L506.448%20141.64C506.375%20141.602%20506.314%20141.545%20506.272%20141.475C506.23%20141.405%20506.209%20141.324%20506.209%20141.242V140.641C506.211%20140.56%20506.233%20140.481%20506.274%20140.412C506.315%20140.343%20506.373%20140.286%20506.443%20140.246C506.513%20140.206%20506.591%20140.184%20506.672%20140.184C506.752%20140.183%20506.831%20140.204%20506.901%20140.243L516.87%20145.921C516.939%20145.962%20516.997%20146.02%20517.037%20146.089C517.077%20146.159%20517.097%20146.238%20517.097%20146.319Z'%20fill='%23F9FBFC'/%3e%3cpath%20d='M284.927%2030.6317C286.323%2031.5387%20287.484%2032.7638%20288.316%2034.2068C289.148%2035.6497%20289.627%2037.2695%20289.713%2038.9333C289.713%2041.9883%20287.558%2043.2148%20284.904%2041.6816C283.508%2040.7745%20282.345%2039.5496%20281.512%2038.1069C280.678%2036.6641%20280.197%2035.0444%20280.107%2033.38C280.119%2030.3818%20282.273%2029.0872%20284.927%2030.6317Z'%20stroke='%23E6F4FF'%20stroke-width='0.75'%20stroke-miterlimit='10'/%3e%3cpath%20d='M286.657%2034.6392L287.689%2036.4222L283.754%2038.6708L281.837%2035.3546L282.869%2034.7641L283.754%2036.2972L286.657%2034.6392Z'%20fill='white'/%3e%3cpath%20d='M605.057%2054.7488L606.134%2057.6788L609.071%2058.769L606.134%2059.8592L605.057%2062.7892L603.968%2059.8592L601.031%2058.769L603.968%2057.6788L605.057%2054.7488Z'%20fill='white'/%3e%3cpath%20d='M618.664%2045.6648L619.742%2048.5948L622.679%2049.685L619.742%2050.7753L618.664%2053.7052L617.575%2050.7753L614.638%2049.685L617.575%2048.5948L618.664%2045.6648Z'%20fill='white'/%3e%3cpath%20d='M628.591%2059.0103L629.362%2061.1112L631.472%2061.8948L629.362%2062.6784L628.591%2064.7794L627.809%2062.6784L625.699%2061.8948L627.809%2061.1112L628.591%2059.0103Z'%20fill='white'/%3e%3cpath%20d='M384.006%20161.057L391.899%20156.435'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M352.2%20179.716L380.563%20163.078'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M352.575%20180.809C352.575%20181.261%20352.44%20181.702%20352.189%20182.076C351.937%20182.451%20351.579%20182.742%20351.161%20182.912C350.744%20183.082%20350.285%20183.124%20349.843%20183.032C349.402%20182.939%20348.998%20182.717%20348.683%20182.394C348.368%20182.07%20348.157%20181.66%20348.076%20181.216C347.995%20180.772%20348.048%20180.314%20348.228%20179.9C348.409%20179.486%20348.708%20179.135%20349.088%20178.892C349.469%20178.65%20349.913%20178.526%20350.364%20178.538C350.955%20178.552%20351.518%20178.798%20351.931%20179.223C352.344%20179.647%20352.575%20180.216%20352.575%20180.809Z'%20stroke='%23E6F4FF'%20stroke-miterlimit='10'/%3e%3cpath%20d='M559.788%2027.6204L567.681%2022.9983'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M527.982%2046.2785L556.346%2029.6411'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M528.358%2047.4156C528.358%2047.8648%20528.224%2048.304%20527.975%2048.6775C527.726%2049.051%20527.372%2049.3421%20526.957%2049.514C526.543%2049.6859%20526.087%2049.7309%20525.647%2049.6433C525.207%2049.5556%20524.803%2049.3393%20524.486%2049.0217C524.168%2048.704%20523.952%2048.2993%20523.865%2047.8587C523.777%2047.4181%20523.822%2046.9614%20523.994%2046.5464C524.166%2046.1314%20524.456%2045.7767%20524.829%2045.5271C525.202%2045.2775%20525.641%2045.1443%20526.089%2045.1443C526.691%2045.1443%20527.268%2045.3836%20527.693%2045.8095C528.119%2046.2355%20528.358%2046.8132%20528.358%2047.4156Z'%20stroke='%23E6F4FF'%20stroke-miterlimit='10'/%3e%3cpath%20d='M641.44%2021.9437L649.333%2017.3215'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M609.635%2040.5979L637.999%2023.9604'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M610.014%2041.733C610.014%2042.1822%20609.881%2042.6214%20609.632%2042.9949C609.383%2043.3684%20609.028%2043.6595%20608.614%2043.8314C608.199%2044.0033%20607.743%2044.0483%20607.303%2043.9607C606.863%2043.873%20606.459%2043.6567%20606.142%2043.3391C605.825%2043.0214%20605.609%2042.6167%20605.521%2042.1761C605.434%2041.7355%20605.479%2041.2788%20605.65%2040.8638C605.822%2040.4488%20606.113%2040.094%20606.486%2039.8445C606.859%2039.5949%20607.297%2039.4617%20607.746%2039.4617C608.347%2039.4617%20608.924%2039.701%20609.35%2040.1269C609.775%2040.5529%20610.014%2041.1306%20610.014%2041.733Z'%20stroke='%23E6F4FF'%20stroke-miterlimit='10'/%3e%3cpath%20d='M10.4121%20314.616L2.53021%20309.993'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M42.2219%20333.27L13.8471%20316.633'%20stroke='%23E6F4FF'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M41.8344%20334.359C41.8344%20334.808%2041.9675%20335.247%2042.2167%20335.621C42.4659%20335.994%2042.8202%20336.285%2043.2346%20336.457C43.6491%20336.629%2044.1051%20336.674%2044.5451%20336.586C44.9851%20336.499%2045.3892%20336.282%2045.7065%20335.965C46.0237%20335.647%2046.2397%20335.242%2046.3272%20334.802C46.4147%20334.361%2046.3698%20333.905%2046.1981%20333.49C46.0265%20333.074%2045.7357%20332.72%2045.3627%20332.47C44.9897%20332.221%2044.5512%20332.087%2044.1026%20332.087C43.5011%20332.087%2042.9241%20332.327%2042.4988%20332.753C42.0734%20333.179%2041.8344%20333.756%2041.8344%20334.359Z'%20stroke='%23E6F4FF'%20stroke-miterlimit='10'/%3e%3cpath%20d='M537.046%20165.261V166.181L545.495%20171.075V170.144L537.046%20165.261Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M541.227%20165.537V166.457L545.502%20168.932V168.012L541.227%20165.537Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M543.852%20164.374V165.305L545.507%20166.27L545.519%20165.339L543.852%20164.374Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M544.63%20195.469C544.85%20195.797%20545.136%20196.075%20545.47%20196.287L545.663%20196.389C545.322%20196.264%20544.982%20196.105%20544.63%20195.935V195.469Z'%20fill='%23747878'/%3e%3cpath%20d='M544.5%20177.641L544%20177.322L544.114%20177.39L544.432%20177.595L544.5%20177.641Z'%20fill='%236C7070'/%3e%3cpath%20d='M544.209%20192.554L544.437%20192.668L544.209%20192.554Z'%20fill='%23747878'/%3e%3cpath%20d='M545.176%20193C545.002%20192.949%20544.817%20192.949%20544.642%20193V192.783C544.816%20192.865%20544.995%20192.937%20545.176%20193Z'%20fill='%23747878'/%3e%3cpath%20d='M545.292%20178.223L545.655%20178.53C545.299%20178.218%20544.919%20177.933%20544.521%20177.677L544.657%20177.768V177.564C544.834%20177.814%20545.048%20178.037%20545.292%20178.223Z'%20fill='%23747878'/%3e%3cpath%20d='M544.046%20174.202C544.273%20174.327%20544.488%20174.463%20544.693%20174.599V175.065C544.513%20175.142%20544.364%20175.276%20544.268%20175.447C544.172%20175.617%20544.134%20175.814%20544.16%20176.008C544.185%20176.567%20544.37%20177.107%20544.693%20177.563V177.768C544.486%20177.618%20544.27%20177.482%20544.046%20177.359C540.44%20175.269%20537.491%20176.95%20537.48%20181.118C537.595%20183.393%20538.247%20185.609%20539.382%20187.583C540.518%20189.557%20542.104%20191.233%20544.012%20192.475L544.216%20192.588L544.454%20192.713L544.659%20192.804V193.02C544.479%20193.095%20544.329%20193.226%20544.231%20193.394C544.133%20193.562%20544.092%20193.758%20544.114%20193.951C544.137%20194.51%20544.323%20195.051%20544.647%20195.507V195.972L544.466%20195.882L544.001%20195.632C538.863%20192.656%20534.724%20185.411%20534.735%20179.562C534.747%20173.713%20538.92%20171.204%20544.046%20174.202Z'%20stroke='%23E6F4FF'%20stroke-width='0.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M545.544%20175.222L545.725%20175.347H545.805C549.516%20178.466%20552.069%20182.747%20553.051%20187.498C553.056%20187.54%20553.056%20187.582%20553.051%20187.623V187.759C553.055%20187.805%20553.055%20187.85%20553.051%20187.896C553.054%20187.941%20553.054%20187.987%20553.051%20188.032V188.168C553.049%20188.214%20553.049%20188.259%20553.051%20188.305C553.051%20188.373%20553.051%20188.407%20553.051%20188.452C553.056%20188.547%20553.056%20188.642%20553.051%20188.736V188.861V190.837C553.048%20190.879%20553.048%20190.92%20553.051%20190.962C553.054%20191.004%20553.054%20191.045%20553.051%20191.087C553.06%20191.128%20553.06%20191.171%20553.051%20191.212C553.059%20191.253%20553.059%20191.295%20553.051%20191.337C553.051%20191.405%20553.051%20191.428%20553.051%20191.462C553.051%20191.496%20553.051%20191.553%20553.051%20191.575C553.051%20191.598%20553.051%20191.757%20553.051%20191.836C553.051%20191.916%20553.051%20191.916%20553.051%20191.95V192.064V192.177V192.279C553.049%20192.317%20553.049%20192.355%20553.051%20192.393V192.507C553.048%20192.544%20553.048%20192.582%20553.051%20192.62C553.047%20192.658%20553.047%20192.696%20553.051%20192.734C552.144%20196.141%20549.309%20197.628%20545.77%20196.356H545.702L545.51%20196.254C545.111%20195.994%20544.779%20195.644%20544.54%20195.232C544.302%20194.819%20544.164%20194.356%20544.137%20193.881C544.115%20193.687%20544.156%20193.492%20544.254%20193.324C544.352%20193.156%20544.502%20193.024%20544.682%20192.949C544.856%20192.899%20545.041%20192.899%20545.215%20192.949H545.283C546.17%20193.309%20547.152%20193.361%20548.073%20193.097H548.186H548.288H548.402L548.492%20193.04H548.594H548.685L548.787%20192.983L548.878%20192.927L548.98%20192.859L549.059%20192.79L549.15%20192.722L549.229%20192.643L549.32%20192.563L549.4%20192.484L549.479%20192.393L549.558%20192.302V192.245V192.177L549.626%20192.075L549.694%20191.973C549.721%20191.937%20549.743%20191.899%20549.762%20191.859L549.831%20191.746V191.643C549.854%20191.608%20549.873%20191.57%20549.887%20191.53C549.892%20191.488%20549.892%20191.446%20549.887%20191.405V191.28V191.155V191.019V190.894C549.884%20190.848%20549.884%20190.803%20549.887%20190.758V190.621C549.884%20190.576%20549.884%20190.53%20549.887%20190.485C549.89%20190.436%20549.89%20190.387%20549.887%20190.337C549.89%20190.284%20549.89%20190.231%20549.887%20190.178C549.892%20190.129%20549.892%20190.08%20549.887%20190.031C549.887%20190.031%20549.887%20189.929%20549.887%20189.883C549.887%20189.838%20549.887%20189.781%20549.887%20189.736C549.887%20189.69%20549.887%20189.622%20549.887%20189.565C549.887%20189.508%20549.887%20189.452%20549.887%20189.406C549.887%20189.361%20549.887%20189.293%20549.887%20189.236V189.065C549.887%20188.997%20549.887%20188.941%20549.887%20188.895C549.893%20188.838%20549.893%20188.781%20549.887%20188.725V188.554C549.894%20188.498%20549.894%20188.441%20549.887%20188.384C549.894%20188.324%20549.894%20188.263%20549.887%20188.202C549.894%20188.146%20549.894%20188.089%20549.887%20188.032C549.887%20187.953%20549.887%20187.896%20549.887%20187.839C549.887%20187.669%20549.887%20187.669%20549.887%20187.498C549.882%20187.438%20549.882%20187.377%20549.887%20187.317C549.883%20187.256%20549.883%20187.195%20549.887%20187.135V186.953C549.887%20186.76%20549.808%20186.59%20549.774%20186.408C549.767%20186.348%20549.767%20186.287%20549.774%20186.226L549.672%20185.863C548.932%20183.323%20547.554%20181.016%20545.668%20179.163L545.555%20179.049L545.419%20178.924L545.351%20178.856L545.271%20178.788L544.897%20178.47C544.665%20178.281%20544.463%20178.059%20544.296%20177.811C543.973%20177.354%20543.788%20176.814%20543.763%20176.255C543.737%20176.061%20543.775%20175.864%20543.872%20175.694C543.968%20175.524%20544.117%20175.39%20544.296%20175.313C544.472%20175.177%20544.684%20175.096%20544.906%20175.079C545.128%20175.063%20545.35%20175.113%20545.544%20175.222Z'%20fill='%2358AFFB'/%3e%3cpath%20d='M545.724%20175.349L545.543%20175.224C545.291%20175.06%20544.985%20175.003%20544.692%20175.065V174.61C544.998%20174.837%20545.395%20175.087%20545.724%20175.349Z'%20fill='%23747878'/%3e%3cpath%20d='M579.805%2062.4946V63.4145L571.356%2068.2978V67.378L579.805%2062.4946Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M575.616%2062.7666V63.6865L571.341%2066.1622V65.231L575.616%2062.7666Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M573%2061.6077V62.5389L571.344%2063.5042L571.333%2062.573L573%2061.6077Z'%20fill='%23E6F4FF'/%3e%3cpath%20d='M548.123%2073.3742L548.214%20102.413L564.726%2092.8622L564.646%2063.8347L548.123%2073.3742Z'%20stroke='%23E6F4FF'%20stroke-width='0.8'%20stroke-miterlimit='10'/%3e%3cpath%20d='M550.291%2074.5995L549.713%2074.2588L549.803%20103.298L550.37%20103.627L550.291%2074.5995Z'%20fill='%23BDC5CB'/%3e%3cpath%20d='M566.803%2065.049L566.236%2064.7083L549.713%2074.2591L550.291%2074.5998L566.803%2065.049Z'%20fill='white'/%3e%3cpath%20d='M550.291%2074.5985L550.371%20103.626L566.883%2094.075L566.803%2065.0476L550.291%2074.5985Z'%20fill='%23EAF1F7'/%3e%3cpath%20d='M561.945%2078.3853L561.957%2079.3051L553.496%2084.1998V83.2686L561.945%2078.3853Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M557.76%2078.6553L557.772%2079.5752L553.496%2082.0509V81.131L557.76%2078.6553Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M555.148%2077.4963L555.16%2078.4276L553.492%2079.3929V78.4616L555.148%2077.4963Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M561.945%2087.6621L561.957%2088.582L553.496%2093.4653V92.5454L561.945%2087.6621Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M557.76%2087.9321L557.772%2088.852L553.496%2091.3278V90.3965L557.76%2087.9321Z'%20fill='%2394A3C0'/%3e%3cpath%20d='M555.148%2086.7771L555.16%2087.7083L553.492%2088.6736V87.731L555.148%2086.7771Z'%20fill='%2394A3C0'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='22'%20height='32'%20viewBox='0%200%2022%2032'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M19.1593%2014.3814C17.2069%2015.0272%205.56056%2018.3882%205.56056%2018.3882C4.03868%2021.4659%2011.1005%2023.4995%2011.1005%2023.4995C6.62739%2019.7609%2013.9819%2017.901%2018.4833%2016.4868C23.7193%2014.8403%2020.7473%2012.4385%2020.7473%2012.4385C21.0173%2013.2089%2020.6906%2013.8716%2019.1574%2014.3776'%20fill='white'/%3e%3cpath%20d='M19.9428%2015.3237C18.6683%2015.7448%2014.2688%2016.9796%2010.7945%2018.3807C6.36106%2020.1763%2011.1004%2023.5014%2011.1004%2023.5014C6.62729%2019.7628%2013.9818%2017.903%2018.4832%2016.4887C23.7211%2014.8403%2020.7491%2012.4404%2020.7491%2012.4404C21.4477%2013.36%2021.476%2014.8177%2019.9428%2015.3237Z'%20fill='white'/%3e%3cpath%20d='M5.56915%2023.6885C8.14464%2026.9022%2013.0124%2030.0007%2015.7314%2031.5887C16.8794%2032.259%2018.3295%2032.0966%2019.3001%2031.1903C20.1007%2030.4425%2020.1422%2029.1869%2019.3945%2028.3863C19.2472%2028.2277%2019.0754%2028.0955%2018.8847%2027.9936C16.1657%2026.5321%2011.7624%2024.0756%208.74509%2021.923C4.09636%2018.6111%207.66693%2017.7822%207.66693%2017.7822C3.3392%2018.7414%202.58392%2019.9688%205.56915%2023.6828'%20fill='white'/%3e%3cpath%20d='M3.38919%2016.1084C-1.84676%2017.753%201.12525%2020.1567%201.12525%2020.1567C0.853355%2019.3844%201.1819%2018.7235%202.71511%2018.2175C4.67505%2017.5698%2016.312%2014.207%2016.312%2014.207C17.8357%2011.1292%2010.7739%209.09375%2010.7739%209.09375C15.2433%2012.8324%207.88875%2014.6941%203.38919%2016.1084Z'%20fill='white'/%3e%3cpath%20d='M3.38919%2016.1084C-1.84676%2017.753%201.12525%2020.1567%201.12525%2020.1567C0.426624%2019.2371%200.38886%2017.7794%201.92962%2017.2734C3.20604%2016.8523%207.60552%2015.6174%2011.0798%2014.2164C15.5114%2012.4207%2010.7739%209.09375%2010.7739%209.09375C15.2433%2012.8324%207.88875%2014.6941%203.38919%2016.1084Z'%20fill='white'/%3e%3cpath%20d='M2.57331%201.40596C1.77272%202.15368%201.72929%203.40933%202.47701%204.20992C2.62429%204.36853%202.79612%204.5007%202.98682%204.60266C5.70771%206.06412%2010.111%208.51877%2013.1283%2010.6732C17.777%2013.9851%2014.2065%2014.814%2014.2065%2014.814C18.5323%2013.8529%2019.2895%2012.6275%2016.3042%208.9134C13.7287%205.6997%208.86098%202.59929%206.1401%201.01321C4.99397%200.342905%203.54195%200.50529%202.57331%201.41162'%20fill='white'/%3e%3cg%20opacity='0.3'%3e%3cpath%20d='M15.6146%2014.4409C15.8714%2014.3635%2016.1093%2014.2823%2016.3264%2014.1973C16.4284%2014.0293%2016.4945%2013.8404%2016.519%2013.646C16.5473%2013.391%2016.5152%2013.1324%2016.4227%2012.8907C16.3377%2012.6622%2016.2207%2012.447%2016.0791%2012.2487C15.9431%2012.0523%2015.7921%2011.8692%2015.6278%2011.6973C15.303%2011.365%2014.9518%2011.0572%2014.5798%2010.7778C13.8434%2010.2264%2013.0655%209.72607%2012.2895%209.23325C11.5134%208.74232%2010.7223%208.27405%209.92923%207.81333C8.34315%206.89378%206.73441%206.00633%205.13134%205.12077L3.93045%204.45235C3.52826%204.24087%203.17328%203.95009%202.88817%203.597C2.75033%203.41951%202.65026%203.2137%202.5955%202.99467C2.54263%202.77564%202.55396%202.54528%202.6276%202.33191C2.70312%202.11855%202.82019%201.92218%202.97125%201.75413C3.04677%201.66916%203.12797%201.58797%203.21294%201.51055L3.34133%201.40103L3.40931%201.34817L3.44518%201.32173L3.46218%201.30851C3.46218%201.30851%203.47351%201.31795%203.46218%201.29152C3.45085%201.26509%203.46218%201.29152%203.44707%201.28019H3.43763L3.42064%201.29341L3.38476%201.31984L3.31679%201.37082L3.18272%201.48034C3.09587%201.55587%203.01279%201.63706%202.93537%201.72392C2.77488%201.89385%202.65026%202.094%202.56717%202.31303C2.48787%202.53584%202.47276%202.77564%202.52375%203.006C2.5785%203.23447%202.67858%203.44783%202.82019%203.63476C3.1072%204.00107%203.46595%204.30507%203.8738%204.52977L5.06525%205.21707C6.657%206.13662%208.24874%207.03728%209.81783%207.9776C10.6014%208.44965%2011.3794%208.93303%2012.1479%209.43151C12.9145%209.92999%2013.6754%2010.4455%2014.3929%2010.9968C14.7498%2011.2725%2015.0821%2011.5765%2015.3918%2011.905C15.6977%2012.2166%2015.9375%2012.5867%2016.0998%2012.9926C16.1678%2013.1833%2016.1924%2013.3892%2016.1678%2013.5912C16.1376%2013.7876%2016.0564%2013.9745%2015.9299%2014.1293C15.8355%2014.2445%2015.7279%2014.3484%2015.607%2014.4371'%20fill='white'/%3e%3c/g%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='89'%20height='21'%20viewBox='0%200%2089%2021'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.4537%209.65056L5.6297%2017.2781H12.9309C13.4136%2017.243%2013.8916%2017.3924%2014.2685%2017.696C14.4166%2017.8312%2014.5335%2017.997%2014.6112%2018.1818C14.6889%2018.3667%2014.7255%2018.5662%2014.7185%2018.7666C14.7242%2018.9592%2014.6875%2019.1507%2014.6111%2019.3276C14.5346%2019.5045%2014.4202%2019.6624%2014.2759%2019.7902C13.9792%2020.0539%2013.5309%2020.1858%2012.9309%2020.1858H2.83086C2.12127%2020.1858%201.59463%2020.0325%201.24107%2019.7209C1.0652%2019.5615%200.926946%2019.3651%200.836296%2019.1457C0.745646%2018.9264%200.704869%2018.6896%200.716905%2018.4526C0.728826%2018.0998%200.858518%2017.7612%201.0853%2017.4908C1.3309%2017.1611%201.84023%2016.5677%202.61329%2015.7106C3.43744%2014.8007%204.17918%2013.9766%204.83851%2013.2381C5.50608%2012.4964%206.12667%2011.8115%206.70028%2011.1687C7.27389%2010.5258%207.74861%209.98434%208.1269%209.5393C8.50519%209.09426%208.80683%208.71103%209.03429%208.39208H3.5009C2.9168%208.41478%202.33277%208.34553%201.77017%208.18686C1.37787%208.0517%201.18173%207.69237%201.18173%207.10887C1.17386%206.91572%201.2098%206.7233%201.28688%206.54603C1.36395%206.36876%201.48015%206.21123%201.62677%206.08526C1.98683%205.80907%202.43488%205.6729%202.88773%205.70203H11.4425C12.0692%205.66774%2012.6949%205.78744%2013.2647%206.05065C13.6867%206.28306%2013.8985%206.69926%2013.9001%207.29924C13.8974%207.51195%2013.8555%207.72233%2013.7765%207.91984C13.7093%208.10655%2013.6179%208.28361%2013.5045%208.44647C13.4032%208.58246%2013.2573%208.74811%2013.0941%208.94097C12.9309%209.13382%2012.7084%209.37118%2012.4537%209.64562'%20fill='white'/%3e%3cpath%20d='M17.2637%203.64451C16.7764%203.65633%2016.3022%203.4862%2015.9335%203.16732C15.7567%202.99393%2015.6165%202.78678%2015.5212%202.55816C15.4259%202.32955%2015.3776%202.08413%2015.3789%201.83647C15.3803%201.58881%2015.4314%201.34394%2015.5292%201.11641C15.6271%200.888871%2015.7696%200.683299%2015.9483%200.511889C16.3048%200.178623%2016.7758%20-0.00464918%2017.2637%208.96584e-05C17.7334%20-0.00408682%2018.1889%200.160906%2018.5469%200.464912C18.7373%200.632%2018.8868%200.84066%2018.9837%201.07475C19.0806%201.30884%2019.1223%201.56208%2019.1057%201.81488C19.1194%202.06527%2019.0778%202.31562%2018.9838%202.5481C18.8898%202.78058%2018.7457%202.98947%2018.5617%203.15991C18.2073%203.48319%2017.7434%203.65992%2017.2637%203.6544M19.1057%207.50404V18.2716C19.1057%2019.0134%2018.9301%2019.5821%2018.5741%2019.9628C18.4037%2020.15%2018.1948%2020.2981%2017.9618%2020.3972C17.7288%2020.4962%2017.4772%2020.5437%2017.2241%2020.5364C16.9723%2020.5445%2016.7219%2020.4961%2016.4913%2020.3947C16.2607%2020.2933%2016.0557%2020.1415%2015.8915%2019.9505C15.5503%2019.5598%2015.3797%2018.9986%2015.3797%2018.2716V7.60294C15.3797%206.86614%2015.5503%206.31066%2015.8915%205.93649C16.0602%205.75283%2016.2667%205.6078%2016.4967%205.51136C16.7267%205.41491%2016.9749%205.36933%2017.2241%205.37771C17.4758%205.37068%2017.7261%205.41681%2017.9587%205.5131C18.1913%205.60938%2018.401%205.75366%2018.5741%205.93649C18.9496%206.3654%2019.1406%206.92517%2019.1057%207.49415'%20fill='white'/%3e%3cpath%20d='M24.8301%207.43997V7.88996C25.3957%207.10255%2026.1308%206.45199%2026.9811%205.98616C27.8125%205.56827%2028.7334%205.3595%2029.6637%205.37793C30.5817%205.36311%2031.4882%205.58356%2032.2969%206.0183C33.0505%206.42702%2033.6562%207.06291%2034.0276%207.83557C34.2757%208.29687%2034.4375%208.79962%2034.5048%209.31905C34.5864%209.98918%2034.6227%2010.664%2034.6136%2011.3391V18.262C34.6136%2019.0087%2034.443%2019.5724%2034.1018%2019.9531C33.9362%2020.141%2033.731%2020.2899%2033.501%2020.3891C33.271%2020.4883%2033.0219%2020.5353%2032.7716%2020.5268C32.5172%2020.5353%2032.2641%2020.4872%2032.0306%2020.3858C31.7971%2020.2845%2031.5891%2020.1325%2031.4217%2019.9408C31.0755%2019.5501%2030.9024%2018.9889%2030.9024%2018.262V12.0511C30.9024%2010.8149%2030.7318%209.88524%2030.3906%209.23251C30.0494%208.57978%2029.3695%208.25836%2028.3508%208.25836C27.6969%208.25479%2027.0594%208.46296%2026.5336%208.85175C25.9783%209.26214%2025.5602%209.83104%2025.3344%2010.4836C25.1515%2011.0374%2025.06%2012.0742%2025.06%2013.594V18.262C25.06%2019.0169%2024.8853%2019.5831%2024.5358%2019.9606C24.3635%2020.1468%2024.153%2020.2938%2023.9188%2020.3915C23.6846%2020.4892%2023.4321%2020.5353%2023.1784%2020.5268C22.9279%2020.5335%2022.679%2020.4845%2022.4498%2020.3831C22.2206%2020.2818%2022.0168%2020.1307%2021.8532%2019.9408C21.5071%2019.5501%2021.334%2018.9889%2021.334%2018.262V7.49436C21.334%206.78477%2021.4897%206.25813%2021.7988%205.90457C21.958%205.72826%2022.1543%205.58954%2022.3737%205.49845C22.5931%205.40737%2022.8299%205.3662%2023.0672%205.37793C23.3787%205.37314%2023.6856%205.4535%2023.9548%205.61034C24.2293%205.77571%2024.45%206.01702%2024.5902%206.30511C24.7616%206.6584%2024.8463%207.04742%2024.8375%207.43997'%20fill='white'/%3e%3cpath%20d='M40.2031%207.43997V7.88996C40.7688%207.10255%2041.5038%206.45199%2042.3542%205.98616C43.1847%205.56829%2044.1047%205.3595%2045.0343%205.37793C45.9531%205.36279%2046.8605%205.58325%2047.67%206.0183C48.4231%206.4277%2049.0285%207.06339%2049.4007%207.83557C49.6477%208.29734%2049.8093%208.79988%2049.8779%209.31905C49.9582%209.98929%2049.9945%2010.6641%2049.9867%2011.3391V18.262C49.9867%2019.0087%2049.8161%2019.5724%2049.4749%2019.9531C49.3093%2020.141%2049.1041%2020.2899%2048.8741%2020.3891C48.6441%2020.4883%2048.395%2020.5353%2048.1447%2020.5268C47.89%2020.5347%2047.6367%2020.4862%2047.403%2020.3849C47.1692%2020.2836%2046.9606%2020.132%2046.7922%2019.9408C46.4461%2019.5501%2046.2755%2018.9889%2046.2755%2018.262V12.0511C46.2755%2010.8149%2046.1049%209.88524%2045.7637%209.23251C45.4225%208.57978%2044.7401%208.25836%2043.7214%208.25836C43.0683%208.25514%2042.4317%208.4633%2041.9066%208.85175C41.3499%209.26122%2040.9308%209.83035%2040.705%2010.4836C40.5237%2011.0374%2040.433%2012.0742%2040.433%2013.594V18.262C40.433%2019.0169%2040.2575%2019.5831%2039.9064%2019.9606C39.7344%2020.1472%2039.524%2020.2945%2039.2897%2020.3922C39.0554%2020.4899%2038.8027%2020.5358%2038.549%2020.5268C38.2989%2020.5332%2038.0505%2020.4839%2037.8217%2020.3826C37.5929%2020.2813%2037.3896%2020.1303%2037.2263%2019.9408C36.8801%2019.5501%2036.707%2018.9889%2036.707%2018.262V7.49436C36.707%206.78477%2036.8628%206.25813%2037.1719%205.90457C37.331%205.72826%2037.5274%205.58954%2037.7468%205.49845C37.9661%205.40737%2038.203%205.3662%2038.4402%205.37793C38.7517%205.37314%2039.0587%205.4535%2039.3279%205.61034C39.6023%205.77571%2039.823%206.01702%2039.9633%206.30511C40.1346%206.6584%2040.2194%207.04742%2040.2105%207.43997'%20fill='white'/%3e%3cpath%20d='M62.5909%2013.8682H55.3045C55.2961%2014.6445%2055.4706%2015.4119%2055.8138%2016.1083C56.0972%2016.7002%2056.5443%2017.1985%2057.1021%2017.5442C57.6599%2017.8899%2058.3051%2018.0686%2058.9613%2018.059C59.3736%2018.0634%2059.7846%2018.0109%2060.1827%2017.9033C60.5618%2017.7916%2060.9225%2017.625%2061.2533%2017.4088C61.5893%2017.1934%2061.9091%2016.9538%2062.2101%2016.6918C62.5002%2016.4363%2062.8777%2016.091%2063.3425%2015.6558C63.5761%2015.4765%2063.8671%2015.3885%2064.1609%2015.4086C64.4983%2015.3935%2064.8292%2015.5056%2065.0881%2015.7226C65.2092%2015.835%2065.304%2015.973%2065.3656%2016.1264C65.4271%2016.2799%2065.454%2016.4451%2065.4441%2016.6102C65.4164%2017.0309%2065.2801%2017.4372%2065.0485%2017.7895C64.736%2018.2937%2064.3308%2018.7342%2063.8543%2019.0876C63.2467%2019.5398%2062.5682%2019.8882%2061.8467%2020.1186C60.9495%2020.4048%2060.0116%2020.5426%2059.0701%2020.5266C56.6767%2020.5266%2054.8158%2019.8442%2053.4872%2018.4794C52.1587%2017.1146%2051.4944%2015.2635%2051.4944%2012.9262C51.4863%2011.8837%2051.6534%2010.8473%2051.9889%209.86033C52.2925%208.96156%2052.7819%208.1368%2053.4254%207.43978C54.0703%206.75306%2054.8635%206.22281%2055.7446%205.88954C56.7214%205.5203%2057.7588%205.33747%2058.803%205.35054C60.1121%205.31362%2061.4066%205.63234%2062.5488%206.27277C63.5369%206.83149%2064.3482%207.65648%2064.8903%208.65376C65.3902%209.56343%2065.6569%2010.5828%2065.6666%2011.6207C65.6666%2012.5586%2065.3988%2013.166%2064.8631%2013.4429C64.3241%2013.7199%2063.57%2013.8583%2062.5958%2013.8583M55.3094%2011.7443H62.0642C61.9736%2010.4718%2061.6299%209.5183%2061.0332%208.8837C60.7303%208.56817%2060.3638%208.32058%2059.9581%208.15733C59.5523%207.99408%2059.1164%207.91889%2058.6794%207.93674C58.2515%207.92332%2057.8257%208.00227%2057.431%208.16824C57.0364%208.33422%2056.6821%208.5833%2056.3924%208.89853C55.7957%209.53808%2055.4347%2010.4867%2055.3094%2011.7443Z'%20fill='white'/%3e%3cpath%20d='M75.0025%2018.9842L72.3001%2015.0135L69.5309%2018.9842C69.2359%2019.4182%2068.8925%2019.8172%2068.5073%2020.1735C68.21%2020.4156%2067.8347%2020.5412%2067.4516%2020.5271C67.0071%2020.5377%2066.5751%2020.3796%2066.2425%2020.0845C66.0908%2019.9616%2065.9679%2019.8069%2065.8825%2019.6313C65.797%2019.4557%2065.7511%2019.2635%2065.748%2019.0683C65.748%2018.676%2066.0027%2018.1164%2066.512%2017.3895L69.882%2012.5583L66.8928%208.53063C66.3736%207.86801%2066.1164%207.2944%2066.1164%206.7999C66.1177%206.61148%2066.1597%206.42556%2066.2395%206.25486C66.3193%206.08417%2066.435%205.93273%2066.5788%205.81092C66.9148%205.51876%2067.3505%205.36733%2067.7952%205.38813C68.1892%205.37419%2068.5745%205.50527%2068.8782%205.75652C69.2554%206.10401%2069.5921%206.49301%2069.882%206.91611L72.2976%2010.2193L74.6465%206.91611C74.9393%206.48057%2075.2857%206.08351%2075.6775%205.73427C75.9802%205.4913%2076.3601%205.36497%2076.7481%205.37823C77.1925%205.36149%2077.6274%205.5094%2077.9695%205.79361C78.1225%205.9126%2078.2465%206.06477%2078.3321%206.23866C78.4178%206.41254%2078.4629%206.6036%2078.464%206.79743C78.4633%207.08041%2078.3955%207.3592%2078.2661%207.61087C78.0919%207.93536%2077.8883%208.24322%2077.6579%208.53063L74.6489%2012.5583L78.0189%2017.3895C78.5447%2018.1444%2078.8084%2018.7131%2078.8101%2019.0955C78.8094%2019.2901%2078.7645%2019.482%2078.6789%2019.6568C78.5932%2019.8315%2078.469%2019.9845%2078.3156%2020.1043C77.9771%2020.3904%2077.5446%2020.5411%2077.1016%2020.5271C76.7074%2020.538%2076.3223%2020.4073%2076.0162%2020.1587C75.6305%2019.8104%2075.2892%2019.416%2075%2018.9842'%20fill='white'/%3e%3cpath%20d='M80.1811%205.70949H80.5915V3.46944C80.5915%202.86863%2080.6064%202.39886%2080.6385%202.05766C80.6608%201.74802%2080.752%201.44728%2080.9055%201.17746C81.0552%200.917818%2081.2721%200.703405%2081.5335%200.556866C81.8103%200.392732%2082.1266%200.307244%2082.4484%200.309618C82.9289%200.31336%2083.3891%200.504012%2083.7316%200.841198C83.9854%201.06984%2084.1588%201.37415%2084.2261%201.70904C84.3039%202.18956%2084.3378%202.67618%2084.3274%203.16285V5.70949H85.6922C86.1277%205.67931%2086.5587%205.81242%2086.9013%206.08284C87.037%206.20323%2087.1446%206.35203%2087.2164%206.51868C87.2882%206.68533%2087.3224%206.86574%2087.3167%207.0471C87.3338%207.26146%2087.2865%207.47606%2087.1808%207.66332C87.075%207.85057%2086.9157%208.00192%2086.7233%208.0979C86.187%208.32481%2085.6062%208.4271%2085.0247%208.39707H84.3274V15.2483C84.3202%2015.6975%2084.3409%2016.1467%2084.3892%2016.5933C84.4163%2016.8756%2084.5304%2017.1426%2084.7156%2017.3573C84.8317%2017.4641%2084.969%2017.5452%2085.1185%2017.5955C85.268%2017.6457%2085.4264%2017.664%2085.5835%2017.6491C85.8823%2017.6397%2086.1795%2017.6016%2086.4711%2017.5353C86.7574%2017.4677%2087.0498%2017.4288%2087.3439%2017.4191C87.4965%2017.4205%2087.6473%2017.4533%2087.7868%2017.5154C87.9263%2017.5775%2088.0516%2017.6676%2088.1548%2017.7801C88.2737%2017.8963%2088.3673%2018.0357%2088.4298%2018.1897C88.4924%2018.3437%2088.5225%2018.509%2088.5183%2018.6751C88.5183%2019.2735%2088.1886%2019.7325%2087.5293%2020.0523C86.87%2020.3721%2085.9288%2020.5311%2084.7057%2020.5295C83.5387%2020.5295%2082.6585%2020.3342%2082.0577%2019.9435C81.469%2019.5736%2081.0444%2018.9924%2080.8709%2018.3191C80.6615%2017.4107%2080.5677%2016.4794%2080.5915%2015.5475V8.39459H80.097C79.6515%208.42648%2079.2102%208.28969%2078.8608%208.01136C78.7234%207.8914%2078.6142%207.74251%2078.5411%207.57537C78.468%207.40823%2078.4328%207.22698%2078.438%207.04463C78.4337%206.8606%2078.4716%206.67803%2078.5487%206.5109C78.6259%206.34376%2078.7402%206.19649%2078.8831%206.08036C79.2545%205.807%2079.7111%205.67466%2080.1712%205.70702'%20fill='white'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='7'%20height='13'%20viewBox='0%200%207%2013'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M5.04492%206.50535L0.757579%2010.7927C0.457835%2011.0924%200.457835%2011.5784%200.757579%2011.8782C1.05732%2012.1779%201.54331%2012.1779%201.84305%2011.8782L6.67312%207.04809C6.97287%206.74835%206.97287%206.26236%206.67312%205.96262L1.84305%201.13255C1.54331%200.832802%201.05732%200.832802%200.757579%201.13255C0.457835%201.43229%200.457835%201.91827%200.757579%202.21802L5.04492%206.50535Z'%20fill='white'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M10%2019C5.5544%2017.9895%202%2013.6998%202%209.18182V4.27273L10%201L18%204.27273V9.18182C18%2013.7015%2014.4456%2017.9895%2010%2019ZM3.6%205.09091V9.18182C3.64572%2011.0736%204.29629%2012.8979%205.45214%2014.3755C6.608%2015.8532%208.20545%2016.9028%2010%2017.3636C11.7946%2016.9028%2013.392%2015.8532%2014.5479%2014.3755C15.7037%2012.8979%2016.3543%2011.0736%2016.4%209.18182V5.09091L10%202.63636L3.6%205.09091Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M10%209.18185C11.1046%209.18185%2012%208.26607%2012%207.1364C12%206.00672%2011.1046%205.09094%2010%205.09094C8.89543%205.09094%208%206.00672%208%207.1364C8%208.26607%208.89543%209.18185%2010%209.18185Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M6%2012.4545C6.39431%2013.1894%206.97247%2013.804%207.67531%2014.2353C8.37815%2014.6666%209.18042%2014.8991%2010%2014.9091C10.8196%2014.8991%2011.6219%2014.6666%2012.3247%2014.2353C13.0275%2013.804%2013.6057%2013.1894%2014%2012.4545C13.98%2010.9033%2011.3264%2010%2010%2010C8.6664%2010%206.02%2010.9033%206%2012.4545Z'%20fill='%23C9C9E8'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M6.66669%202.5H13.3334C14.2538%202.5%2015%203.24619%2015%204.16667V17.5L10%2015L5%2017.5V4.16667C5%203.24619%205.74621%202.5%206.66669%202.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M7.91669%207.5H12.0834'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M7.91669%2010.8333H10.8334'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M15%205.83333H16.25C16.9404%205.83333%2017.5%206.39298%2017.5%207.08333V13.75C17.5%2014.4404%2016.9404%2015%2016.25%2015H15'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M5%2015H3.75C3.05964%2015%202.5%2014.4404%202.5%2013.75V7.08333C2.5%206.39298%203.05964%205.83333%203.75%205.83333H5'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M17%205.3335H3.66667C2.74619%205.3335%202%206.07969%202%207.00016V15.3335C2%2016.254%202.74619%2017.0002%203.66667%2017.0002H17C17.9205%2017.0002%2018.6667%2016.254%2018.6667%2015.3335V7.00016C18.6667%206.07969%2017.9205%205.3335%2017%205.3335Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.6667%2017V3.66667C13.6667%203.22464%2013.4911%202.80072%2013.1785%202.48816C12.866%202.17559%2012.442%202%2012%202H8.66667C8.22464%202%207.80072%202.17559%207.48816%202.48816C7.1756%202.80072%207%203.22464%207%203.66667V17'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M19.1667%2017.5V15.8333C19.1661%2015.0948%2018.9203%2014.3773%2018.4678%2013.7936C18.0153%2013.2099%2017.3818%2012.793%2016.6667%2012.6083'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M14.1667%2017.5V15.8333C14.1667%2014.9493%2013.8155%2014.1014%2013.1904%2013.4763C12.5652%2012.8512%2011.7174%2012.5%2010.8333%2012.5H4.16668C3.28262%2012.5%202.43478%2012.8512%201.80965%2013.4763C1.18453%2014.1014%200.833344%2014.9493%200.833344%2015.8333V17.5'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3333%202.60834C14.0504%202.79192%2014.6859%203.20892%2015.1397%203.7936C15.5935%204.37827%2015.8399%205.09736%2015.8399%205.8375C15.8399%206.57765%2015.5935%207.29674%2015.1397%207.88141C14.6859%208.46609%2014.0504%208.88309%2013.3333%209.06667'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M7.49999%209.16667C9.34094%209.16667%2010.8333%207.67428%2010.8333%205.83333C10.8333%203.99238%209.34094%202.5%207.49999%202.5C5.65904%202.5%204.16666%203.99238%204.16666%205.83333C4.16666%207.67428%205.65904%209.16667%207.49999%209.16667Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M3.33331%205.83333C3.33331%204.91286%204.07951%204.16667%204.99998%204.16667H11.6666C12.5871%204.16667%2013.3333%204.91286%2013.3333%205.83333V12.5C13.3333%2013.4205%2012.5871%2014.1667%2011.6666%2014.1667H4.99998C4.07951%2014.1667%203.33331%2013.4205%203.33331%2012.5V5.83333Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M6.24998%208.33333C6.24998%207.8731%206.62308%207.5%207.08331%207.5H9.16665C9.62688%207.5%209.99998%207.8731%209.99998%208.33333C9.99998%208.79357%209.62688%209.16667%209.16665%209.16667H7.08331C6.62308%209.16667%206.24998%208.79357%206.24998%208.33333Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M5.83331%2011.6667H10.8333'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3333%207.5H15.8333C16.7538%207.5%2017.5%208.24619%2017.5%209.16667C17.5%2010.0871%2016.7538%2010.8333%2015.8333%2010.8333H13.3333'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3333%2014.1667L15.4166%2016.25'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M16.25%2017.5C16.9403%2017.5%2017.5%2016.9404%2017.5%2016.25C17.5%2015.5596%2016.9403%2015%2016.25%2015C15.5596%2015%2015%2015.5596%2015%2016.25C15%2016.9404%2015.5596%2017.5%2016.25%2017.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M2.49998%203.33333C3.19034%203.33333%203.74998%202.77369%203.74998%202.08333C3.74998%201.39298%203.19034%200.833333%202.49998%200.833333C1.80962%200.833333%201.24998%201.39298%201.24998%202.08333C1.24998%202.77369%201.80962%203.33333%202.49998%203.33333Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M3.41665%202.91667L4.99998%204.16667'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M17.5%2011.6667H11.6667V17.5001H17.5V11.6667Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M8.33333%2011.6667H2.5V17.5001H8.33333V11.6667Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M17.5%202.5H11.6667V8.33333H17.5V2.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M8.33333%202.5H2.5V8.33333H8.33333V2.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M3.33331%208.33333H16.6666V16.25C16.6666%2016.7102%2016.2936%2017.0833%2015.8333%2017.0833H4.16665C3.70641%2017.0833%203.33331%2016.7102%203.33331%2016.25V8.33333Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M6.66669%208.33333V5.41667C6.66669%204.95643%207.03978%204.58333%207.50002%204.58333H12.5C12.9603%204.58333%2013.3334%204.95643%2013.3334%205.41667V8.33333'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M2.5%208.33333H17.5'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'/%3e%3cpath%20d='M7.5%2012.0833H12.5'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'/%3e%3cpath%20d='M10%209.58333V14.5833'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'/%3e%3cpath%20d='M5.83331%202.91667H14.1666'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M10%201C5.02991%201%201%205.02991%201%2010C1%2014.9701%205.02991%2019%2010%2019C14.9701%2019%2019%2014.9701%2019%2010C19%205.02991%2014.9701%201%2010%201ZM10%2017.4732C5.87366%2017.4732%202.52679%2014.1263%202.52679%2010C2.52679%205.87366%205.87366%202.52679%2010%202.52679C14.1263%202.52679%2017.4732%205.87366%2017.4732%2010C17.4732%2014.1263%2014.1263%2017.4732%2010%2017.4732Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M12.242%206.07661C11.6393%205.54826%2010.8437%205.25897%209.99999%205.25897C9.15624%205.25897%208.36071%205.55027%207.75803%206.07661C7.13124%206.62504%206.78571%207.36232%206.78571%208.15183V8.30451C6.78571%208.3929%206.85803%208.46522%206.94642%208.46522H7.91071C7.9991%208.46522%208.07142%208.3929%208.07142%208.30451V8.15183C8.07142%207.26589%208.93727%206.54469%209.99999%206.54469C11.0627%206.54469%2011.9286%207.26589%2011.9286%208.15183C11.9286%208.77661%2011.4866%209.34915%2010.8016%209.61232C10.3757%209.77504%2010.0141%2010.0603%209.7549%2010.434C9.49173%2010.8157%209.35512%2011.2737%209.35512%2011.7378V12.1697C9.35512%2012.2581%209.42745%2012.3304%209.51584%2012.3304H10.4801C10.5685%2012.3304%2010.6408%2012.2581%2010.6408%2012.1697V11.7137C10.6419%2011.5186%2010.7017%2011.3285%2010.8124%2011.1679C10.9231%2011.0074%2011.0797%2010.8839%2011.2616%2010.8137C12.4469%2010.3576%2013.2123%209.31299%2013.2123%208.15183C13.2143%207.36232%2012.8687%206.62504%2012.242%206.07661ZM9.19642%2014.4197C9.19642%2014.6328%209.28108%2014.8372%209.43178%2014.9879C9.58248%2015.1386%209.78687%2015.2233%209.99999%2015.2233C10.2131%2015.2233%2010.4175%2015.1386%2010.5682%2014.9879C10.7189%2014.8372%2010.8036%2014.6328%2010.8036%2014.4197C10.8036%2014.2066%2010.7189%2014.0022%2010.5682%2013.8515C10.4175%2013.7008%2010.2131%2013.6161%209.99999%2013.6161C9.78687%2013.6161%209.58248%2013.7008%209.43178%2013.8515C9.28108%2014.0022%209.19642%2014.2066%209.19642%2014.4197Z'%20fill='%23C9C9E8'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15%2018.3333C16.3807%2018.3333%2017.5%2017.214%2017.5%2015.8333C17.5%2014.4526%2016.3807%2013.3333%2015%2013.3333C13.6193%2013.3333%2012.5%2014.4526%2012.5%2015.8333C12.5%2017.214%2013.6193%2018.3333%2015%2018.3333Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M5%2012.5C6.38071%2012.5%207.5%2011.3807%207.5%2010C7.5%208.61929%206.38071%207.5%205%207.5C3.61929%207.5%202.5%208.61929%202.5%2010C2.5%2011.3807%203.61929%2012.5%205%2012.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M7.15833%2011.2584L12.85%2014.575'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M15%206.66669C16.3807%206.66669%2017.5%205.5474%2017.5%204.16669C17.5%202.78598%2016.3807%201.66669%2015%201.66669C13.6193%201.66669%2012.5%202.78598%2012.5%204.16669C12.5%205.5474%2013.6193%206.66669%2015%206.66669Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M12.8417%205.42499L7.15833%208.74165'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M11.6667%201.66669H5.00001C4.55798%201.66669%204.13406%201.84228%203.8215%202.15484C3.50894%202.4674%203.33334%202.89133%203.33334%203.33335V16.6667C3.33334%2017.1087%203.50894%2017.5326%203.8215%2017.8452C4.13406%2018.1578%204.55798%2018.3334%205.00001%2018.3334H15C15.442%2018.3334%2015.866%2018.1578%2016.1785%2017.8452C16.4911%2017.5326%2016.6667%2017.1087%2016.6667%2016.6667V6.66669L11.6667%201.66669Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3333%2014.1667H6.66666'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3333%2010.8333H6.66666'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M8.33332%207.5H7.49999H6.66666'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M11.6667%201.66669V6.66669H16.6667'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_530_15536)'%3e%3cpath%20d='M10%2012.5C11.3807%2012.5%2012.5%2011.3807%2012.5%2010C12.5%208.61929%2011.3807%207.5%2010%207.5C8.61929%207.5%207.5%208.61929%207.5%2010C7.5%2011.3807%208.61929%2012.5%2010%2012.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M16.1667%2012.5C16.0557%2012.7513%2016.0227%2013.0301%2016.0717%2013.3005C16.1207%2013.5708%2016.2496%2013.8202%2016.4417%2014.0166L16.4917%2014.0666C16.6466%2014.2214%2016.7696%2014.4052%2016.8534%2014.6076C16.9373%2014.8099%2016.9805%2015.0268%2016.9805%2015.2458C16.9805%2015.4648%2016.9373%2015.6817%2016.8534%2015.884C16.7696%2016.0864%2016.6466%2016.2702%2016.4917%2016.425C16.3369%2016.5799%2016.1531%2016.7029%2015.9507%2016.7867C15.7484%2016.8706%2015.5315%2016.9138%2015.3125%2016.9138C15.0935%2016.9138%2014.8766%2016.8706%2014.6743%2016.7867C14.4719%2016.7029%2014.2881%2016.5799%2014.1333%2016.425L14.0833%2016.375C13.8869%2016.1829%2013.6375%2016.054%2013.3672%2016.005C13.0968%2015.956%2012.818%2015.989%2012.5667%2016.1C12.3202%2016.2056%2012.11%2016.381%2011.9619%2016.6046C11.8139%2016.8282%2011.7344%2017.0902%2011.7333%2017.3583V17.5C11.7333%2017.942%2011.5577%2018.3659%2011.2452%2018.6785C10.9326%2018.991%2010.5087%2019.1666%2010.0667%2019.1666C9.62465%2019.1666%209.20073%2018.991%208.88817%2018.6785C8.5756%2018.3659%208.40001%2017.942%208.40001%2017.5V17.425C8.39356%2017.1491%208.30427%2016.8816%208.14377%2016.6572C7.98326%2016.4328%207.75896%2016.2619%207.50001%2016.1666C7.24866%2016.0557%206.96985%2016.0226%206.69952%2016.0716C6.42919%2016.1207%206.17974%2016.2495%205.98334%2016.4416L5.93334%2016.4916C5.77855%2016.6466%205.59474%2016.7695%205.39241%2016.8534C5.19008%2016.9373%204.9732%2016.9805%204.75418%2016.9805C4.53515%2016.9805%204.31827%2016.9373%204.11594%2016.8534C3.91361%2016.7695%203.7298%2016.6466%203.57501%2016.4916C3.42005%2016.3369%203.29712%2016.153%203.21324%2015.9507C3.12937%2015.7484%203.0862%2015.5315%203.0862%2015.3125C3.0862%2015.0935%203.12937%2014.8766%203.21324%2014.6742C3.29712%2014.4719%203.42005%2014.2881%203.57501%2014.1333L3.62501%2014.0833C3.81712%2013.8869%203.946%2013.6375%203.99501%2013.3671C4.04403%2013.0968%204.01094%2012.818%203.90001%2012.5666C3.79437%2012.3202%203.61897%2012.11%203.3954%2011.9619C3.17182%2011.8138%202.90983%2011.7344%202.64168%2011.7333H2.50001C2.05798%2011.7333%201.63406%2011.5577%201.3215%2011.2452C1.00894%2010.9326%200.833344%2010.5087%200.833344%2010.0666C0.833344%209.62462%201.00894%209.2007%201.3215%208.88813C1.63406%208.57557%202.05798%208.39998%202.50001%208.39998H2.57501C2.85084%208.39353%203.11835%208.30424%203.34276%208.14374C3.56717%207.98323%203.73811%207.75893%203.83334%207.49998C3.94427%207.24863%203.97736%206.96982%203.92835%206.69949C3.87933%206.42916%203.75046%206.17971%203.55834%205.98331L3.50834%205.93331C3.35338%205.77852%203.23045%205.59471%203.14658%205.39238C3.0627%205.19005%203.01953%204.97317%203.01953%204.75415C3.01953%204.53512%203.0627%204.31824%203.14658%204.11591C3.23045%203.91358%203.35338%203.72977%203.50834%203.57498C3.66313%203.42002%203.84695%203.29709%204.04928%203.21321C4.25161%203.12934%204.46848%203.08617%204.68751%203.08617C4.90654%203.08617%205.12341%203.12934%205.32574%203.21321C5.52807%203.29709%205.71189%203.42002%205.86668%203.57498L5.91668%203.62498C6.11308%203.81709%206.36252%203.94597%206.63285%203.99498C6.90318%204.044%207.182%204.01091%207.43334%203.89998H7.50001C7.74648%203.79434%207.95669%203.61894%208.10475%203.39537C8.25282%203.17179%208.33227%202.9098%208.33334%202.64165V2.49998C8.33334%202.05795%208.50894%201.63403%208.8215%201.32147C9.13406%201.00891%209.55798%200.833313%2010%200.833313C10.442%200.833313%2010.866%201.00891%2011.1785%201.32147C11.4911%201.63403%2011.6667%202.05795%2011.6667%202.49998V2.57498C11.6677%202.84313%2011.7472%203.10513%2011.8953%203.3287C12.0433%203.55228%2012.2535%203.72768%2012.5%203.83331C12.7514%203.94424%2013.0302%203.97733%2013.3005%203.92832C13.5708%203.8793%2013.8203%203.75043%2014.0167%203.55831L14.0667%203.50831C14.2215%203.35335%2014.4053%203.23042%2014.6076%203.14655C14.8099%203.06267%2015.0268%203.0195%2015.2458%203.0195C15.4649%203.0195%2015.6817%203.06267%2015.8841%203.14655C16.0864%203.23042%2016.2702%203.35335%2016.425%203.50831C16.58%203.6631%2016.7029%203.84692%2016.7868%204.04925C16.8706%204.25158%2016.9138%204.46845%2016.9138%204.68748C16.9138%204.90651%2016.8706%205.12338%2016.7868%205.32571C16.7029%205.52804%2016.58%205.71186%2016.425%205.86665L16.375%205.91665C16.1829%206.11305%2016.054%206.36249%2016.005%206.63282C15.956%206.90315%2015.9891%207.18197%2016.1%207.43331V7.49998C16.2056%207.74645%2016.381%207.95666%2016.6046%208.10472C16.8282%208.25279%2017.0902%208.33224%2017.3583%208.33331H17.5C17.942%208.33331%2018.366%208.50891%2018.6785%208.82147C18.9911%209.13403%2019.1667%209.55795%2019.1667%209.99998C19.1667%2010.442%2018.9911%2010.8659%2018.6785%2011.1785C18.366%2011.4911%2017.942%2011.6666%2017.5%2011.6666H17.425C17.1569%2011.6677%2016.8949%2011.7472%2016.6713%2011.8952C16.4477%2012.0433%2016.2723%2012.2535%2016.1667%2012.5V12.5Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_530_15536'%3e%3crect%20width='20'%20height='20'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M1%204.33333C1%203.18274%201.93274%202.25%203.08333%202.25H16.4167C17.5673%202.25%2018.5%203.18274%2018.5%204.33333V16C18.5%2017.1506%2017.5673%2018.0833%2016.4167%2018.0833H3.08333C1.93274%2018.0833%201%2017.1506%201%2016V4.33333ZM3.08333%203.08333C2.39298%203.08333%201.83333%203.64298%201.83333%204.33333V16C1.83333%2016.6904%202.39298%2017.25%203.08333%2017.25H16.4167C17.107%2017.25%2017.6667%2016.6904%2017.6667%2016V4.33333C17.6667%203.64298%2017.107%203.08333%2016.4167%203.08333H3.08333Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'%20stroke-linejoin='round'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M1%204.33333C1%203.18274%201.93274%202.25%203.08333%202.25H16.4167C17.5673%202.25%2018.5%203.18274%2018.5%204.33333V6.83333C18.5%207.06345%2018.3135%207.25%2018.0833%207.25H1.41667C1.18655%207.25%201%207.06345%201%206.83333V4.33333ZM3.08333%203.08333C2.39298%203.08333%201.83333%203.64298%201.83333%204.33333V6.41667H17.6667V4.33333C17.6667%203.64298%2017.107%203.08333%2016.4167%203.08333H3.08333Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'%20stroke-linejoin='round'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M4.33333%201V3.91667H3.5V1H4.33333Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M10.1667%201V3.91667H9.33334V1H10.1667Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M16%201V3.91667H15.1667V1H16Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M6.53453%2015.2573C6.43104%2015.1538%206.38944%2015.0036%206.42493%2014.8616L7.01419%2012.5046C7.03251%2012.4313%207.07039%2012.3644%207.12379%2012.311L10.0701%209.36472C10.5582%208.87657%2011.3497%208.87657%2011.8378%209.36472L12.4271%209.95398C12.9152%2010.4421%2012.9152%2011.2336%2012.4271%2011.7217L9.48081%2014.668C9.42741%2014.7214%209.3605%2014.7593%209.28724%2014.7776L6.93022%2015.3669C6.78823%2015.4024%206.63802%2015.3608%206.53453%2015.2573ZM8.97316%2013.9972L11.8378%2011.1325C12.0006%2010.9698%2012.0006%2010.706%2011.8378%2010.5432L11.2486%209.95398C11.0859%209.79126%2010.822%209.79126%2010.6593%209.95398L7.79465%2012.8186L7.40181%2014.39L8.97316%2013.9972Z'%20fill='%23C9C9E8'%20stroke='%23C9C9E8'%20stroke-width='0.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_530_15505)'%3e%3cpath%20d='M18.3333%201.66669L9.16666%2010.8334'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M18.3333%201.66669L12.5%2018.3334L9.16666%2010.8334L1.66666%207.50002L18.3333%201.66669Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_530_15505'%3e%3crect%20width='20'%20height='20'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_7154_21562)'%3e%3cpath%20d='M4.10156%208.64844H8.24219V9.82031H4.10156V8.64844Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M4.10156%2010.9922H8.24219V12.1641H4.10156V10.9922Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M4.10156%2013.3359H8.24219V14.5078H4.10156V13.3359Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M18.2422%2011.3516H20V0.804688H9.41406V3.96074H4.10156C2.80922%203.96074%201.75781%205.01215%201.75781%206.30449V14.5076C1.75781%2014.9344%201.87301%2015.3345%202.07312%2015.6795H0V16.2654C0%2017.8809%201.31426%2019.1951%202.92969%2019.1951H17.0703C18.6857%2019.1951%2020%2017.8809%2020%2016.2654V15.6795H17.9269C18.127%2015.3345%2018.2422%2014.9344%2018.2422%2014.5076V11.3516ZM10.5859%201.97656H18.8281V10.1797H12.1429L10.5859%2011.7112V1.97656ZM1.27227%2016.8513H7.07031V18.0232H2.92969C2.16578%2018.0232%201.5141%2017.5334%201.27227%2016.8513ZM11.7578%2016.8513V18.0232H8.24219V16.8513H11.7578ZM17.0703%2018.0232H12.9297V16.8513H18.7277C18.4859%2017.5334%2017.8342%2018.0232%2017.0703%2018.0232ZM4.10156%2015.6795C3.45539%2015.6795%202.92969%2015.1538%202.92969%2014.5076V6.30445C2.92969%205.65828%203.45539%205.13258%204.10156%205.13258H9.41406V14.5075L12.6227%2011.3515H17.0703V14.5076C17.0703%2015.1538%2016.5446%2015.6795%2015.8984%2015.6795H4.10156Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M17.6367%208.42184C17.6367%207.64664%2017.3213%206.88887%2016.7714%206.34258L16.4648%206.0368V4.90625C16.4648%203.93699%2015.6763%203.14844%2014.707%203.14844C13.7378%203.14844%2012.9492%203.93699%2012.9492%204.90625V6.03691L12.6437%206.34152C12.0931%206.88793%2011.7773%207.64617%2011.7773%208.42188V9.00781H17.6367V8.42184ZM13.0507%207.8359C13.1386%207.58801%2013.2814%207.35973%2013.4702%207.17234L14.1211%206.52328V4.90625C14.1211%204.58316%2014.3839%204.32031%2014.707%204.32031C15.0301%204.32031%2015.293%204.58316%2015.293%204.90625V6.52313L15.9448%207.17336C16.1331%207.36016%2016.2756%207.5882%2016.3634%207.83594H13.0507V7.8359Z'%20fill='%23C9C9E8'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_7154_21562'%3e%3crect%20width='20'%20height='20'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_6415_8719)'%3e%3cpath%20d='M10.0391%208.88672H11.0156C11.3392%208.88672%2011.6016%208.62438%2011.6016%208.30078C11.6016%207.97719%2011.3392%207.71484%2011.0156%207.71484H10.0391C9.71547%207.71484%209.45312%207.97719%209.45312%208.30078C9.45312%208.62438%209.71547%208.88672%2010.0391%208.88672Z'%20fill='white'/%3e%3cpath%20d='M7.53906%207.71484H6.5625C6.23891%207.71484%205.97656%207.97719%205.97656%208.30078C5.97656%208.62438%206.23891%208.88672%206.5625%208.88672H7.53906C7.86266%208.88672%208.125%208.62438%208.125%208.30078C8.125%207.97719%207.86266%207.71484%207.53906%207.71484Z'%20fill='white'/%3e%3cpath%20d='M13.5156%208.88672H14.4922C14.8158%208.88672%2015.0781%208.62438%2015.0781%208.30078C15.0781%207.97719%2014.8158%207.71484%2014.4922%207.71484H13.5156C13.192%207.71484%2012.9297%207.97719%2012.9297%208.30078C12.9297%208.62438%2013.192%208.88672%2013.5156%208.88672Z'%20fill='white'/%3e%3cpath%20d='M4.0625%2010.3516H3.08594C2.76234%2010.3516%202.5%2010.6139%202.5%2010.9375C2.5%2011.2611%202.76234%2011.5234%203.08594%2011.5234H4.0625C4.38609%2011.5234%204.64844%2011.2611%204.64844%2010.9375C4.64844%2010.6139%204.38609%2010.3516%204.0625%2010.3516Z'%20fill='white'/%3e%3cpath%20d='M7.53906%2010.3516H6.5625C6.23891%2010.3516%205.97656%2010.6139%205.97656%2010.9375C5.97656%2011.2611%206.23891%2011.5234%206.5625%2011.5234H7.53906C7.86266%2011.5234%208.125%2011.2611%208.125%2010.9375C8.125%2010.6139%207.86266%2010.3516%207.53906%2010.3516Z'%20fill='white'/%3e%3cpath%20d='M11.6016%2010.9375C11.6016%2010.6139%2011.3392%2010.3516%2011.0156%2010.3516H10.0391C9.71547%2010.3516%209.45312%2010.6139%209.45312%2010.9375C9.45312%2011.2611%209.71547%2011.5234%2010.0391%2011.5234H11.0156C11.3392%2011.5234%2011.6016%2011.2611%2011.6016%2010.9375Z'%20fill='white'/%3e%3cpath%20d='M4.0625%2012.9883H3.08594C2.76234%2012.9883%202.5%2013.2506%202.5%2013.5742C2.5%2013.8978%202.76234%2014.1602%203.08594%2014.1602H4.0625C4.38609%2014.1602%204.64844%2013.8978%204.64844%2013.5742C4.64844%2013.2506%204.38609%2012.9883%204.0625%2012.9883Z'%20fill='white'/%3e%3cpath%20d='M7.53906%2012.9883H6.5625C6.23891%2012.9883%205.97656%2013.2506%205.97656%2013.5742C5.97656%2013.8978%206.23891%2014.1602%206.5625%2014.1602H7.53906C7.86266%2014.1602%208.125%2013.8978%208.125%2013.5742C8.125%2013.2506%207.86266%2012.9883%207.53906%2012.9883Z'%20fill='white'/%3e%3cpath%20d='M17.5781%2010.9014V3.32031C17.5781%202.13566%2016.6143%201.17188%2015.4297%201.17188H14.2969V0.585938C14.2969%200.262344%2014.0345%200%2013.7109%200C13.3873%200%2013.125%200.262344%2013.125%200.585938V1.17188H11.0156V0.585938C11.0156%200.262344%2010.7533%200%2010.4297%200C10.1061%200%209.84375%200.262344%209.84375%200.585938V1.17188H7.73438V0.585938C7.73438%200.262344%207.47203%200%207.14844%200C6.82484%200%206.5625%200.262344%206.5625%200.585938V1.17188H4.45312V0.585938C4.45312%200.262344%204.19078%200%203.86719%200C3.54359%200%203.28125%200.262344%203.28125%200.585938V1.17188H2.14844C0.963789%201.17188%200%202.13566%200%203.32031V15.0391C0%2016.0083%200.788555%2016.7969%201.75781%2016.7969H10.5321C11.2184%2018.6643%2013.0147%2020%2015.1172%2020C17.8096%2020%2020%2017.8096%2020%2015.1172C20%2013.3217%2019.0257%2011.7496%2017.5781%2010.9014ZM1.17188%203.32031C1.17188%202.78184%201.60996%202.34375%202.14844%202.34375H3.28125V2.92969C3.28125%203.25328%203.54359%203.51562%203.86719%203.51562C4.19078%203.51562%204.45312%203.25328%204.45312%202.92969V2.34375H6.5625V2.92969C6.5625%203.25328%206.82484%203.51562%207.14844%203.51562C7.47203%203.51562%207.73438%203.25328%207.73438%202.92969V2.34375H9.84375V2.92969C9.84375%203.25328%2010.1061%203.51562%2010.4297%203.51562C10.7533%203.51562%2011.0156%203.25328%2011.0156%202.92969V2.34375H13.125V2.92969C13.125%203.25328%2013.3873%203.51562%2013.7109%203.51562C14.0345%203.51562%2014.2969%203.25328%2014.2969%202.92969V2.34375H15.4297C15.9682%202.34375%2016.4062%202.78184%2016.4062%203.32031V5.07812H1.17188V3.32031ZM1.75781%2015.625C1.43473%2015.625%201.17188%2015.3621%201.17188%2015.0391V6.25H16.4062V10.4074C15.9954%2010.2948%2015.5632%2010.2344%2015.1172%2010.2344C12.4248%2010.2344%2010.2344%2012.4248%2010.2344%2015.1172C10.2344%2015.2886%2010.2434%2015.458%2010.2607%2015.625H1.75781ZM15.1172%2018.8281C13.071%2018.8281%2011.4062%2017.1634%2011.4062%2015.1172C11.4062%2013.071%2013.071%2011.4062%2015.1172%2011.4062C17.1634%2011.4062%2018.8281%2013.071%2018.8281%2015.1172C18.8281%2017.1634%2017.1634%2018.8281%2015.1172%2018.8281Z'%20fill='white'/%3e%3cpath%20d='M17.0703%2014.5312H15.7031V13.1641C15.7031%2012.8405%2015.4408%2012.5781%2015.1172%2012.5781C14.7936%2012.5781%2014.5312%2012.8405%2014.5312%2013.1641V15.1172C14.5312%2015.4408%2014.7936%2015.7031%2015.1172%2015.7031H17.0703C17.3939%2015.7031%2017.6562%2015.4408%2017.6562%2015.1172C17.6562%2014.7936%2017.3939%2014.5312%2017.0703%2014.5312Z'%20fill='white'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_6415_8719'%3e%3crect%20width='20'%20height='20'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18.415%208.82125C18.21%208.71313%2017.9606%208.72938%2017.7694%208.86063L11.8056%2012.9894L10.3562%2011.9856C10.1419%2011.8375%209.85875%2011.8375%209.64437%2011.9856L8.19438%2012.9894L3.0275%209.4125L5.32188%208.03563C5.61813%207.85813%205.71375%207.47438%205.53625%207.17813C5.35875%206.88188%204.97438%206.78625%204.67875%206.96375L1.55375%208.83875C1.37%208.94875%201.25%209.17563%201.25%209.375V16.875C1.25%2017.9088%202.09125%2018.75%203.125%2018.75H16.875C17.9088%2018.75%2018.75%2017.9088%2018.75%2016.875V9.375C18.75%209.1425%2018.6206%208.92938%2018.415%208.82125ZM2.51%2016.925C2.50875%2016.9075%202.5%2016.8925%202.5%2016.875V10.5681L7.09625%2013.75L2.51%2016.925ZM3.87625%2017.5L10%2013.26L16.1244%2017.5H3.87625ZM17.5%2016.875C17.5%2016.8925%2017.4912%2016.9075%2017.49%2016.925L12.9037%2013.75L17.5%2010.5681V16.875Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M13.3644%208.7025C13.5975%208.60562%2013.75%208.3775%2013.75%208.125V2.5C13.75%202.2475%2013.5975%202.01937%2013.3644%201.9225C13.13%201.825%2012.8619%201.87937%2012.6831%202.05812C11.6162%203.125%209.95937%203.125%208.75%203.125H7.8125C6.60625%203.125%205.625%204.10625%205.625%205.3125C5.625%206.44875%206.49937%207.37437%207.60875%207.47937L8.1375%2010.1225C8.20438%2010.4587%208.53187%2010.6806%208.87312%2010.6125C9.21187%2010.545%209.43125%2010.2156%209.36312%209.87687L8.8875%207.5C10.0831%207.50125%2011.655%207.53812%2012.6831%208.56625C12.8619%208.74562%2013.13%208.79937%2013.3644%208.7025ZM8.125%206.25H7.8125C7.29562%206.25%206.875%205.82937%206.875%205.3125C6.875%204.79562%207.29562%204.375%207.8125%204.375H8.125V6.25ZM12.5%206.905C11.4719%206.3725%2010.3263%206.27437%209.375%206.25562V4.36937C10.3263%204.35062%2011.4719%204.2525%2012.5%203.72V6.905Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M16.25%204.6875H17.5C17.845%204.6875%2018.125%204.9675%2018.125%205.3125C18.125%205.6575%2017.845%205.9375%2017.5%205.9375H16.25C15.905%205.9375%2015.625%205.6575%2015.625%205.3125C15.625%204.9675%2015.905%204.6875%2016.25%204.6875Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M17.2488%202.1875C17.4213%202.48625%2017.3188%202.86875%2017.02%203.04125L15.9375%203.66625C15.6413%203.8375%2015.2575%203.73875%2015.0838%203.4375C14.9113%203.13875%2015.0138%202.75625%2015.3125%202.58375L16.395%201.95875C16.6931%201.78562%2017.0763%201.88812%2017.2488%202.1875Z'%20fill='%23C9C9E8'/%3e%3cpath%20d='M15.0838%207.1875C15.2563%206.88813%2015.6388%206.78562%2015.9375%206.95875L17.02%207.58375C17.3194%207.75625%2017.4213%208.13875%2017.2488%208.4375C17.075%208.73813%2016.6913%208.8375%2016.395%208.66625L15.3125%208.04125C15.0132%207.86875%2014.9113%207.48625%2015.0838%207.1875Z'%20fill='%23C9C9E8'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M20%204.35092C20%203.33607%2019.1743%202.51041%2018.1595%202.51041H1.84052C0.825863%202.51045%200.000351564%203.33572%200%204.35123V4.35155V15.6484C0%2016.676%200.834066%2017.4896%201.84114%2017.4896H18.1588C19.1863%2017.4896%2020%2016.6555%2020%2015.6484V4.35155C20%204.35147%2020%204.35139%2020%204.35131C20%204.35119%2020%204.35108%2020%204.35092ZM1.84052%203.68233H18.1595C18.5282%203.68233%2018.8281%203.98229%2018.8281%204.3519C18.8281%204.54831%2018.7305%204.73061%2018.5668%204.83967L10.3713%2010.3036C10.1458%2010.454%209.8543%2010.454%209.62875%2010.3036C9.62875%2010.3036%201.43301%204.83956%201.43317%204.83967C1.43321%204.83971%201.43305%204.8396%201.43301%204.83956C1.2695%204.73061%201.17188%204.54831%201.17188%204.35092C1.17188%203.98225%201.47184%203.68233%201.84052%203.68233ZM18.1589%2016.3177H1.84114C1.47633%2016.3177%201.17188%2016.0227%201.17188%2015.6484V6.07394L8.97867%2011.2786C9.2889%2011.4854%209.64445%2011.5888%2010%2011.5888C10.3556%2011.5888%2010.7112%2011.4854%2011.0214%2011.2786L18.8281%206.07394V15.6485C18.8281%2016.0132%2018.5332%2016.3177%2018.1589%2016.3177Z'%20fill='%23586888'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M11.6666%201.66666H4.99992C4.55789%201.66666%204.13397%201.84225%203.82141%202.15481C3.50885%202.46737%203.33325%202.8913%203.33325%203.33332V16.6667C3.33325%2017.1087%203.50885%2017.5326%203.82141%2017.8452C4.13397%2018.1577%204.55789%2018.3333%204.99992%2018.3333H14.9999C15.4419%2018.3333%2015.8659%2018.1577%2016.1784%2017.8452C16.491%2017.5326%2016.6666%2017.1087%2016.6666%2016.6667V6.66666L11.6666%201.66666Z'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3334%2014.1667H6.66675'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M13.3334%2010.8333H6.66675'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M8.33341%207.5H7.50008H6.66675'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M11.6667%201.66666V6.66666H16.6667'%20stroke='%23C9C9E8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15.3077%2011.0205C15.6349%2010.7536%2016.1175%2010.7725%2016.4226%2011.0775L19.1309%2013.7858C19.4562%2014.1112%2019.4562%2014.6387%2019.1309%2014.9641C18.8055%2015.2895%2018.278%2015.2895%2017.9526%2014.9641L16.6667%2013.6784V18.3333C16.6667%2018.7935%2016.2936%2019.1666%2015.8334%2019.1666C15.3733%2019.1666%2015.0002%2018.7934%2015.0001%2018.3333V13.6784L13.7142%2014.9641C13.3888%2015.2895%2012.8613%2015.2895%2012.5359%2014.9641C12.2107%2014.6387%2012.2106%2014.1111%2012.5359%2013.7858L15.2442%2011.0775L15.3077%2011.0205ZM13.3334%203.33331C14.2539%203.33331%2015.0001%204.0795%2015.0001%204.99998V9.16665H13.3334V8.33331H3.33341V11.6666H10.0001V13.3333H3.33341C2.41294%2013.3333%201.66675%2012.5871%201.66675%2011.6666V4.99998C1.66675%204.0795%202.41294%203.33331%203.33341%203.33331H13.3334ZM3.33341%206.24998H13.3334V4.99998H3.33341V6.24998Z'%20fill='%23C9C9E8'/%3e%3c/svg%3e\"","import {\n  AppstoreOutlined,\n  DownOutlined,\n  LogoutOutlined,\n  UserOutlined,\n} from '@ant-design/icons';\nimport { Avatar, Dropdown, Tooltip } from 'antd';\nimport { Link, useLocation, useNavigate } from 'react-router-dom';\nimport AppTypography from '../typography/Typography';\nimport { logout } from '../../services/authApi';\nimport { ZinInbox } from '../../assets/images';\n\nfunction capitalizeName(value) {\n  if (!value || typeof value !== 'string') return 'User';\n\n  return value\n    .split(' ')\n    .filter(Boolean)\n    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n    .join(' ');\n}\n\nfunction getInitials(value) {\n  const parts = (value || 'User').split(' ').filter(Boolean);\n  const first = parts[0]?.charAt(0) || 'U';\n  const last = parts.length > 1 ? parts.at(-1)?.charAt(0) : '';\n\n  return `${first}${last}`.toUpperCase();\n}\n\nfunction getAvatarColor(name) {\n  const firstLetter = (name || 'User').charAt(0).toUpperCase();\n  const storedMap = JSON.parse(localStorage.getItem('colorMap') || '{}');\n\n  if (storedMap[firstLetter]) return storedMap[firstLetter];\n\n  const colors = ['#0053a5', '#1677ff', '#15803d', '#f97316', '#6366f1', '#8b5cf6'];\n  const color = colors[firstLetter.charCodeAt(0) % colors.length];\n  localStorage.setItem('colorMap', JSON.stringify({ ...storedMap, [firstLetter]: color }));\n\n  return color;\n}\n\nexport default function Header({ leftOffset }) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const companyName = localStorage.getItem('companyName') || 'Zinnext';\n  const username = localStorage.getItem('userName') || localStorage.getItem('preferred_Username') || 'User';\n  const preferredUsername = localStorage.getItem('preferred_Username') || username;\n  const roleId = localStorage.getItem('roleId') || '';\n  const displayName = capitalizeName(username);\n  const initials = getInitials(displayName);\n\n  function handleLogoutClick() {\n    logout();\n    navigate('/login', { replace: true });\n  }\n\n  const profileItems = [\n    {\n      key: 'profile-name',\n      label: (\n        <div className=\"app-layout-profile-summary\">\n          <Avatar\n            size={42}\n            style={{ backgroundColor: getAvatarColor(displayName) }}\n          >\n            {initials}\n          </Avatar>\n          <div className=\"app-layout-profile-copy\">\n            <AppTypography variant=\"body-strong\" truncate className=\"app-layout-profile-name\">\n              {displayName}\n            </AppTypography>\n            {roleId && (\n              <AppTypography variant=\"caption\" color=\"secondary\" className=\"app-layout-profile-role\">\n                {roleId}\n              </AppTypography>\n            )}\n          </div>\n        </div>\n      ),\n      disabled: true,\n    },\n    { type: 'divider' },\n    {\n      key: 'dashboard',\n      label: (\n        <Link to=\"/dashboard\" className=\"app-layout-menu-link\">\n          <AppstoreOutlined />\n          Dashboard\n        </Link>\n      ),\n    },\n    {\n      key: 'my-profile',\n      label: (\n        <Link to=\"/my-profile\" className=\"app-layout-menu-link\">\n          <UserOutlined />\n          My Profile\n        </Link>\n      ),\n    },\n    { type: 'divider' },\n    {\n      key: 'logout',\n      label: (\n        <span className=\"app-layout-menu-link app-layout-menu-danger\">\n          <LogoutOutlined />\n          Logout\n        </span>\n      ),\n      onClick: handleLogoutClick,\n    },\n  ];\n\n  return (\n    <header className=\"app-layout-header\" style={{ left: leftOffset }}>\n      <div className=\"app-layout-company\">\n        <AppTypography variant=\"body-strong\" truncate className=\"app-layout-company-name\">\n          {companyName}\n        </AppTypography>\n      </div>\n\n      <div className=\"app-layout-header-actions\">\n        <Tooltip title=\"Inbox\">\n          <Link\n            to=\"/inbox\"\n            className={location.pathname === '/inbox' ? 'app-layout-icon-btn is-active' : 'app-layout-icon-btn'}\n            aria-label=\"Inbox\"\n          >\n            <img src={ZinInbox} alt=\"\" aria-hidden=\"true\" className=\"app-layout-icon-img\" />\n          </Link>\n        </Tooltip>\n\n        <div className=\"app-layout-header-divider\" />\n\n        <div className=\"app-layout-user\">\n          <Avatar\n            size={30}\n            style={{ backgroundColor: getAvatarColor(displayName) }}\n          >\n            {initials}\n          </Avatar>\n          <AppTypography variant=\"label\" truncate className=\"app-layout-user-name\">\n            {preferredUsername}\n          </AppTypography>\n          <Dropdown\n            menu={{ items: profileItems }}\n            trigger={['click']}\n            placement=\"bottomRight\"\n            overlayClassName=\"app-layout-user-dropdown\"\n          >\n            <button type=\"button\" className=\"app-layout-dropdown-btn\" aria-label=\"Open user menu\">\n              <DownOutlined />\n            </button>\n          </Dropdown>\n        </div>\n      </div>\n    </header>\n  );\n}\n","import { Layout, Menu } from 'antd';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport {\n  AppstoreOutlined,\n  BankOutlined,\n  CalendarOutlined,\n  DashboardOutlined,\n  FileProtectOutlined,\n  FileTextOutlined,\n  FolderOpenOutlined,\n  SettingOutlined,\n  TeamOutlined,\n  UploadOutlined,\n  UsergroupAddOutlined,\n  UserOutlined,\n} from '@ant-design/icons';\nimport {\n  ZinAdmin,\n  ZinArrowClose,\n  ZinAssignments,\n  ZinCampaign,\n  ZinCandidate,\n  ZinClientManagement,\n  ZinDashboard,\n  ZinEmployerManagement,\n  ZinHelp,\n  ZinJobs,\n  ZinLogoIcon,\n  ZinLogoText,\n  ZinNetwork,\n  ZinOnBoarding,\n  ZinReports,\n  ZinScheduler,\n  ZinSettings,\n  ZinSubmission,\n  ZinTimesheet,\n  ZinPayrollIcon,\n  ZinBillingIcon,\n} from '../../assets/images';\n\nconst { Sider } = Layout;\n\nexport const SIDEBAR_WIDTH = 200;\nexport const SIDEBAR_COLLAPSED_WIDTH = 60;\n\nconst iconMap = {\n  Dashboard: ZinDashboard,\n  Jobs: ZinJobs,\n  Candidates: ZinCandidate,\n  Submissions: ZinSubmission,\n  Network: ZinNetwork,\n  ClientManagement: ZinClientManagement,\n  Clients: ZinClientManagement,\n  clients: ZinClientManagement,\n  EmployerManagement: ZinEmployerManagement,\n  Employers: ZinEmployerManagement,\n  employers: ZinEmployerManagement,\n  ReferralManagement: ZinEmployerManagement,\n  Referral: ZinEmployerManagement,\n  Referrals: ZinEmployerManagement,\n  referrals: ZinEmployerManagement,\n  Scheduler: ZinScheduler,\n  Admin: ZinAdmin,\n  Reports: ZinReports,\n  Settings: ZinSettings,\n  Help: ZinHelp,\n  onboarding: ZinOnBoarding,\n  Onboarding: ZinOnBoarding,\n  assignments: ZinAssignments,\n  Assignments: ZinAssignments,\n  assignment: ZinAssignments,\n  Assignment: ZinAssignments,\n  timesheet: ZinTimesheet,\n  Timesheet: ZinTimesheet,\n  timesheets: ZinTimesheet,\n  Timesheets: ZinTimesheet,\n  billing: ZinBillingIcon,\n  Billing: ZinBillingIcon,\n  payroll: ZinPayrollIcon,\n  Payroll: ZinPayrollIcon,\n  campaign: ZinCampaign,\n  Campaign: ZinCampaign,\n  campaigns: ZinCampaign,\n  Campaigns: ZinCampaign,\n  addTestCase: ZinReports,\n  viewTestCase: ZinScheduler,\n  manageModules: ZinSettings,\n  bulkUpload: UploadOutlined,\n  'bulk-upload': UploadOutlined,\n};\n\n// Icon names are stored in Admin > Menus. Keep the resolver tolerant of\n// casing/spaces/hyphens so values such as \"AppstoreOutlined\", \"appstore-outlined\"\n// and legacy asset names all resolve to the same visible icon.\nconst antIconMap = {\n  AppstoreOutlined,\n  BankOutlined,\n  CalendarOutlined,\n  DashboardOutlined,\n  FileProtectOutlined,\n  FileTextOutlined,\n  FolderOpenOutlined,\n  SettingOutlined,\n  TeamOutlined,\n  UploadOutlined,\n  UsergroupAddOutlined,\n  UserOutlined,\n};\n\nfunction normalizeIconName(value) {\n  return String(value ?? '').trim().replace(/[\\s_-]+/g, '').toLowerCase();\n}\n\nconst normalizedIconMap = Object.entries({ ...iconMap, ...antIconMap }).reduce((acc, [name, value]) => {\n  acc[normalizeIconName(name)] = value;\n  return acc;\n}, {});\n\nfunction fallbackIconForMenu(itemKey, label) {\n  const token = normalizeIconName(`${itemKey} ${label}`);\n  if (token.includes('dashboard')) return ZinDashboard;\n  if (token.includes('client')) return ZinClientManagement;\n  if (token.includes('employer')) return ZinEmployerManagement;\n  if (token.includes('referral')) return ZinEmployerManagement;\n  if (token.includes('candidate')) return ZinCandidate;\n  if (token.includes('submission')) return ZinSubmission;\n  if (token.includes('onboarding')) return ZinOnBoarding;\n  if (token.includes('assignment')) return ZinAssignments;\n  if (token.includes('timesheet')) return ZinTimesheet;\n  if (token.includes('billing')) return ZinBillingIcon;\n  if (token.includes('payroll')) return ZinPayrollIcon;\n  if (token.includes('campaign')) return ZinCampaign;\n  if (token.includes('job')) return ZinJobs;\n  if (token.includes('admin') || token.includes('config')) return ZinAdmin;\n  if (token.includes('batch')) return FolderOpenOutlined;\n  if (token.includes('pomsa') || token.includes('msa')) return FileProtectOutlined;\n  if (token.includes('user')) return UserOutlined;\n  return AppstoreOutlined;\n}\n\nfunction resolveSidebarIcon(icon, itemKey, label) {\n  const rawIcon = String(icon ?? '').trim();\n  if (/^(https?:\\/\\/|data:image\\/|\\/)/i.test(rawIcon)) return rawIcon;\n\n  return normalizedIconMap[normalizeIconName(rawIcon)]\n    ?? normalizedIconMap[normalizeIconName(itemKey)]\n    ?? normalizedIconMap[normalizeIconName(label)]\n    ?? fallbackIconForMenu(itemKey, label);\n}\n\nfunction parseStoredMenu(storageKey) {\n  const rawValue = localStorage.getItem(storageKey);\n\n  if (!rawValue || rawValue === 'undefined' || rawValue === 'null' || rawValue.trim() === '') {\n    return [];\n  }\n\n  try {\n    const parsedValue = JSON.parse(rawValue);\n    if (Array.isArray(parsedValue)) return parsedValue;\n    if (Array.isArray(parsedValue?.menu)) return parsedValue.menu;\n    if (Array.isArray(parsedValue?.menus?.menu)) return parsedValue.menus.menu;\n\n    return [];\n  } catch (error) {\n    console.error(`Error parsing ${storageKey}:`, error);\n    return [];\n  }\n}\n\nfunction getSelectedKeys(pathname) {\n  const cleanPath = pathname.replace(/^\\/+/, '');\n  if (!cleanPath) return ['dashboard'];\n\n  const parts = cleanPath.split('/');\n  return [cleanPath, parts[0], parts.at(-1)].filter(Boolean);\n}\n\nfunction SidebarIcon({ icon, itemKey, label }) {\n  const iconSrc = resolveSidebarIcon(icon, itemKey, label);\n  if (typeof iconSrc !== 'string') {\n    const Icon = iconSrc;\n    return <Icon className=\"app-sidebar-menu-icon app-sidebar-menu-icon--antd\" aria-hidden=\"true\" />;\n  }\n\n  return (\n    <img\n      src={iconSrc}\n      alt=\"\"\n      className=\"app-sidebar-menu-icon\"\n      aria-hidden=\"true\"\n    />\n  );\n}\n\nfunction buildMenuItems(menuItems) {\n  return menuItems.map((item) => ({\n    key: item.key,\n    icon: <SidebarIcon icon={item.icon} itemKey={item.key} label={item.label} />,\n    label: item.label,\n    disabled: item.status === 'inactive',\n    children: Array.isArray(item.children) ? buildMenuItems(item.children) : undefined,\n  }));\n}\n\nfunction filterMenuByPermission(menuItems) {\n  let permissions;\n  try {\n    permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n  } catch {\n    return menuItems;\n  }\n  const permissionEntries = Object.entries(permissions).reduce((lookup, [key, value]) => ({\n    ...lookup,\n    [String(key).trim().toLowerCase()]: value,\n  }), {});\n  const permissionKeys = Object.keys(permissionEntries);\n  // The MENU's spelling and the PERMISSION's spelling are not guaranteed to\n  // match: the backend lists the menu item as \"timesheet\" but keys its\n  // permission \"timesheets\". An exact-only lookup found nothing, left `view`\n  // undefined, and the `view !== undefined` guard below then treated an\n  // explicit view:0 as \"unconfigured\" and kept the item visible. Fall back to\n  // a singular/plural tolerant match so a deny is never read as unconfigured.\n  const lookupAccess = (key) => permissionEntries[key]\n    ?? permissionEntries[permissionKeys.find((pk) => pk === `${key}s` || `${pk}s` === key) ?? ''];\n\n  return menuItems.flatMap((item) => {\n    const candidates = [item.key, item.label].map((value) => String(value ?? '').trim().toLowerCase());\n    const access = candidates.map(lookupAccess).find(Boolean);\n    const view = permissionValue(access, 'view');\n\n    // Admin View permission is authoritative for sidebar visibility.  The API\n    // can return either a primitive (0/1/true/false) or the admin-config shape\n    // { value: 0|1 }.  Treat every explicit false/0 as hidden, regardless of\n    // the user's add/edit/approve permissions.\n    if (view !== undefined && view !== null && !permissionEnabled(view)) return [];\n\n    const children = Array.isArray(item.children) ? filterMenuByPermission(item.children) : undefined;\n    return [{ ...item, children }];\n  });\n}\n\nfunction menuKeys(menuItems) {\n  return new Set(menuItems.flatMap((item) => [\n    String(item?.key ?? '').trim().toLowerCase(),\n    ...(Array.isArray(item?.children) ? [...menuKeys(item.children)] : []),\n  ]).filter(Boolean));\n}\n\nfunction permissionScalar(value) {\n  if (value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, 'value')) {\n    return value.value;\n  }\n  return value;\n}\n\nfunction permissionValue(access, permissionKey) {\n  if (!access || typeof access !== 'object') return undefined;\n  if (Object.prototype.hasOwnProperty.call(access, permissionKey)) return access[permissionKey];\n\n  const wanted = String(permissionKey).trim().toLowerCase();\n  const matchedKey = Object.keys(access).find(\n    (key) => String(key).trim().toLowerCase() === wanted,\n  );\n  return matchedKey ? access[matchedKey] : undefined;\n}\n\nfunction permissionEnabled(value) {\n  const scalar = permissionScalar(value);\n  return scalar === true || scalar === 1 || scalar === '1';\n}\n\nfunction menuLabel(key) {\n  return String(key)\n    .split(/[\\s_\\-/]+/)\n    .filter(Boolean)\n    .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)\n    .join(' ');\n}\n\n// The login response can contain a freshly configured module in\n// menuPermission before the saved menu structure includes it. Reconcile the\n// two sources so any explicitly view-enabled module remains reachable without\n// requiring a second backend/menu-structure update.\nfunction withPermissionBackedItems(menuItems) {\n  let permissions;\n  try {\n    permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n  } catch {\n    return menuItems;\n  }\n  if (!permissions || typeof permissions !== 'object' || Array.isArray(permissions)) {\n    return menuItems;\n  }\n\n  const existingKeys = menuKeys(menuItems);\n  const missingItems = Object.entries(permissions).flatMap(([rawKey, access]) => {\n    const key = String(rawKey).trim().toLowerCase();\n    if (!key || key.includes('/') || existingKeys.has(key) || !permissionEnabled(permissionValue(access, 'view'))) {\n      return [];\n    }\n    existingKeys.add(key);\n    return [{ key, icon: key, label: menuLabel(key), status: 'active' }];\n  });\n\n  return [...menuItems, ...missingItems];\n}\n\nfunction withBulkUploadItem(menuItems) {\n  const hasTesterMenu = menuItems.some((item) => item.key === 'addTestCase');\n  const hasBulkUpload = menuItems.some((item) => item.key === 'bulk-upload');\n  if (!hasTesterMenu || hasBulkUpload) return menuItems;\n\n  const nextItems = [...menuItems];\n  const manageIndex = nextItems.findIndex((item) => item.key === 'manageModules');\n  nextItems.splice(manageIndex >= 0 ? manageIndex + 1 : nextItems.length, 0, {\n    key: 'bulk-upload',\n    icon: 'bulk-upload',\n    label: 'Bulk upload',\n    status: 'active',\n  });\n  return nextItems;\n}\n\nfunction hasClientPermission() {\n  try {\n    const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    const client = permissions?.client ?? permissions?.clients;\n    if (!client || typeof client !== 'object') return false;\n    return permissionEnabled(permissionValue(client, 'view'));\n  } catch {\n    return false;\n  }\n}\n\nfunction hasEmployerPermission() {\n  try {\n    const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    const employer = permissions?.employers ?? permissions?.employer;\n    if (!employer || typeof employer !== 'object') return false;\n    return permissionEnabled(permissionValue(employer, 'view'));\n  } catch {\n    return false;\n  }\n}\n\nfunction withClientManagementItem(menuItems) {\n  const hasClients = menuItems.some((item) => item.key === 'clients' || item.key === 'client');\n  if (hasClients || !hasClientPermission()) return menuItems;\n\n  const nextItems = [...menuItems];\n  const jobsIndex = nextItems.findIndex((item) => item.key === 'jobs');\n  nextItems.splice(jobsIndex >= 0 ? jobsIndex : nextItems.length, 0, {\n    key: 'clients',\n    icon: 'ClientManagement',\n    label: 'Client Management',\n    status: 'active',\n  });\n  return nextItems;\n}\n\nfunction withEmployerManagementItem(menuItems) {\n  const hasEmployers = menuItems.some((item) => item.key === 'employers' || item.key === 'employer');\n  const hasClients = menuItems.some((item) => item.key === 'clients' || item.key === 'client');\n  const hasManagementAccess = hasEmployerPermission() || hasClients || hasClientPermission();\n  if (hasEmployers || !hasManagementAccess) return menuItems;\n\n  const nextItems = [...menuItems];\n  const jobsIndex = nextItems.findIndex((item) => item.key === 'jobs');\n  nextItems.splice(jobsIndex >= 0 ? jobsIndex : nextItems.length, 0, {\n    key: 'employers',\n    icon: 'EmployerManagement',\n    label: 'Employer Management',\n    status: 'active',\n  });\n  return nextItems;\n}\n\nfunction hasReferralPermission() {\n  try {\n    const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    const referral = permissions?.referrals ?? permissions?.referral;\n    if (!referral || typeof referral !== 'object') return false;\n    return permissionEnabled(permissionValue(referral, 'view'));\n  } catch {\n    return false;\n  }\n}\n\n// Referral Management mirrors Employer Management: a top-level item linking to\n// /referrals, injected right after Employers so the two sit together. Shown when\n// the role can reach referrals or the same management area Employer uses.\nfunction withReferralManagementItem(menuItems) {\n  const hasReferrals = menuItems.some((item) => item.key === 'referrals' || item.key === 'referral');\n  const hasEmployers = menuItems.some((item) => item.key === 'employers' || item.key === 'employer');\n  const hasManagementAccess = hasReferralPermission() || hasEmployerPermission() || hasEmployers || hasClientPermission();\n  if (hasReferrals || !hasManagementAccess) return menuItems;\n\n  const nextItems = [...menuItems];\n  const anchorIndex = nextItems.findIndex((item) => item.key === 'employers' || item.key === 'employer');\n  const jobsIndex = nextItems.findIndex((item) => item.key === 'jobs');\n  const insertAt = anchorIndex >= 0 ? anchorIndex + 1 : (jobsIndex >= 0 ? jobsIndex : nextItems.length);\n  nextItems.splice(insertAt, 0, {\n    key: 'referrals',\n    icon: 'ReferralManagement',\n    label: 'Referral Management',\n    status: 'active',\n  });\n  return nextItems;\n}\n\nfunction hasFinancePermission(module) {\n  try {\n    const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n    const entry = permissions?.[module];\n    return Boolean(entry) && permissionEnabled(permissionValue(entry, 'view'));\n  } catch {\n    return false;\n  }\n}\n\nfunction withFinanceItems(menuItems) {\n  const nextItems = [...menuItems];\n  const assignmentsIndex = nextItems.findIndex((item) => item.key === 'assignments');\n  let insertAt = assignmentsIndex >= 0 ? assignmentsIndex + 1 : nextItems.length;\n  for (const [key, label] of [['billing', 'Billing'], ['payroll', 'Payroll']]) {\n    if (!nextItems.some((item) => item.key === key) && hasFinancePermission(key)) {\n      nextItems.splice(insertAt, 0, { key, icon: key, label, status: 'active' });\n      insertAt += 1;\n    }\n  }\n  return nextItems;\n}\n\n// The vendor concept has been replaced by Employer — drop any lingering\n// \"Vendors\" entry (e.g. a stored menu from before this change) so it never shows\n// while the DB menu catches up on the next login.\nfunction withoutVendorItems(menuItems) {\n  return menuItems\n    .filter((item) => {\n      const key = String(item.key ?? '').toLowerCase();\n      const label = String(item.label ?? '').toLowerCase();\n      return !key.includes('vendor') && label !== 'vendors';\n    })\n    .map((item) => (Array.isArray(item.children)\n      ? { ...item, children: withoutVendorItems(item.children) }\n      : item));\n}\n\nfunction getRoleMenuSnapshot() {\n  return [\n    localStorage.getItem('menu') ?? '',\n    localStorage.getItem('menuPermission') ?? '',\n    localStorage.getItem('roleId') ?? '',\n    localStorage.getItem('userId') ?? '',\n  ].join('::');\n}\n\nexport default function Sidebar({ collapsed, onToggle }) {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const [openKeys, setOpenKeys] = useState([]);\n  const [roleMenuSnapshot, setRoleMenuSnapshot] = useState(() => getRoleMenuSnapshot());\n  const selectedKeys = useMemo(() => getSelectedKeys(location.pathname), [location.pathname]);\n\n  // Sidebar menu data is written during login. React to login/logout and\n  // cross-tab localStorage changes so the visible navigation always belongs to\n  // the currently authenticated role instead of the first user that mounted\n  // this Sidebar instance.\n  useEffect(() => {\n    const refreshRoleMenu = () => setRoleMenuSnapshot(getRoleMenuSnapshot());\n    window.addEventListener('auth:login', refreshRoleMenu);\n    window.addEventListener('auth:logout', refreshRoleMenu);\n    window.addEventListener('menu:updated', refreshRoleMenu);\n    window.addEventListener('storage', refreshRoleMenu);\n    return () => {\n      window.removeEventListener('auth:login', refreshRoleMenu);\n      window.removeEventListener('auth:logout', refreshRoleMenu);\n      window.removeEventListener('menu:updated', refreshRoleMenu);\n      window.removeEventListener('storage', refreshRoleMenu);\n    };\n  }, []);\n\n  useEffect(() => {\n    if (selectedKeys.length > 0) {\n      localStorage.setItem('activeKey', selectedKeys[0]);\n    }\n  }, [selectedKeys]);\n\n  const items = useMemo(() => {\n    const storedMenu = withoutVendorItems(parseStoredMenu('menu'));\n    const knownMenu = withFinanceItems(withBulkUploadItem(\n      withReferralManagementItem(withEmployerManagementItem(withClientManagementItem(storedMenu))),\n    ));\n    const augmentedMenu = withPermissionBackedItems(knownMenu);\n    return buildMenuItems(filterMenuByPermission(augmentedMenu));\n  }, [roleMenuSnapshot]);\n\n  function handleToggle() {\n    if (!collapsed) {\n      setOpenKeys([]);\n    }\n\n    onToggle();\n  }\n\n  function handleMenuClick({ key }) {\n    navigate(`/${key}`);\n  }\n\n  return (\n    <Sider\n      trigger={null}\n      collapsible\n      collapsed={collapsed}\n      width={SIDEBAR_WIDTH}\n      collapsedWidth={SIDEBAR_COLLAPSED_WIDTH}\n      className=\"app-sidebar\"\n    >\n      <div className=\"app-sidebar-panel\">\n        <div className=\"app-sidebar-brand\">\n          <div className=\"app-sidebar-logo\">\n            <img src={ZinLogoIcon} alt=\"\" className=\"app-sidebar-logo-icon\" />\n            <img src={ZinLogoText} alt=\"Zinnext\" className=\"app-sidebar-logo-text\" />\n          </div>\n        </div>\n\n        <button\n          type=\"button\"\n          className=\"app-sidebar-toggle\"\n          onClick={handleToggle}\n          aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n        >\n          <img src={ZinArrowClose} alt=\"\" aria-hidden=\"true\" />\n        </button>\n\n        <div className=\"app-sidebar-body\">\n          <Menu\n            mode=\"inline\"\n            theme=\"dark\"\n            selectedKeys={selectedKeys}\n            openKeys={collapsed ? [] : openKeys}\n            items={items}\n            onClick={handleMenuClick}\n            onOpenChange={setOpenKeys}\n            className=\"app-sidebar-menu\"\n          />\n        </div>\n      </div>\n    </Sider>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// AuthGuard — the ONE central place that protects the whole app.\n//\n// Problem it solves: when a page (Admin, Jobs, Candidates, …) is opened\n// WITHOUT a valid login session, the data APIs throw a 401 (\"Authentication\n// required\") and the page silently renders empty — \"no module\" — with no\n// explanation. That happens both in this app and in any host project that\n// consumes @realtek/core-theme and drops a page like <AdminPage /> onto a route.\n//\n// Instead of editing every page, wrap once and every child is guarded:\n//\n//   import { AuthGuard } from '@realtek/core-theme';\n//   import '@realtek/core-theme/style.css';\n//\n//   <BrowserRouter>\n//     <AuthGuard>\n//       <Routes> … your routes / pages … </Routes>\n//     </AuthGuard>\n//   </BrowserRouter>\n//\n// When there is no session it shows a clear \"you haven't logged in\" screen\n// with a Login button; when a session exists it renders the children untouched.\n// It also re-checks live on login / logout / cross-tab storage changes.\n// ─────────────────────────────────────────────────────────────────────────\nimport { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Result } from 'antd';\nimport { LockOutlined } from '@ant-design/icons';\nimport { getStoredToken } from '../../services/authApi';\nimport '../../styles/AuthGuard.css';\n\nconst DEFAULT_TITLE = \"You're not logged in\";\nconst DEFAULT_MESSAGE =\n  \"You haven't logged into this session. Please login to access the data.\";\n\nfunction hasSession() {\n  try {\n    return Boolean(getStoredToken());\n  } catch {\n    return false;\n  }\n}\n\nexport default function AuthGuard({\n  children,\n  title = DEFAULT_TITLE,\n  message = DEFAULT_MESSAGE,\n  loginPath = '/login',\n  loginLabel = 'Go to Login',\n  onLogin,\n  fallback,\n}) {\n  const [authed, setAuthed] = useState(hasSession);\n\n  useEffect(() => {\n    const recheck = () => setAuthed(hasSession());\n    // Our own login/logout events + cross-tab localStorage changes.\n    window.addEventListener('auth:login', recheck);\n    window.addEventListener('auth:logout', recheck);\n    window.addEventListener('storage', recheck);\n    // Re-check when the user returns to the tab (token may have expired/cleared).\n    window.addEventListener('focus', recheck);\n    return () => {\n      window.removeEventListener('auth:login', recheck);\n      window.removeEventListener('auth:logout', recheck);\n      window.removeEventListener('storage', recheck);\n      window.removeEventListener('focus', recheck);\n    };\n  }, []);\n\n  if (authed) return children;\n\n  // Caller-supplied custom screen wins over the default one.\n  if (fallback !== undefined) return fallback;\n\n  const goToLogin = () => {\n    if (typeof onLogin === 'function') {\n      onLogin();\n      return;\n    }\n    if (typeof window !== 'undefined') {\n      window.location.assign(loginPath);\n    }\n  };\n\n  return (\n    <div className=\"ct-auth-guard\">\n      <div className=\"ct-auth-guard__card\">\n        <Result\n          status=\"403\"\n          icon={<LockOutlined className=\"ct-auth-guard__icon\" />}\n          title={title}\n          subTitle={message}\n          extra={\n            <Button type=\"primary\" size=\"large\" onClick={goToLogin}>\n              {loginLabel}\n            </Button>\n          }\n        />\n      </div>\n    </div>\n  );\n}\n\nAuthGuard.propTypes = {\n  children: PropTypes.node,\n  title: PropTypes.node,\n  message: PropTypes.node,\n  loginPath: PropTypes.string,\n  loginLabel: PropTypes.node,\n  onLogin: PropTypes.func,\n  fallback: PropTypes.node,\n};\n","import { useLocation, useNavigate } from 'react-router-dom';\nimport { Button, Result } from 'antd';\nimport { LockOutlined } from '@ant-design/icons';\nimport '../../styles/AuthGuard.css';\nimport { useMenuPermission } from '../../hooks/useMenuPermission';\n\n// Route names do not always match the module/menuPermission key.\n// Keep only real route aliases here; ordinary plural/singular differences are\n// already handled by useMenuPermission.\nconst ROUTE_MODULE_ALIASES = {\n  'candidate-onboarding': 'onboarding',\n  'candidate-assignment': 'assignments',\n  candidate: 'candidates',\n  job: 'jobs',\n  submission: 'submissions',\n  client: 'clients',\n  employer: 'employers',\n  referral: 'referrals',\n  timesheet: 'timesheets',\n};\n\n// These are shell/utility pages rather than permission-backed business\n// modules. They must not be denied just because menuPermission has no entry.\nconst UNGUARDED_ROUTES = new Set([\n  '',\n  'dashboard',\n  'my-profile',\n  'profile',\n  'viewall-sticky',\n  'select-project',\n  'addtestcase',\n  'managemodules',\n  'viewtestcase',\n  'test-cases',\n  'zinnext-home',\n  'lms-home',\n  'test',\n]);\n\nfunction firstPathSegment(pathname) {\n  return String(pathname ?? '')\n    .split('?')[0]\n    .split('#')[0]\n    .replace(/^\\/+/, '')\n    .split('/')[0]\n    .trim()\n    .toLowerCase();\n}\n\nexport function getPermissionModuleFromPath(pathname) {\n  const segment = firstPathSegment(pathname);\n  if (!segment || UNGUARDED_ROUTES.has(segment)) return '';\n  return ROUTE_MODULE_ALIASES[segment] ?? segment;\n}\n\n/**\n * Prevents direct URL access when the logged-in role has View = 0.\n *\n * Sidebar filtering is only presentation. This guard enforces the same\n * permission at page-render time, so typing/pasting a hidden module URL does\n * not bypass the role configuration.\n */\nexport default function RoutePermissionGuard({ children }) {\n  const location = useLocation();\n  const navigate = useNavigate();\n  const moduleName = getPermissionModuleFromPath(location.pathname);\n  const { canView } = useMenuPermission(moduleName);\n\n  if (moduleName && !canView) {\n    const moduleLabel = moduleName\n      .replace(/[-_]+/g, ' ')\n      .replace(/\\b\\w/g, (letter) => letter.toUpperCase());\n\n    return (\n      <div className=\"ct-auth-guard\">\n        <div className=\"ct-auth-guard__card\">\n          <Result\n            status=\"403\"\n            icon={<LockOutlined className=\"ct-auth-guard__icon\" />}\n            title=\"Access Denied\"\n            subTitle={`You do not have View access to the ${moduleLabel} module. Please contact your administrator if you need access.`}\n            extra={(\n              <Button\n                type=\"primary\"\n                size=\"large\"\n                onClick={() => navigate('/dashboard')}\n              >\n                Go to Dashboard\n              </Button>\n            )}\n          />\n        </div>\n      </div>\n    );\n  }\n\n  return children;\n}\n","import { useState } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport Header from './Header';\nimport Sidebar, { SIDEBAR_COLLAPSED_WIDTH } from './Sidebar';\nimport AuthGuard from '../auth/AuthGuard';\nimport RoutePermissionGuard from '../auth/RoutePermissionGuard';\nimport { PermissionProvider } from '../../contexts/PermissionContext';\n\nconst HEADER_HEIGHT = 60;\n\nexport default function AppShell({ children }) {\n  const [collapsed, setCollapsed] = useState(true);\n  const layoutOffset = SIDEBAR_COLLAPSED_WIDTH;\n\n  return (\n    <PermissionProvider>\n      <div className=\"app-layout-shell\">\n        <Sidebar collapsed={collapsed} onToggle={() => setCollapsed((value) => !value)} />\n        <Header leftOffset={layoutOffset} />\n\n        <main\n          className=\"app-layout-main\"\n          style={{\n            marginLeft: layoutOffset,\n            paddingTop: HEADER_HEIGHT,\n          }}\n        >\n          <div className=\"app-layout-content\">\n            {/* Single, central auth + live-permission gate. PermissionProvider\n                keeps /me/permissions authoritative and mirrors it to the legacy\n                localStorage snapshot used by older screens. */}\n            <AuthGuard>\n              <RoutePermissionGuard>\n                {children ?? <Outlet />}\n              </RoutePermissionGuard>\n            </AuthGuard>\n          </div>\n        </main>\n      </div>\n    </PermissionProvider>\n  );\n}\n","import {\n  Alert,\n  Button,\n  Divider,\n  Form,\n  Input,\n} from 'antd';\nimport { ExclamationCircleFilled } from '@ant-design/icons';\nimport { useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport AppTypography from '../typography/Typography';\nimport { colors } from '../../theme/colors/colors';\nimport { isTester, login } from '../../services/authApi';\nimport Login1 from '../../assets/images/login-1.svg';\nimport Login2 from '../../assets/images/login-2.svg';\n\nexport default function Login({ onLogin, defaultRedirectPath = '/' }) {\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState('');\n  const navigate = useNavigate();\n  const location = useLocation();\n  const redirectPath = location.state?.from?.pathname || defaultRedirectPath;\n  const sessionExpired = new URLSearchParams(location.search).get('session_expired') === '1';\n\n  async function handleFinish(values) {\n    setError('');\n    setLoading(true);\n\n    try {\n      const result = await login({\n        email: values.email,\n        user_pwd: values.user_pwd,\n      });\n\n      onLogin?.(result);\n\n      // Testers never enter the main app / dashboard — they pick a project,12\n      // then go straight to the test-case authoring flow. Their role name is\n      // available from the login response (stored as localStorage['roleId']).\n      if (isTester()) {\n        navigate('/select-project', { replace: true });\n        return;\n      }\n\n      // Other roles keep the normal flow (server redirectUrl is handled\n      // elsewhere; fall back to the originally requested path).\n      navigate(redirectPath, { replace: true });\n    } catch (err) {\n      setError(err.message || 'Unable to login. Please check your credentials.');\n    } finally {\n      setLoading(false);\n    }\n  }\n\n  return (\n    <div className=\"auth-login-page\">\n      <section className=\"auth-login-bg\" style={{ background: colors.brand }}>\n        <div className=\"auth-login-static-section\">\n          <div>\n            <img\n              src={Login1}\n              alt=\"\"\n              className=\"auth-login-img-one\"\n            />\n          </div>\n          <div className=\"auth-login-hero-wrap\">\n            <img\n              src={Login2}\n              alt=\"\"\n              className=\"auth-login-img-two\"\n            />\n          </div>\n          <AppTypography\n            as=\"p\"\n            variant=\"body\"\n            color=\"inverse\"\n            size=\"2xl\"\n            weight=\"regular\"\n            align=\"right\"\n            className=\"auth-login-tagline\"\n          >\n            Best in class processes in a box.\n          </AppTypography>\n        </div>\n      </section>\n\n      <section className=\"auth-login-form-layout\">\n        <div className=\"auth-login-form-container\">\n          <div className=\"auth-login-form-shell\">\n            {sessionExpired && (\n              <div className=\"auth-login-session-expired-container\">\n                <div className=\"auth-login-slide-in\">\n                  <Alert\n                    type=\"warning\"\n                    showIcon\n                    icon={(\n                      <ExclamationCircleFilled\n                        style={{ fontSize: 30, color: '#FFC107' }}\n                      />\n                    )}\n                    message={(\n                      <div className=\"auth-login-alert-message-container\">\n                        <Divider className=\"auth-login-alert-divider\" type=\"vertical\" />\n                        <div className=\"auth-login-alert-text\">\n                          Session expired. Please log in again.\n                        </div>\n                      </div>\n                    )}\n                    className=\"auth-login-session-expired-alert\"\n                  />\n                </div>\n              </div>\n            )}\n\n            <div className=\"auth-login-brand\">\n              <img src=\"/favicon.ico\" alt=\"\" className=\"auth-login-logo\" />\n              <AppTypography\n                variant=\"h3\"\n                color=\"primary\"\n                weight=\"bold\"\n                className=\"auth-login-brand-text\"\n              >\n                Zinnext\n              </AppTypography>\n            </div>\n\n            <div className=\"auth-login-body\">\n              <div className=\"auth-login-sign-body\">\n                <AppTypography\n                  variant=\"h2\"\n                  color=\"primary\"\n                  weight=\"bold\"\n                  align=\"center\"\n                  className=\"auth-login-title\"\n                >\n                  Sign in\n                </AppTypography>\n\n                <div className=\"auth-login-form-con\">\n                  <Form\n                    className=\"v1-form auth-login-form\"\n                    layout=\"vertical\"\n                    requiredMark={false}\n                    onFinish={handleFinish}\n                    autoComplete=\"off\"\n                  >\n                    <Form.Item\n                      label=\"Email\"\n                      name=\"email\"\n                      rules={[\n                        {\n                          type: 'email',\n                          required: true,\n                          message: 'Enter valid email.',\n                        },\n                      ]}\n                    >\n                      <Input\n                        size=\"large\"\n                        placeholder=\"Your work email\"\n                        autoComplete=\"email\"\n                      />\n                    </Form.Item>\n\n                    <Form.Item\n                      label=\"Password\"\n                      name=\"user_pwd\"\n                      rules={[\n                        {\n                          required: true,\n                          message: 'Mandatory field.',\n                        },\n                      ]}\n                    >\n                      <Input.Password\n                        size=\"large\"\n                        placeholder=\"Enter password\"\n                        autoComplete=\"current-password\"\n                      />\n                    </Form.Item>\n\n                    <Form.Item className=\"auth-login-forgot-row\">\n                      <Button\n                        type=\"link\"\n                        className=\"auth-login-forgot\"\n                        htmlType=\"button\"\n                      >\n                        Forgot Password?\n                      </Button>\n                    </Form.Item>\n\n                    {error && (\n                      <Form.Item>\n                        <AppTypography color=\"danger\" variant=\"body\">\n                          {error}\n                        </AppTypography>\n                      </Form.Item>\n                    )}\n\n                    <Button\n                      className=\"auth-login-submit\"\n                      block\n                      size=\"large\"\n                      type=\"primary\"\n                      htmlType=\"submit\"\n                      loading={loading}\n                      id=\"znxt-signin\"\n                    >\n                      Sign in\n                    </Button>\n\n                    <Form.Item className=\"auth-login-divider-row\">\n                      <Divider>Or</Divider>\n                    </Form.Item>\n\n                    <AppTypography\n                      as=\"p\"\n                      variant=\"body\"\n                      color=\"secondary\"\n                      align=\"center\"\n                      className=\"auth-login-signup-text\"\n                    >\n                      Not registered yet?{' '}\n                      <Button\n                        type=\"link\"\n                        htmlType=\"button\"\n                        className=\"auth-login-signup\"\n                        id=\"znxt-signup\"\n                      >\n                        Sign up\n                      </Button>\n                    </AppTypography>\n                  </Form>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </section>\n    </div>\n  );\n}\n","import { fetchJsonWithAuth, apiGetWithAuth } from './authApi';\nimport { AUTH_URL } from './apiConfig';\n\nasync function authapiGet(path) {\n  return apiGetWithAuth(AUTH_URL, path);\n}\n\nasync function authapiPost(path, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, path, {\n    method: 'POST',\n    body: JSON.stringify(payload),\n  });\n  return json.data ?? json;\n}\n\nasync function authapiPut(path, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, path, {\n    method: 'PUT',\n    body: JSON.stringify(payload),\n  });\n  return json.data ?? json;\n}\n\nasync function authapiDelete(path) {\n  const json = await fetchJsonWithAuth(AUTH_URL, path, { method: 'DELETE' });\n  return json.data ?? json;\n}\n\n// ── Testing Options ───────────────────────────────────────────────────────────\n\nexport async function getTestingOptions(type) {\n  return authapiGet(`/testing-modules?type=${encodeURIComponent(type)}`);\n}\n\nexport async function addTestingOption({ name, type }) {\n  return authapiPost('/testing-modules', { name, type });\n}\n\nexport async function getActionFieldRules() {\n  return authapiGet('/test-action-field-rules');\n}\n\n// ── Test Flows ────────────────────────────────────────────────────────────────\n\nexport async function addTestFlow(payload) {\n  return authapiPost('/test-flows', payload);\n}\n\nexport async function getTestFlows({\n  limit = 10, offset = 0, search = '', module = '',\n  keyword = '', tags = '', active,\n} = {}) {\n  const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n  if (search) params.append('search', search);\n  if (module) params.append('module', module);\n  if (keyword) params.append('keyword', keyword);\n  if (tags) params.append('tags', tags);\n  if (active !== undefined && active !== null && active !== '') params.append('active', String(active));\n  return authapiGet(`/test-flows?${params.toString()}`);\n}\n\n// ── Test Steps ────────────────────────────────────────────────────────────────\n\nexport async function validateTestSteps(payload) {\n  return authapiPost('/test-steps/validate', payload);\n}\n\nexport async function bulkInsertTestSteps(payload) {\n  return authapiPost('/test-steps/bulk-insert', payload);\n}\n\n// ── LMS Flows ─────────────────────────────────────────────────────────────────\n\nexport async function addLmsFlow(payload) {\n  return authapiPost('/lms-flows', payload);\n}\n\nexport async function getLmsFlows({\n  limit = 10, offset = 0, search = '', module = '',\n  keyword = '', tags = '', active,\n} = {}) {\n  const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n  if (search) params.append('search', search);\n  if (module) params.append('module', module);\n  if (keyword) params.append('keyword', keyword);\n  if (tags) params.append('tags', tags);\n  if (active !== undefined && active !== null && active !== '') params.append('active', String(active));\n  return authapiGet(`/lms-flows?${params.toString()}`);\n}\n\n// ── CT Projects ───────────────────────────────────────────────────────────────\n\nexport async function getCTProjects({ activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/projects${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTProject(projectname) {\n  return authapiPost('/ct/projects', { projectname });\n}\n\nexport async function setCTProjectStatus(id, active) {\n  return authapiPut('/ct/projects/status', { id, active });\n}\n\n// ── CT Modules ────────────────────────────────────────────────────────────────\n\nexport async function getCTModules({ project = '', activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (project) params.append('project', project);\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/modules${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTModule({ project, modulename }) {\n  return authapiPost('/ct/modules', { project, modulename });\n}\n\nexport async function setCTModuleStatus(id, active) {\n  return authapiPut('/ct/modules/status', { id, active });\n}\n\n// ── CT Submodules ─────────────────────────────────────────────────────────────\n\nexport async function getCTSubmodules({ project = '', module = '', activeOnly = false } = {}) {\n  const params = new URLSearchParams();\n  if (project) params.append('project', project);\n  if (module) params.append('module', module);\n  if (activeOnly) params.append('active', '1');\n  const query = params.toString();\n  return authapiGet(`/ct/submodules${query ? `?${query}` : ''}`);\n}\n\nexport async function addCTSubmodule({ project, modulename, submodulename }) {\n  return authapiPost('/ct/submodules', { project, modulename, submodulename });\n}\n\nexport async function setCTSubmoduleStatus(id, active) {\n  return authapiPut('/ct/submodules/status', { id, active });\n}\n\n// ── CT Flows ──────────────────────────────────────────────────────────────────\n\nexport async function getCTFlows({\n  project = '', module = '', submodule = '',\n  product_parent_ID = '', module_parent_ID = '', submodule_parent_ID = '',\n  actions = '', search = '', active, limit = 1000, offset = 0,\n} = {}) {\n  const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n  const productParentID = product_parent_ID || project;\n  const moduleParentID = module_parent_ID || module;\n  const submoduleParentID = submodule_parent_ID || submodule;\n  if (productParentID) params.append('product_parent_ID', productParentID);\n  if (moduleParentID) params.append('module_parent_ID', moduleParentID);\n  if (submoduleParentID) params.append('submodule_parent_ID', submoduleParentID);\n  if (actions) params.append('actions', actions);\n  if (search) params.append('search', search);\n  if (active !== undefined && active !== null && active !== '') params.append('active', String(active));\n  return authapiGet(`/ct/flows?${params.toString()}`);\n}\n\nexport async function addCTFlow(payload) {\n  return authapiPost('/ct/flows', payload);\n}\n\nexport async function getCTFlow(id) {\n  return authapiGet(`/ct/flows/${encodeURIComponent(id)}`);\n}\n\nexport async function getCTNextStep({ project, module, submodule, product_parent_ID, module_parent_ID, submodule_parent_ID }) {\n  const params = new URLSearchParams({\n    product_parent_ID: String(product_parent_ID || project),\n    module_parent_ID: String(module_parent_ID || module),\n    submodule_parent_ID: String(submodule_parent_ID || submodule),\n  });\n  return authapiGet(`/ct/flows/next-step?${params.toString()}`);\n}\n\nexport async function updateCTFlow(id, payload) {\n  return authapiPut(`/ct/flows/${encodeURIComponent(id)}`, payload);\n}\n\nexport async function deleteCTFlow(id) {\n  return authapiDelete(`/ct/flows/${encodeURIComponent(id)}`);\n}\n","import { Button, Form, Select } from 'antd';\nimport { ProjectOutlined } from '@ant-design/icons';\nimport { useEffect, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport AppTypography from '../typography/Typography';\nimport { colors } from '../../theme/colors/colors';\nimport { getCTProjects } from '../../services/testingApi';\nimport { getSelectedProject, setSelectedProject } from '../../services/authApi';\nimport Login1 from '../../assets/images/login-1.svg';\nimport Login2 from '../../assets/images/login-2.svg';\n\nconst DEFAULT_PROJECT = 'zinnext';\n\nexport default function ProjectSelect() {\n  const [form] = Form.useForm();\n  const navigate = useNavigate();\n  const [projects, setProjects] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState('');\n\n  useEffect(() => {\n    let active = true;\n\n    Promise.resolve()\n      .then(() => getCTProjects({ activeOnly: true }))\n      .then((res) => {\n        if (!active) return;\n        const items = res?.items ?? [];\n        setProjects(items);\n\n        // default to the previously chosen project, else \"zinnext\", else first\n        const previous = getSelectedProject();\n        const preferred =\n          items.find((p) => p.id === previous?.id) ||\n          items.find((p) => p.projectname?.toLowerCase() === DEFAULT_PROJECT) ||\n          items[0];\n        if (preferred) form.setFieldsValue({ project: preferred.id });\n      })\n      .catch((err) => {\n        console.error('Unable to load projects:', err);\n        if (active) setError('Unable to load projects. Please try again.');\n      });\n\n    return () => {\n      active = false;\n    };\n  }, [form]);\n\n  function handleFinish(values) {\n    const selected = projects.find((p) => p.id === values.project);\n    if (!selected) {\n      setError('Please select a project.');\n      return;\n    }\n    setLoading(true);\n    setSelectedProject({ id: selected.id, name: selected.projectname });\n    navigate('/addTestCase', { replace: true });\n  }\n\n  return (\n    <div className=\"auth-login-page\">\n      <section className=\"auth-login-bg\" style={{ background: colors.brand }}>\n        <div className=\"auth-login-static-section\">\n          <div>\n            <img src={Login1} alt=\"\" className=\"auth-login-img-one\" />\n          </div>\n          <div className=\"auth-login-hero-wrap\">\n            <img src={Login2} alt=\"\" className=\"auth-login-img-two\" />\n          </div>\n          <AppTypography\n            as=\"p\"\n            variant=\"body\"\n            color=\"inverse\"\n            size=\"2xl\"\n            weight=\"regular\"\n            align=\"right\"\n            className=\"auth-login-tagline\"\n          >\n            Best in class processes in a box.\n          </AppTypography>\n        </div>\n      </section>\n\n      <section className=\"auth-login-form-layout\">\n        <div className=\"auth-login-form-container\">\n          <div className=\"auth-login-form-shell\">\n            <div className=\"auth-login-brand\">\n              <img src=\"/favicon.ico\" alt=\"\" className=\"auth-login-logo\" />\n              <AppTypography\n                variant=\"h3\"\n                color=\"primary\"\n                weight=\"bold\"\n                className=\"auth-login-brand-text\"\n              >\n                Zinnext\n              </AppTypography>\n            </div>\n\n            <div className=\"auth-login-body\">\n              <div className=\"auth-login-sign-body\">\n                <AppTypography\n                  variant=\"h2\"\n                  color=\"primary\"\n                  weight=\"bold\"\n                  align=\"center\"\n                  className=\"auth-login-title\"\n                >\n                  Select Project\n                </AppTypography>\n\n                <div className=\"auth-login-form-con\">\n                  <Form\n                    form={form}\n                    className=\"v1-form auth-login-form\"\n                    layout=\"vertical\"\n                    requiredMark={false}\n                    onFinish={handleFinish}\n                    autoComplete=\"off\"\n                  >\n                    <Form.Item\n                      label=\"Project\"\n                      name=\"project\"\n                      rules={[{ required: true, message: 'Select a project.' }]}\n                    >\n                      <Select\n                        size=\"large\"\n                        showSearch\n                        optionFilterProp=\"label\"\n                        placeholder=\"Select project\"\n                        prefix={<ProjectOutlined />}\n                        options={projects.map((p) => ({\n                          value: p.id,\n                          label: p.projectname,\n                        }))}\n                      />\n                    </Form.Item>\n\n                    {error && (\n                      <Form.Item>\n                        <AppTypography color=\"danger\" variant=\"body\">\n                          {error}\n                        </AppTypography>\n                      </Form.Item>\n                    )}\n\n                    <Button\n                      className=\"auth-login-submit\"\n                      block\n                      size=\"large\"\n                      type=\"primary\"\n                      htmlType=\"submit\"\n                      loading={loading}\n                      id=\"znxt-select-project\"\n                    >\n                      Continue\n                    </Button>\n                  </Form>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </section>\n    </div>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// withAuthGuard — wraps a page component so it guards ITSELF.\n//\n// This is what makes the not-logged-in handling work with ZERO setup in a host\n// project. The package's public page exports (AdminPage, JobsListPage, …) are\n// passed through this HOC in src/index.js, so a consumer can simply do:\n//\n//     import { AdminPage } from '@realtek/core-theme';\n//     <Route path=\"/admin\" element={<AdminPage />} />\n//\n// …and opening /admin without a session shows the \"you haven't logged in\"\n// screen automatically — the consumer never has to wrap anything.\n//\n// Pass guard overrides per page if needed: withAuthGuard(Page, { loginPath })\n// ─────────────────────────────────────────────────────────────────────────\nimport AuthGuard from './AuthGuard';\n\nexport default function withAuthGuard(PageComponent, guardProps) {\n  function Guarded(props) {\n    return (\n      <AuthGuard {...guardProps}>\n        <PageComponent {...props} />\n      </AuthGuard>\n    );\n  }\n  Guarded.displayName = `withAuthGuard(${\n    PageComponent.displayName || PageComponent.name || 'Component'\n  })`;\n  return Guarded;\n}\n","import { ADMIN_API_URL, ADMIN_APP_ID, withAdminAppId } from './apiConfig';\nimport { getStoredToken } from './authApi';\n\nconst AUTH_PREFIX = `${ADMIN_API_URL}`;\n\nasync function request(path, options = {}) {\n  const token = getStoredToken();\n  const res = await fetch(`${AUTH_PREFIX}${path}`, {\n    ...options,\n    headers: {\n      'Content-Type': 'application/json',\n      ...withAdminAppId({ 'X-App-Id': String(ADMIN_APP_ID) }),\n      ...(token ? { Authorization: `Bearer ${token}` } : {}),\n      ...(options.headers ?? {}),\n    },\n  });\n\n  const json = await res.json().catch(() => ({}));\n  if (!res.ok) {\n    throw new Error(json?.error ?? json?.message ?? `Request failed: ${res.status}`);\n  }\n  return json?.data ?? json;\n}\n\nfunction toArray(value, keys = []) {\n  if (Array.isArray(value)) return value;\n  for (const key of [...keys, 'data', 'result', 'rows', 'items']) {\n    if (Array.isArray(value?.[key])) return value[key];\n  }\n  for (const key of keys) {\n    if (Array.isArray(value?.data?.[key])) return value.data[key];\n    if (Array.isArray(value?.result?.[key])) return value.result[key];\n  }\n  return [];\n}\n\nfunction normalizeUser(user) {\n  const userId = user.user_id ?? user.userId ?? user.UserId ?? user.legacyUserId ?? user.legacy_user_id ?? user.id ?? user._id;\n  const roleId = user.user_type_id ?? user.roleId ?? user.role_id ?? user.RoleId;\n  const firstName = user.first_name ?? user.firstName ?? '';\n  const lastName = user.last_name ?? user.lastName ?? '';\n  const reportingId = user.reporting_id ?? user.reportingId ?? user.reportingManagerId ?? user.managerId ?? 0;\n  return {\n    ...user,\n    user_id: userId,\n    userId,\n    legacyUserId: user.legacyUserId ?? user.legacy_user_id ?? userId,\n    username: user.username ?? user.userName ?? user.user_name ?? `${firstName}${lastName}`.trim(),\n    userName: user.userName ?? user.username ?? user.user_name ?? `${firstName}${lastName}`.trim(),\n    first_name: firstName,\n    firstName,\n    last_name: lastName,\n    lastName,\n    email: user.email,\n    mobile: user.mobile ?? user.phoneNumber ?? user.phone_number ?? user.mobile_number,\n    mobileNumber: user.mobileNumber ?? user.mobile_number ?? user.mobile ?? user.phoneNumber ?? user.phone_number,\n    user_type_id: roleId,\n    role_id: roleId,\n    roleId,\n    reporting_id: reportingId,\n    reportingId,\n    profile_image: user.profile_image ?? user.photoLocation ?? user.photo_location,\n    status: normalizeStatus(user.status ?? user.active_status),\n  };\n}\n\nfunction normalizeRole(role) {\n  const roleId = role.user_type_id ?? role.role_id ?? role.roleId ?? role.id;\n  return {\n    ...role,\n    user_type_id: roleId,\n    user_type_name: role.user_type_name ?? role.role_name ?? role.roleName ?? role.name,\n    description: role.description ?? role.role_description ?? role.roleDescription ?? '',\n    status: normalizeStatus(role.status ?? role.active_status ?? 'ACTIVE'),\n  };\n}\n\nfunction normalizeMenu(menu) {\n  const menuId = menu.menu_id ?? menu.menuId ?? menu.legacyMenuId ?? menu.id;\n  const parentMenuId = menu.parent_menu_id ?? menu.parentMenuId;\n  const menuName = menu.menu_name ?? menu.menuName ?? menu.name ?? menu.label;\n  return {\n    ...menu,\n    menu_id: menuId,\n    menu_name: menuName,\n    menu_key: menu.menu_key ?? menu.menuKey ?? menu.key,\n    api_url: menu.api_url ?? menu.apiUrl ?? menu.route ?? '',\n    menu_type: menu.menu_type ?? menu.menuType ?? menu.placement ?? 'MENU',\n    parent_menu_id: parentMenuId || null,\n    component_name: menu.component_name ?? menu.componentName ?? '',\n    display_order: menu.display_order ?? menu.displayOrder ?? menuId ?? 0,\n    status: normalizeStatus(menu.status),\n  };\n}\n\nfunction normalizeStatus(value) {\n  if (value === true || value === 1 || value === '1') return 'ACTIVE';\n  const status = String(value ?? 'ACTIVE').trim().toUpperCase();\n  return status === 'ACTIVE' || status === 'ENABLED' ? 'ACTIVE' : 'INACTIVE';\n}\n\nfunction numberOrZero(value) {\n  const numeric = Number(value);\n  return Number.isFinite(numeric) && numeric > 0 ? numeric : 0;\n}\n\nfunction idOrZero(value) {\n  if (value === undefined || value === null || value === '') return 0;\n  const numeric = Number(value);\n  return Number.isFinite(numeric) && numeric > 0 ? numeric : value;\n}\n\nfunction integerOrUndefined(value) {\n  const numeric = Number(value);\n  return Number.isInteger(numeric) && numeric > 0 ? numeric : undefined;\n}\n\nfunction currentScope() {\n  return {\n    tenantId: localStorage.getItem('tenantId') || undefined,\n    businessId: localStorage.getItem('businessId') || undefined,\n    businessUnitId: localStorage.getItem('businessUnitId') || undefined,\n  };\n}\n\nfunction toUserPayload(user) {\n  const username = user.username ?? user.user_name ?? user.userName;\n  const firstName = user.first_name ?? user.firstName ?? '';\n  const lastName = user.last_name ?? user.lastName ?? '';\n  const roleId = numberOrZero(user.user_type_id ?? user.role_id ?? user.roleId);\n  const reportingId = idOrZero(user.reporting_id ?? user.reportingId ?? user.managerId);\n  const mobile = user.mobile ?? user.mobileNumber ?? user.mobile_number ?? user.phone_number;\n  const activeStatus = normalizeStatus(user.status ?? user.activeStatus) === 'ACTIVE';\n  const appId = String(ADMIN_APP_ID);\n  const updatedBy = integerOrUndefined(user.updated_by ?? user.updatedBy);\n  const createdBy = integerOrUndefined(user.created_by ?? user.createdBy);\n\n  return {\n    ...user,\n    ...currentScope(),\n    appId,\n    app_id: appId,\n    userName: username,\n    user_name: username,\n    username,\n    firstName,\n    first_name: firstName,\n    lastName,\n    last_name: lastName,\n    email: user.email,\n    user_pwd: user.password ?? user.user_pwd,\n    password: user.password ?? user.user_pwd,\n    phoneNumber: mobile,\n    phone_number: mobile,\n    mobileNumber: mobile,\n    mobile_number: mobile,\n    roleId,\n    role_id: roleId,\n    user_type_id: roleId,\n    reportingId,\n    reporting_id: reportingId,\n    activeStatus,\n    // UserMaster.status is a string in the auth API. Keep activeStatus as the\n    // boolean field and send the display/database status using its Go type.\n    status: activeStatus ? 'ACTIVE' : 'INACTIVE',\n    statusText: activeStatus ? 'ACTIVE' : 'INACTIVE',\n    updatedBy,\n    updated_by: updatedBy,\n    createdBy,\n    created_by: createdBy,\n  };\n}\n\nfunction toMenuPayload(menu) {\n  const menuType = String(menu.menu_type ?? menu.menuType ?? menu.placement ?? 'MENU').toUpperCase();\n  return {\n    ...menu,\n    menuName: menu.menu_name,\n    name: menu.menu_name,\n    menuKey: menu.menu_key,\n    key: menu.menu_key,\n    parentMenuId: Number(menu.parent_menu_id ?? 0),\n    // MongoDB's menu schema accepts only \"main\" and \"footer\". MENU and CHILD\n    // are legacy UI types; a child menu's hierarchy is carried by parentMenuId.\n    placement: menuType === 'FOOTER' ? 'footer' : 'main',\n    icon: menu.icon,\n    status: menu.status,\n  };\n}\n\n\nfunction isPermissionValueEnabled(value) {\n  // Permission data reaches this service in several shapes depending on which\n  // Admin screen loaded it (legacy accessValue/access_value, normalized value,\n  // raw booleans, or an object containing one of those fields). Never treat a\n  // missing alias as false when another alias contains the actual value.\n  if (value && typeof value === 'object' && !Array.isArray(value)) {\n    return isPermissionValueEnabled(\n      value.value\n      ?? value.access_value\n      ?? value.accessValue\n      ?? value.permissionValue\n      ?? value.enabled,\n    );\n  }\n\n  if (value === true || value === 1 || value === '1') return true;\n  const normalized = String(value ?? '').trim().toLowerCase();\n  return normalized === 'true' || normalized === 'yes' || normalized === 'active';\n}\n\nfunction permissionValueString(value) {\n  return isPermissionValueEnabled(value) ? '1' : '0';\n}\n\nfunction normalizePermissionGroups(groups) {\n  const source = Array.isArray(groups)\n    ? groups\n    : Object.entries(groups ?? {}).map(([menuName, group]) => ({ ...group, menu_name: menuName }));\n\n  return source.map((group) => {\n    const menuId = group.menu_id ?? group.menuId;\n    const menuName = group.menu_name ?? group.menuName ?? group.name ?? String(menuId ?? '');\n    const permissions = Object.entries(group.permissions ?? {}).reduce((acc, [key, permission]) => {\n      acc[key] = {\n        ...permission,\n        permission_id: permission?.permission_id ?? permission?.permissionId ?? permission?.id,\n        permission_key: permission?.permission_key ?? permission?.permissionKey ?? key,\n        value: permissionValueString(\n          permission?.value\n          ?? permission?.access_value\n          ?? permission?.accessValue\n          ?? permission?.permissionValue\n          ?? permission?.enabled\n          ?? permission,\n        ),\n      };\n      return acc;\n    }, {});\n    return {\n      ...group,\n      menu_id: menuId,\n      menu_name: menuName,\n      menu_key: group.menu_key ?? group.menuKey ?? menuName,\n      permissions,\n    };\n  });\n}\n\nfunction toPermissionUpdatePayload(roleId, rows, menuOrder = []) {\n  const menus = rows.reduce((acc, row) => {\n    const menuName = row.menu_name ?? row.menuName ?? row.menu_key ?? String(row.menu_id);\n    const permissionKey = row.permission_key ?? row.permissionKey;\n    if (!permissionKey) return acc;\n    if (!acc[menuName]) {\n      acc[menuName] = {\n        menuId: row.menu_id ?? row.menuId,\n        permissions: {},\n      };\n    }\n    acc[menuName].permissions[permissionKey] = {\n      id: row.permission_id ?? row.permissionId,\n      value: permissionValueString(\n        row.access_value\n        ?? row.accessValue\n        ?? row.value\n        ?? row.permissionValue\n        ?? row.enabled,\n      ),\n    };\n    return acc;\n  }, {});\n\n  return { roleId, menus, menuOrder };\n}\n\n// listUsers — SERVER-side paging and search.\n//\n// This used to be a hardcoded `?limit=500&offset=0`, with the caller filtering\n// and paginating the returned array in the browser. On a database with 6,134\n// users that had three compounding effects, all reported as separate bugs:\n//   * only the first 500 users existed as far as the UI was concerned;\n//   * those 500 are the NEWEST, which here are all provisioned employer logins,\n//     so the real staff users were not on any page the admin could reach;\n//   * \"search\" only ever matched inside that same 500, so looking for anyone\n//     else returned nothing — the search looked broken when it was simply\n//     searching the wrong 500 rows.\n//\n// The endpoint already supported limit/offset/searchquery/type/sortBy and\n// already returned totalCount; nothing here needed a backend change.\n//\n// Returns { users, total } so the caller can drive real pagination. `total` is\n// the server's count for the CURRENT query, which is what a pager needs.\nexport function listUsers({ limit = 10, offset = 0, search = '', type = '', sort = '' } = {}) {\n  const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n  if (search) params.set('searchquery', search);\n  if (type) params.set('type', type);\n  if (sort) params.set('sortBy', sort);\n  return request(`/get-all-users?${params.toString()}`).then((data) => ({\n    users: toArray(data, ['users']).map(normalizeUser),\n    total: Number(data?.totalCount ?? data?.total ?? 0) || 0,\n  }));\n}\n\nexport function getUsersFromRole(roleId) {\n  return request(`/get-users?roleId=${encodeURIComponent(roleId)}`).then((data) => (\n    toArray(data, ['users']).map(normalizeUser)\n  ));\n}\n\nexport function createUser(user) {\n  return request('/create-user', {\n    method: 'POST',\n    body: JSON.stringify(toUserPayload(user)),\n  });\n}\n\nexport function updateUser(userId, user) {\n  return request(`/update-user?userId=${encodeURIComponent(userId)}`, {\n    method: 'PUT',\n    body: JSON.stringify(toUserPayload(user)),\n  });\n}\n\nexport function deleteUser(userId) {\n  return request(`/delete-user?userId=${encodeURIComponent(userId)}`, {\n    method: 'PUT',\n  });\n}\n\nexport function listUserTypes() {\n  return request('/get-roles').then((data) => [\n    ...toArray(data, ['zinnext_default']),\n    ...toArray(data, ['custom_roles']),\n  ].map(normalizeRole));\n}\n\nexport function createRole(role) {\n  return request('/add-custom-role', {\n    method: 'POST',\n    body: JSON.stringify({\n      importedPermissionId: Number(role.imported_permission_id ?? 0),\n      newRoleName: role.user_type_name,\n      roleDescription: role.description ?? '',\n      menuIds: role.visible_menu_ids ?? [],\n    }),\n  }).then(normalizeRole);\n}\n\nexport function updateRole(roleId, role) {\n  return request(`/custom-roles/${encodeURIComponent(roleId)}`, {\n    method: 'PUT',\n    body: JSON.stringify({\n      roleName: role.user_type_name,\n      role_name: role.user_type_name,\n      roleDescription: role.description ?? '',\n      description: role.description ?? '',\n      status: normalizeStatus(role.status) === 'ACTIVE' ? 1 : 0,\n      statusText: normalizeStatus(role.status),\n    }),\n  }).then(normalizeRole);\n}\n\nexport function deleteRole(roleId) {\n  return request(`/custom-roles/${encodeURIComponent(roleId)}`, { method: 'DELETE' });\n}\n\nexport function listMenus() {\n  return request('/admin/menu-modules').then((data) => toArray(data).map(normalizeMenu));\n}\n\nexport function createMenu(menu) {\n  return request('/admin/menu-modules', {\n    method: 'POST',\n    body: JSON.stringify(toMenuPayload(menu)),\n  });\n}\n\nexport function updateMenu(menuId, menu) {\n  return request(`/admin/menu-modules/${menuId}`, {\n    method: 'PUT',\n    body: JSON.stringify(toMenuPayload(menu)),\n  });\n}\n\nexport function deleteMenu(menuId) {\n  return request(`/admin/menu-modules/${menuId}`, {\n    method: 'DELETE',\n  });\n}\n\nexport function listMenuPermissions() {\n  return request('/admin/menu-actions');\n}\n\nexport function getRoleMenuPermissions(userTypeId) {\n  return request(`/get-role-details?roleid=${encodeURIComponent(userTypeId)}`)\n    .then(normalizePermissionGroups);\n}\n\nexport function saveRoleMenuPermissions(userTypeId, permissions) {\n  return request('/edit-role-details', {\n    method: 'PUT',\n    body: JSON.stringify(toPermissionUpdatePayload(\n      userTypeId,\n      permissions,\n      [...new Set(permissions.map((row) => row.menu_key ?? row.menuName ?? row.menu_name).filter(Boolean))],\n    )),\n  });\n}\n\nexport function getUserMenuPermissions(userId) {\n  return request(`/get-role-details?userId=${encodeURIComponent(userId)}`)\n    .then(normalizePermissionGroups);\n}\n\nexport function saveUserMenuPermissions(userId, permissions) {\n  return request('/edit-role-details', {\n    method: 'PUT',\n    body: JSON.stringify({ ...toPermissionUpdatePayload(null, permissions), userId }),\n  });\n}\n","// Specialized permissions only make sense for particular modules. Filtering\n// affects presentation only; saved role values remain intact.\nconst SPECIAL_ACTION_MENUS = {\n  po: [],\n  msa: [],\n  sourcing: ['jobs'],\n  assign: ['jobs'],\n  approve: ['submissions', 'onboarding', 'assignments', 'timesheet', 'vendors', 'test cases'],\n  move_onboard: ['submissions'],\n  change_status: ['jobs', 'candidates', 'submissions', 'onboarding', 'assignments'],\n  candidate_self: ['candidates'],\n  candidate_all: ['candidates'],\n  my_jobs: ['jobs'],\n  all_jobs: ['jobs'],\n  reject: ['submissions', 'onboarding', 'assignments', 'timesheet', 'vendors', 'test cases'],\n  viewProposedRate: ['submissions'],\n  po_msa: ['onboarding'],\n  // ReApprove — gates who may resend an onboarding finance request to the CFO\n  // after a rejection (Approve alone only gates the FIRST send). See the\n  // \"MSI\" role in cmd/wire-delivery-msi-roles.\n  reApprove: ['onboarding'],\n  // SendApprove gates both the first Send for Approval and any resend.\n  sendApprove: ['onboarding'],\n};\n\nexport function isPermissionApplicable(menuName, permissionKey) {\n  const wantedKey = String(permissionKey ?? '').trim().toLowerCase();\n  const canonicalKey = Object.keys(SPECIAL_ACTION_MENUS).find(\n    (key) => key.toLowerCase() === wantedKey,\n  );\n  const applicableMenus = canonicalKey ? SPECIAL_ACTION_MENUS[canonicalKey] : undefined;\n  if (!applicableMenus) return true;\n  return applicableMenus.includes(String(menuName ?? '').trim().toLowerCase());\n}\n","import { Card } from 'antd';\nimport '../../styles/AppCard.css';\n\nexport default function AppCard({\n  title,\n  icon,\n  extra,\n  children,\n  variant = 'default',\n  ...rest\n}) {\n  const cardTitle = (icon || title) ? (\n    <span className=\"app-card-title\">\n      {icon && <span className=\"app-card-title-icon\">{icon}</span>}\n      {title}\n    </span>\n  ) : undefined;\n\n  return (\n    <Card\n      className={`app-card app-card--${variant}`}\n      title={cardTitle}\n      extra={extra}\n      {...rest}\n    >\n      {children}\n    </Card>\n  );\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// ModuleFieldConfigEditor — the full List View / Filter / Form field editor\n// (badges, action buttons, lookups, secondary fields, render types, drag\n// reorder). Configure once per role; every user with that role sees the\n// same fields — this is the role-scoped counterpart of what used to be a\n// per-user editor in UsersSection.jsx (moved here in full, not simplified,\n// so no admin capability is lost).\n// ─────────────────────────────────────────────────────────────────────────\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n  Button, Input, Radio, Select, Space, Spin, Switch, Tabs, Tooltip, Typography, Upload, message,\n} from 'antd';\nimport {\n  CloseOutlined, DownOutlined, HolderOutlined, LinkOutlined,\n  PlusOutlined, RightOutlined, TagsOutlined, UploadOutlined, UserOutlined,\n} from '@ant-design/icons';\nimport TemplateEditor from '../../../../components/TemplateEditor';\nimport {\n  getArraySubfields,\n  getAvailableCollections,\n  getAvailableModules,\n  getCollectionFields,\n  getRoleModuleFields,\n  getRoleModuleFieldsWithMeta,\n  updateRoleModuleFieldConfig,\n  uploadListViewActionIcon,\n} from '../../../../services/adminApi';\nimport { getDropdownValues } from '../../../../services/dropdownApi';\nimport '../../../../styles/UserSettingsSection.css';\n\nconst { Text } = Typography;\nconst { Option } = Select;\n\nconst DEFAULT_MODULE_TABS = [\n  { key: 'job', label: 'Jobs' },\n  { key: 'candidate', label: 'Candidates' },\n  { key: 'submissions', label: 'Submissions' },\n  { key: 'billing', label: 'Billing' },\n  { key: 'payroll', label: 'Payroll' },\n];\n\nconst RENDER_TYPES = [\n  { key: '', label: 'Text', icon: <span style={{ fontSize: 14, fontWeight: 700 }}>Aa</span> },\n  { key: 'badge', label: 'Badge', icon: <TagsOutlined style={{ fontSize: 16 }} /> },\n  { key: 'avatar', label: 'Avatar', icon: <UserOutlined style={{ fontSize: 16 }} /> },\n  { key: 'link', label: 'Link', icon: <LinkOutlined style={{ fontSize: 16 }} /> },\n];\n\nconst BADGE_COLORS = [\n  { color: '#52c41a', bg: '#f6ffed' }, { color: '#1677ff', bg: '#e6f7ff' },\n  { color: '#fa8c16', bg: '#fff7e6' }, { color: '#ff4d4f', bg: '#fff2f0' },\n  { color: '#722ed1', bg: '#f9f0ff' }, { color: '#13c2c2', bg: '#e6fffb' },\n  { color: '#eb2f96', bg: '#fff0f6' }, { color: '#faad14', bg: '#fffbe6' },\n];\n\nconst API_MODULE_MAP = { job: 'jobs', candidate: 'candidates', submissions: 'submissions', billing: 'billing', payroll: 'payroll' };\n\nfunction moduleTitle(value) {\n  return String(value || '')\n    .replace(/[-_]/g, ' ')\n    .replace(/\\b\\w/g, (c) => c.toUpperCase())\n    .trim();\n}\n\nfunction normalizeModuleTab(module) {\n  if (typeof module === 'string') {\n    return { key: module, apiModule: module, label: moduleTitle(module) };\n  }\n\n  const key = (\n    module?.menuKey ?? module?.key ?? module?.moduleKey ?? module?.value ?? module?.module ??\n    module?.apiModule ?? module?.name ?? module?.modulename ?? module?.menuName\n  );\n  if (!key) return null;\n\n  const apiModule = (\n    module?.apiModule ?? module?.api_module ?? module?.module ?? module?.value ??\n    module?.menuKey ?? module?.key ?? module?.name ?? module?.modulename ?? module?.menuName ?? key\n  );\n\n  return {\n    key,\n    apiModule,\n    label: (\n      module?.label ?? module?.moduleLabel ?? module?.moduleName ??\n      module?.name ?? module?.modulename ?? module?.menuName ?? moduleTitle(key)\n    ),\n  };\n}\n\nfunction normalizeModuleTabs(modules) {\n  const source = Array.isArray(modules) && modules.length ? modules : DEFAULT_MODULE_TABS;\n  const seen = new Set();\n  const tabs = source\n    .map(normalizeModuleTab)\n    .filter(Boolean)\n    .filter((module) => {\n      if (seen.has(module.key)) return false;\n      seen.add(module.key);\n      return true;\n    });\n\n  return tabs.length ? tabs : DEFAULT_MODULE_TABS;\n}\n\n// ─────────────────────────────────────────────────────────────\n// List-view field detail panel (badges, avatars, links, secondary fields,\n// lookups, action buttons)\n// ─────────────────────────────────────────────────────────────\nfunction ListViewDetails({\n  field, collections, collFields, subfields,\n  onCollectionChange, onLookupFieldChange,\n  addSecondaryField, removeSecondaryField,\n  addActionButton, updateActionButton, removeActionButton,\n  moduleKey, fieldKey, update,\n}) {\n  const [newSecondary, setNewSecondary] = useState('');\n  const [iconUploading, setIconUploading] = useState({});\n  const [detecting, setDetecting] = useState(false);\n\n  function setBadgeMode(mode) {\n    if (mode === 'common') update({ commonStyle: { color: '#1677ff', bg: '#e6f7ff', variant: 'badge' }, valueStyles: [] });\n    else update({ commonStyle: null });\n  }\n  function updateCommonStyle(patch) {\n    update({ commonStyle: { ...(field.commonStyle ?? { color: '#595959', bg: '#f5f5f5', variant: 'badge' }), ...patch } });\n  }\n  function addValueStyle() {\n    update({ valueStyles: [...(field.valueStyles ?? []), { value: '', label: '', color: '#595959', bg: '#f5f5f5', variant: 'badge' }] });\n  }\n  function updateValueStyle(idx, patch) {\n    const styles = [...(field.valueStyles ?? [])];\n    styles[idx] = { ...styles[idx], ...patch };\n    update({ valueStyles: styles });\n  }\n  function removeValueStyle(idx) {\n    update({ valueStyles: (field.valueStyles ?? []).filter((_, i) => i !== idx) });\n  }\n  async function autoDetectValues() {\n    setDetecting(true);\n    try {\n      const apiMod = field.apiModule ?? API_MODULE_MAP[moduleKey] ?? moduleKey;\n      const result = await getDropdownValues(apiMod, fieldKey, '', 50, 0);\n      const items = Array.isArray(result) ? result : (result?.data ?? []);\n      const styles = items.map((item, i) => {\n        const val = typeof item === 'object' ? (item.value ?? item.label ?? '') : String(item);\n        const lbl = typeof item === 'object' ? (item.label ?? item.value ?? '') : String(item);\n        return { value: String(val), label: String(lbl), variant: 'badge', ...BADGE_COLORS[i % BADGE_COLORS.length] };\n      });\n      if (styles.length === 0) { message.info('No values found for this field'); return; }\n      update({ valueStyles: styles });\n    } catch { message.error('Could not detect values'); }\n    finally { setDetecting(false); }\n  }\n\n  async function handleIconUpload(btnIdx, file) {\n    setIconUploading((p) => ({ ...p, [btnIdx]: true }));\n    try {\n      const result = await uploadListViewActionIcon(file);\n      updateActionButton(btnIdx, {\n        iconUrl: result?.iconUrl ?? result?.url ?? '',\n        iconPath: result?.iconPath ?? result?.path ?? '',\n      });\n    } catch { message.error('Icon upload failed'); }\n    finally { setIconUploading((p) => ({ ...p, [btnIdx]: false })); }\n    return false;\n  }\n\n  const renderType = field.renderType ?? '';\n  const isCommon = Boolean(field.commonStyle);\n  const cs = field.commonStyle ?? {};\n  const vs = field.valueStyles ?? [];\n  const rc = field.renderConfig ?? {};\n\n  return (\n    <>\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">Display Style</div>\n        <div className=\"uss-detail-row\">\n          {RENDER_TYPES.map((rt) => (\n            <button key={rt.key}\n              className={`uss-render-type-btn${renderType === rt.key ? ' active' : ''}`}\n              onClick={() => update({ renderType: rt.key, commonStyle: null, valueStyles: [], renderConfig: null })}>\n              {rt.icon}<span>{rt.label}</span>\n            </button>\n          ))}\n        </div>\n\n        {/* ── Badge color config ── */}\n        {renderType === 'badge' && (\n          <div className=\"uss-badge-config\">\n            <Radio.Group size=\"small\" value={isCommon ? 'common' : 'perValue'}\n              onChange={(e) => setBadgeMode(e.target.value)} style={{ marginBottom: 8 }}>\n              <Radio value=\"perValue\">Per value</Radio>\n              <Radio value=\"common\">Same for all</Radio>\n            </Radio.Group>\n\n            {isCommon && (\n              <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>\n                <Tooltip title=\"Text color\">\n                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n                    <input type=\"color\" value={cs.color || '#595959'} style={{ width: 28, height: 24, border: 'none', cursor: 'pointer', padding: 0 }}\n                      onChange={(e) => updateCommonStyle({ color: e.target.value })} />\n                    <Text style={{ fontSize: 10 }}>Text</Text>\n                  </div>\n                </Tooltip>\n                <Tooltip title=\"Background color\">\n                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n                    <input type=\"color\" value={cs.bg || '#f5f5f5'} style={{ width: 28, height: 24, border: 'none', cursor: 'pointer', padding: 0 }}\n                      onChange={(e) => updateCommonStyle({ bg: e.target.value })} />\n                    <Text style={{ fontSize: 10 }}>BG</Text>\n                  </div>\n                </Tooltip>\n                <Select size=\"small\" style={{ width: 80 }} value={cs.variant || 'badge'}\n                  options={[{ value: 'badge', label: 'Badge' }, { value: 'dot', label: 'Dot' }, { value: 'tag', label: 'Tag' }]}\n                  onChange={(v) => updateCommonStyle({ variant: v })} />\n                <span style={{ padding: '1px 12px', borderRadius: 20, fontSize: 11, fontWeight: 500, color: cs.color || '#595959', background: cs.bg || '#f5f5f5' }}>\n                  Preview\n                </span>\n              </div>\n            )}\n\n            {!isCommon && (\n              <div>\n                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>\n                  <Text style={{ fontSize: 11, color: '#555', fontWeight: 600 }}>Value → Style mapping</Text>\n                  <Space size={6}>\n                    <Button size=\"small\" loading={detecting} onClick={autoDetectValues}>Auto-detect values</Button>\n                    <Button size=\"small\" icon={<PlusOutlined />} onClick={addValueStyle}>Add</Button>\n                  </Space>\n                </div>\n                {vs.length === 0 && (\n                  <Text type=\"secondary\" style={{ fontSize: 12 }}>Click \"Auto-detect values\" to populate from live data, or \"Add\" to map manually.</Text>\n                )}\n                {vs.map((style, idx) => (\n                  <div key={idx} style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 62px 62px 54px 26px', gap: 5, alignItems: 'center', marginBottom: 6 }}>\n                    <Input size=\"small\" placeholder=\"raw value\" value={style.value ?? ''}\n                      onChange={(e) => updateValueStyle(idx, { value: e.target.value })} />\n                    <Input size=\"small\" placeholder=\"display label\" value={style.label ?? ''}\n                      onChange={(e) => updateValueStyle(idx, { label: e.target.value })} />\n                    <Tooltip title=\"Text color\">\n                      <div style={{ display: 'flex', alignItems: 'center', gap: 3 }}>\n                        <input type=\"color\" value={style.color || '#595959'} style={{ width: 28, height: 24, border: 'none', cursor: 'pointer', padding: 0 }}\n                          onChange={(e) => updateValueStyle(idx, { color: e.target.value })} />\n                        <Text style={{ fontSize: 10 }}>Text</Text>\n                      </div>\n                    </Tooltip>\n                    <Tooltip title=\"Background color\">\n                      <div style={{ display: 'flex', alignItems: 'center', gap: 3 }}>\n                        <input type=\"color\" value={style.bg || '#f5f5f5'} style={{ width: 28, height: 24, border: 'none', cursor: 'pointer', padding: 0 }}\n                          onChange={(e) => updateValueStyle(idx, { bg: e.target.value })} />\n                        <Text style={{ fontSize: 10 }}>BG</Text>\n                      </div>\n                    </Tooltip>\n                    <span style={{ padding: '1px 6px', borderRadius: 20, fontSize: 11, fontWeight: 500, textAlign: 'center', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: style.color || '#595959', background: style.bg || '#f5f5f5' }}>\n                      {style.label || style.value || '…'}\n                    </span>\n                    <Button size=\"small\" type=\"text\" danger icon={<CloseOutlined />} onClick={() => removeValueStyle(idx)} />\n                  </div>\n                ))}\n              </div>\n            )}\n          </div>\n        )}\n\n        {/* ── Array value config ── */}\n        <div style={{ marginTop: 10 }}>\n          <Text style={{ fontSize: 11, color: '#555', display: 'block', marginBottom: 3 }}>\n            Array item field (latest item)\n          </Text>\n          <Select\n            size=\"small\"\n            showSearch\n            allowClear\n            style={{ width: '100%' }}\n            placeholder={subfields.length > 0 ? 'Select a child field from the array' : 'Enter child field, e.g. clientBudgetStart'}\n            value={rc.lastItemField || undefined}\n            options={subfields.map((sf) => ({ value: sf, label: sf }))}\n            onChange={(v) => update({\n              renderConfig: {\n                ...rc,\n                lastItemField: v ?? '',\n              },\n            })}\n            onSearch={(value) => {\n              if (!subfields.includes(value) && value) {\n                // Select remains searchable; custom field names can be committed below.\n              }\n            }}\n            dropdownRender={(menu) => (\n              <>\n                {menu}\n                <div style={{ padding: '8px 10px', borderTop: '1px solid var(--color-border-muted)' }}>\n                  <Input\n                    size=\"small\"\n                    placeholder=\"Custom child field\"\n                    value={rc.lastItemField || ''}\n                    onChange={(e) => update({\n                      renderConfig: {\n                        ...rc,\n                        lastItemField: e.target.value.trim(),\n                      },\n                    })}\n                  />\n                </div>\n              </>\n            )}\n          />\n          <Text type=\"secondary\" style={{ display: 'block', marginTop: 4, fontSize: 10 }}>\n            For an array such as jobPayDetails, ListView displays this field from the last array element.\n          </Text>\n        </div>\n\n        {/* ── Avatar config ── */}\n        {renderType === 'avatar' && (\n          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 80px', gap: 8, marginTop: 8 }}>\n            <div>\n              <Text style={{ fontSize: 11, color: '#555', display: 'block', marginBottom: 3 }}>Name field</Text>\n              <Select size=\"small\" showSearch allowClear style={{ width: '100%' }}\n                placeholder=\"e.g. recruiterName\" value={rc.labelField || undefined}\n                options={subfields.length > 0 ? subfields.map((sf) => ({ value: sf, label: sf })) : []}\n                onChange={(v) => update({ renderConfig: { ...rc, labelField: v ?? '' } })} />\n            </div>\n            <div>\n              <Text style={{ fontSize: 11, color: '#555', display: 'block', marginBottom: 3 }}>Color field (opt.)</Text>\n              <Select size=\"small\" showSearch allowClear style={{ width: '100%' }}\n                placeholder=\"color\" value={rc.colorField || undefined}\n                options={subfields.length > 0 ? subfields.map((sf) => ({ value: sf, label: sf })) : []}\n                onChange={(v) => update({ renderConfig: { ...rc, colorField: v ?? '' } })} />\n            </div>\n            <div>\n              <Text style={{ fontSize: 11, color: '#555', display: 'block', marginBottom: 3 }}>Max visible</Text>\n              <Input size=\"small\" type=\"number\" min={1} max={10} value={rc.maxVisible || 3}\n                onChange={(e) => update({ renderConfig: { ...rc, maxVisible: Number(e.target.value) || 3 } })} />\n            </div>\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">Display Template</div>\n        <TemplateEditor value={field.displayTemplate ?? ''}\n          onChange={(v) => update({ displayTemplate: v })}\n          placeholder=\"e.g. {{firstName}} {{lastName}}\" />\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">Default Value</div>\n        <Input\n          size=\"small\"\n          allowClear\n          value={field.defaultValue ?? ''}\n          onChange={(e) => update({ defaultValue: e.target.value })}\n          placeholder=\"Shown when data is empty, e.g. N/A\"\n        />\n        <Text type=\"secondary\" style={{ display: 'block', marginTop: 4, fontSize: 10 }}>\n          Used only when this column resolves to an empty, null, missing, or unavailable value.\n        </Text>\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">Empty / Group Value Rules</div>\n        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>\n            <div>\n              <Text style={{ fontSize: 11 }}>Treat numeric 0 as empty</Text>\n              <Text type=\"secondary\" style={{ display: 'block', fontSize: 10 }}>\n                Useful for integer fields where 0 means the value was not provided.\n              </Text>\n            </div>\n            <Switch\n              size=\"small\"\n              checked={Boolean(rc.treatZeroAsEmpty)}\n              onChange={(v) => update({ renderConfig: { ...rc, treatZeroAsEmpty: v } })}\n            />\n          </div>\n          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>\n            <div>\n              <Text style={{ fontSize: 11 }}>Clean grouped template when a value is empty</Text>\n              <Text type=\"secondary\" style={{ display: 'block', fontSize: 10 }}>\n                Example: <code>{'{{field1}} - {{field2}}'}</code> shows only field2 when field1 is empty, without the extra dash.\n              </Text>\n            </div>\n            <Switch\n              size=\"small\"\n              checked={Boolean(rc.cleanEmptyTemplateSeparators)}\n              onChange={(v) => update({ renderConfig: { ...rc, cleanEmptyTemplateSeparators: v } })}\n            />\n          </div>\n        </div>\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">\n          Link\n          <Switch size=\"small\" style={{ marginLeft: 8 }} checked={Boolean(field.isLink)}\n            onChange={(v) => update({ isLink: v })} />\n        </div>\n        {field.isLink && (\n          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, paddingTop: 4 }}>\n            <TemplateEditor value={field.linkTemplate ?? ''} onChange={(v) => update({ linkTemplate: v })}\n              placeholder=\"e.g. /jobs/{{jobId}}\" />\n            <div className=\"uss-detail-row\">\n              <Select size=\"small\" value={field.linkType ?? 'internal'} onChange={(v) => update({ linkType: v })} style={{ width: 120 }}>\n                <Option value=\"internal\">internal</Option>\n                <Option value=\"external\">external</Option>\n              </Select>\n              <Select size=\"small\" value={field.linkTarget ?? '_self'} onChange={(v) => update({ linkTarget: v })} style={{ width: 100 }}>\n                <Option value=\"_self\">_self</Option>\n                <Option value=\"_blank\">_blank</Option>\n              </Select>\n            </div>\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">Secondary Fields</div>\n        <div className=\"uss-detail-row\" style={{ flexWrap: 'wrap' }}>\n          {(field.secondaryFields ?? []).map((f) => (\n            <span key={f} className=\"uss-secondary-tag\">\n              {f}\n              <button onClick={() => removeSecondaryField(f)}>×</button>\n            </span>\n          ))}\n        </div>\n        <div className=\"uss-detail-row\">\n          <Input size=\"small\" placeholder=\"Add field key\" value={newSecondary}\n            onChange={(e) => setNewSecondary(e.target.value)}\n            onPressEnter={() => { addSecondaryField(newSecondary); setNewSecondary(''); }}\n            style={{ width: 160 }} />\n          <Button size=\"small\" type=\"link\" icon={<PlusOutlined />}\n            onClick={() => { addSecondaryField(newSecondary); setNewSecondary(''); }}>Add</Button>\n        </div>\n        {(field.secondaryFields?.length > 0) && (\n          <div style={{ marginTop: 4, display: 'flex', alignItems: 'center', gap: 8 }}>\n            <Text style={{ fontSize: 11, color: 'var(--color-text-muted)' }}>Separator:</Text>\n            <Input size=\"small\" value={field.secondarySeparator ?? ''} placeholder=\"·\" style={{ width: 64 }}\n              onChange={(e) => update({ secondarySeparator: e.target.value })} />\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">\n          Lookup (FK resolve)\n          <Switch size=\"small\" style={{ marginLeft: 8 }} checked={Boolean(field.lookup)}\n            onChange={(v) => update({ lookup: v ? { collection: '', displayField: '', valueField: '', projectFields: [] } : null })} />\n        </div>\n        {field.lookup && (\n          <div className=\"uss-lookup-grid\">\n            <div className=\"uss-lookup-row\">\n              <span className=\"uss-lookup-label\">Collection</span>\n              <Select size=\"small\" value={field.lookup?.collection ?? ''} onChange={onCollectionChange}\n                showSearch placeholder=\"Select collection\" style={{ flex: 1 }}>\n                {collections.map((c) => <Option key={c} value={c}>{c}</Option>)}\n              </Select>\n            </div>\n            <div className=\"uss-lookup-row\">\n              <span className=\"uss-lookup-label\">Tenant scoped</span>\n              <Switch size=\"small\" checked={Boolean(field.lookup?.tenantScoped)}\n                onChange={(v) => onLookupFieldChange(field.fieldKey, { tenantScoped: v })} />\n            </div>\n            <div className=\"uss-lookup-row\">\n              <span className=\"uss-lookup-label\">Source Field</span>\n              <Input\n                size=\"small\"\n                value={field.lookup?.localField ?? ''}\n                placeholder={`Defaults to ${field.fieldKey}`}\n                onChange={(e) => onLookupFieldChange(field.fieldKey, { localField: e.target.value })}\n                style={{ flex: 1 }}\n              />\n            </div>\n            {collFields.length > 0 && (\n              <>\n                <div className=\"uss-lookup-row\">\n                  <span className=\"uss-lookup-label\">Value Field</span>\n                  <Select size=\"small\" value={field.lookup?.valueField ?? ''}\n                    onChange={(v) => onLookupFieldChange(field.fieldKey, { valueField: v })}\n                    placeholder=\"ID field\" style={{ flex: 1 }}>\n                    {collFields.map((f) => <Option key={f} value={f}>{f}</Option>)}\n                  </Select>\n                </div>\n                <div className=\"uss-lookup-row\">\n                  <span className=\"uss-lookup-label\">Display Field</span>\n                  <Select size=\"small\" value={field.lookup?.displayField ?? ''}\n                    onChange={(v) => onLookupFieldChange(field.fieldKey, { displayField: v })}\n                    placeholder=\"Label field\" style={{ flex: 1 }}>\n                    {[...collFields, ...subfields].map((f) => <Option key={f} value={f}>{f}</Option>)}\n                  </Select>\n                </div>\n              </>\n            )}\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">\n          Derived Array Value\n          <Switch size=\"small\" style={{ marginLeft: 8 }} checked={Boolean(field.derived)}\n            onChange={(v) => update({ derived: v ? { type: 'arrayField', source: '', matchField: '', matchValue: '', valueField: '', default: null } : null })} />\n        </div>\n        {field.derived && (\n          <div className=\"uss-lookup-grid\">\n            {[\n              ['Source array', 'source', 'e.g. stages'],\n              ['Match field', 'matchField', 'e.g. stageCode'],\n              ['Match value', 'matchValue', 'e.g. PO_MSA'],\n              ['Value field', 'valueField', 'e.g. status'],\n            ].map(([label, key, placeholder]) => (\n              <div className=\"uss-lookup-row\" key={key}>\n                <span className=\"uss-lookup-label\">{label}</span>\n                <Input size=\"small\" value={field.derived?.[key] ?? ''} placeholder={placeholder}\n                  onChange={(e) => update({ derived: { ...field.derived, [key]: e.target.value } })} />\n              </div>\n            ))}\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\">\n          Computed Value\n          <Switch size=\"small\" style={{ marginLeft: 8 }} checked={Boolean(field.computed)}\n            onChange={(v) => update({ computed: v ? { operator: 'subtract', operands: [], default: 0 } : null })} />\n        </div>\n        {field.computed && (\n          <div className=\"uss-lookup-grid\">\n            <div className=\"uss-lookup-row\">\n              <span className=\"uss-lookup-label\">Operator</span>\n              <Select size=\"small\" value={field.computed?.operator ?? 'subtract'} style={{ flex: 1 }}\n                options={['add', 'subtract', 'multiply', 'divide', 'percentage', 'ifNull'].map((value) => ({ value, label: value }))}\n                onChange={(operator) => update({ computed: { ...field.computed, operator } })} />\n            </div>\n            <Text style={{ fontSize: 11 }}>Operands JSON (field or value entries)</Text>\n            <Input.TextArea key={JSON.stringify(field.computed?.operands ?? [])} rows={3}\n              defaultValue={JSON.stringify(field.computed?.operands ?? [], null, 2)}\n              placeholder={'[{\"field\":\"billRate\"},{\"field\":\"payRate\"}]'}\n              onBlur={(e) => {\n                try {\n                  const operands = JSON.parse(e.target.value || '[]');\n                  if (!Array.isArray(operands)) throw new Error('Operands must be an array');\n                  update({ computed: { ...field.computed, operands } });\n                } catch (error) {\n                  message.error(error.message || 'Invalid operands JSON');\n                }\n              }} />\n          </div>\n        )}\n      </div>\n\n      <div className=\"uss-detail-section\">\n        <div className=\"uss-detail-label\" style={{ display: 'flex', justifyContent: 'space-between' }}>\n          <span>Action Buttons <span style={{ fontSize: 11, fontWeight: 400, color: 'var(--color-text-muted)' }}>(max 3)</span></span>\n          {(field.actionButtons ?? []).length < 3 && (\n            <Button type=\"link\" size=\"small\" icon={<PlusOutlined />} onClick={addActionButton}>Add Icon</Button>\n          )}\n        </div>\n        {(field.actionButtons ?? []).map((btn, i) => (\n          <div key={i}>\n            <div className=\"uss-action-btn-row\">\n              <Upload showUploadList={false} beforeUpload={(f) => { handleIconUpload(i, f); return false; }} accept=\"image/*\">\n                <Tooltip title=\"Click to upload icon\">\n                  <div className=\"uss-action-btn-icon-slot\">\n                    {iconUploading[i]\n                      ? <Spin size=\"small\" />\n                      : btn.iconUrl\n                        ? <img src={btn.iconUrl} alt={`action-${i}`} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n                        : <UploadOutlined style={{ color: '#aaa', fontSize: 14 }} />\n                    }\n                  </div>\n                </Tooltip>\n              </Upload>\n              <Input size=\"small\" value={btn.name ?? ''} onChange={(e) => updateActionButton(i, { name: e.target.value })}\n                placeholder=\"Tooltip (e.g. Edit)\" style={{ width: 110 }} />\n              <Radio.Group size=\"small\" value={btn.type ?? 'page'} onChange={(e) => updateActionButton(i, { type: e.target.value })}>\n                <Radio value=\"page\">Page</Radio>\n                <Radio value=\"popup\">Popup</Radio>\n              </Radio.Group>\n              <Input size=\"small\" value={btn.routeUrl ?? ''} onChange={(e) => updateActionButton(i, { routeUrl: e.target.value })}\n                placeholder=\"Route URL (e.g. /jobs/:_id)\" prefix={<LinkOutlined style={{ color: '#bbb' }} />} style={{ flex: 1 }} />\n              <Button size=\"small\" danger type=\"text\" onClick={() => removeActionButton(i)}>✕</Button>\n            </div>\n            <div style={{ display: 'flex', alignItems: 'center', gap: 8, paddingLeft: 36 }}>\n              <Text style={{ fontSize: 11, color: '#999', whiteSpace: 'nowrap' }}>Permission:</Text>\n              <Select size=\"small\" allowClear value={btn.permissionKey || undefined}\n                onChange={(v) => updateActionButton(i, { permissionKey: v ?? '' })}\n                placeholder=\"Always visible\" style={{ width: 180 }}\n                options={[{ value: 'edit' }, { value: 'delete' }, { value: 'add' }, { value: 'view' }]}\n              />\n            </div>\n            <div style={{ display: 'flex', alignItems: 'center', gap: 8, paddingLeft: 36, marginTop: 4, flexWrap: 'wrap' }}>\n              <Text style={{ fontSize: 11, color: '#999', whiteSpace: 'nowrap' }}>Show only if:</Text>\n              <Input size=\"small\" value={btn.showIfField ?? ''}\n                onChange={(e) => updateActionButton(i, { showIfField: e.target.value })}\n                placeholder=\"field (e.g. createdBy)\" style={{ width: 180 }} />\n              {/* Same operator set + {currentUserId} token as the module Action\n                  Rules, so a column button uses the common rule logic — e.g.\n                  createdBy eq {currentUserId} shows Resubmit only to the creator. */}\n              <Select size=\"small\" value={btn.showIfOperator || 'eq'} style={{ width: 130 }}\n                onChange={(v) => updateActionButton(i, { showIfOperator: v })}\n                options={ACTION_BUTTON_OPERATORS} />\n              {!['isEmpty', 'notEmpty'].includes(btn.showIfOperator || 'eq') && (\n                <Select size=\"small\" showSearch allowClear mode=\"tags\" maxCount={1}\n                  value={btn.showIfValue ? [btn.showIfValue] : []} style={{ width: 200 }}\n                  onChange={(v) => updateActionButton(i, { showIfValue: v[v.length - 1] ?? '' })}\n                  placeholder=\"value or {currentUserId}\"\n                  options={[{ value: '{currentUserId}', label: '{currentUserId} — signed-in user' }]}\n                  filterOption={(input, opt) => (opt?.label ?? opt?.value ?? '').toLowerCase().includes(input.toLowerCase())} />\n              )}\n              {btn.showIfField && (\n                <Button size=\"small\" type=\"text\" danger icon={<CloseOutlined />}\n                  onClick={() => updateActionButton(i, { showIfField: '', showIfOperator: '', showIfValue: '' })} />\n              )}\n            </div>\n          </div>\n        ))}\n      </div>\n    </>\n  );\n}\n\n// Operators for a column action button's \"Show only if\" — the same set the\n// module Action Rules use (utils/actionRuleEngine), so column, row, toolbar and\n// detail actions all gate on one common logic.\nconst ACTION_BUTTON_OPERATORS = [\n  { value: 'eq', label: 'equals' },\n  { value: 'ne', label: 'not equals' },\n  { value: 'isEmpty', label: 'is empty' },\n  { value: 'notEmpty', label: 'is not empty' },\n  { value: 'contains', label: 'contains' },\n  { value: 'includes', label: 'list includes (exact)' },\n  { value: 'notIncludes', label: 'list excludes (exact)' },\n];\n\nconst FILTER_DROPDOWN_SOURCES = [\n  { label: 'Module data (distinct)', value: 'module' },\n  { label: 'Masters collection', value: 'master' },\n  { label: 'Group value', value: 'group' },\n];\n\nconst DROPDOWN_FIELD_TYPES = ['select', 'radio', 'checkbox'];\n\nconst FILTER_INPUT_TYPE_OPTIONS = [\n  { label: 'Dropdown', value: 'dropdown' },\n  { label: 'Checkbox', value: 'checkbox' },\n  { label: 'Radio', value: 'radio' },\n  { label: 'Date Range', value: 'datepicker' },\n  { label: 'Number Range', value: 'number-range' },\n];\n\nfunction FormFilterDetails({ field, update, configType, collections, collFields, onCollectionChange, onLookupFieldChange, availableFields = [] }) {\n  const isDropdownType = DROPDOWN_FIELD_TYPES.includes(field.type);\n  const hasLookup = Boolean(field.lookup);\n\n  function handleLookupToggle(v) {\n    update({ lookup: v ? { collection: '', displayField: '', valueField: '', projectFields: [] } : null });\n  }\n\n  return (\n    <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n        <Text style={{ fontSize: 12 }}>Editable</Text>\n        <Switch size=\"small\" checked={Boolean(field.isEditable)} onChange={(v) => update({ isEditable: v })} />\n      </div>\n      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n        <Text style={{ fontSize: 12 }}>Mandatory</Text>\n        <Switch size=\"small\" checked={Boolean(field.ismandatory)} onChange={(v) => update({ ismandatory: v })} />\n      </div>\n      {configType === 'filter' && (\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n          <Text style={{ fontSize: 12 }}>Value Input</Text>\n          <Select\n            size=\"small\"\n            value={field.filterInputType ?? 'dropdown'}\n            onChange={(v) => update({ filterInputType: v })}\n            options={FILTER_INPUT_TYPE_OPTIONS}\n            style={{ width: 140 }}\n          />\n        </div>\n      )}\n      {configType === 'filter' && (\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n          <Text style={{ fontSize: 12 }}>Default</Text>\n          <Switch size=\"small\" checked={Boolean(field.isDefaultFilter)} onChange={(v) => update({ isDefaultFilter: v })} />\n        </div>\n      )}\n      {configType === 'filter' && (\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n          <Text style={{ fontSize: 12 }}>Lookup</Text>\n          <Switch size=\"small\" checked={hasLookup} onChange={handleLookupToggle} />\n        </div>\n      )}\n      {configType === 'filter' && (\n        <>\n          <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 360 }}>\n            <Text style={{ fontSize: 12 }}>Group Value Fields</Text>\n            <Select\n              size=\"small\"\n              mode=\"multiple\"\n              allowClear\n              value={Array.isArray(field.filterGroupFields) ? field.filterGroupFields : []}\n              onChange={(values) => update({ filterGroupFields: values })}\n              options={(availableFields ?? []).map((f) => ({\n                label: f.fieldName ?? f.label ?? f.fieldKey,\n                value: f.fieldKey,\n              })).filter((f) => f.value)}\n              placeholder=\"e.g. First Name + Last Name\"\n              style={{ minWidth: 250 }}\n            />\n          </div>\n          {(field.filterGroupFields ?? []).length > 1 && (\n            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n              <Text style={{ fontSize: 12 }}>Group Separator</Text>\n              <Input\n                size=\"small\"\n                value={field.filterGroupSeparator ?? ' '}\n                onChange={(e) => update({ filterGroupSeparator: e.target.value })}\n                placeholder=\"space\"\n                style={{ width: 90 }}\n              />\n            </div>\n          )}\n        </>\n      )}\n      {configType === 'filter' && hasLookup && (\n        <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>\n          <Select\n            size=\"small\"\n            value={field.lookup?.collection || undefined}\n            onChange={onCollectionChange}\n            showSearch\n            placeholder=\"Collection\"\n            style={{ width: 160 }}\n            options={(collections ?? []).map((c) => ({ label: c, value: c }))}\n          />\n          {(collFields ?? []).length > 0 && (\n            <>\n              <Select\n                size=\"small\"\n                value={field.lookup?.valueField || undefined}\n                onChange={(v) => onLookupFieldChange(field.fieldKey, { valueField: v })}\n                showSearch\n                placeholder=\"Value field (ID)\"\n                style={{ width: 160 }}\n                options={(collFields ?? []).map((f) => ({ label: f, value: f }))}\n              />\n              <Input\n                size=\"small\"\n                value={field.lookup?.displayField ?? ''}\n                onChange={(e) => onLookupFieldChange(field.fieldKey, { displayField: e.target.value })}\n                placeholder=\"Display field (e.g. name)\"\n                style={{ width: 180 }}\n              />\n            </>\n          )}\n        </div>\n      )}\n      {isDropdownType && (\n        <>\n          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n            <Text style={{ fontSize: 12 }}>Source</Text>\n            <Select\n              size=\"small\"\n              value={field.dataSource ?? 'module'}\n              onChange={(v) => update({ dataSource: v, groupName: '' })}\n              options={FILTER_DROPDOWN_SOURCES}\n              style={{ width: 170 }}\n            />\n          </div>\n          {(field.dataSource ?? 'module') === 'group' && (\n            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n              <Text style={{ fontSize: 12 }}>Group Name</Text>\n              <Input\n                size=\"small\"\n                value={field.groupName ?? ''}\n                onChange={(e) => update({ groupName: e.target.value })}\n                placeholder=\"e.g. skills\"\n                style={{ width: 120 }}\n              />\n            </div>\n          )}\n        </>\n      )}\n    </div>\n  );\n}\n\n// ─────────────────────────────────────────────────────────────\n// Field row inside config modal\n// ─────────────────────────────────────────────────────────────\nfunction FieldRow({ field, index, configType, moduleKey, onUpdate, onReorder, collections, onFetchCollFields, dragFromRef, availableFields }) {\n  const [expanded, setExpanded] = useState(false);\n  const [labelEdit, setLabelEdit] = useState(false);\n  const [labelVal, setLabelVal] = useState(field.fieldName);\n  const [collFields, setCollFields] = useState([]);\n  const [subfields, setSubfields] = useState([]);\n  const [over, setOver] = useState(false);\n  const [dragging, setDragging] = useState(false);\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      setLabelVal(field.fieldName);\n    });\n  }, [field.fieldName]);\n\n  useEffect(() => {\n    if (!expanded || configType !== 'listView' || !field.fieldKey) return;\n    let cancelled = false;\n    const apiModule = field.apiModule ?? API_MODULE_MAP[moduleKey] ?? moduleKey;\n\n    getArraySubfields(apiModule, field.fieldKey)\n      .then((items) => {\n        if (!cancelled) setSubfields(Array.isArray(items) ? items : []);\n      })\n      .catch(() => {\n        if (!cancelled) setSubfields([]);\n      });\n\n    return () => { cancelled = true; };\n  }, [expanded, configType, field.apiModule, field.fieldKey, moduleKey]);\n\n  function handleDragStart(e) { dragFromRef.current = index; e.dataTransfer.effectAllowed = 'move'; setDragging(true); }\n  function handleDragEnd() { setDragging(false); setOver(false); }\n  function handleDragOver(e) { e.preventDefault(); setOver(true); }\n  function handleDragLeave() { setOver(false); }\n  function handleDrop(e) {\n    e.preventDefault(); setOver(false);\n    if (dragFromRef.current !== null && dragFromRef.current !== index) onReorder(dragFromRef.current, index);\n    dragFromRef.current = null;\n  }\n\n  function update(patch) { onUpdate(index, patch); }\n\n  function commitLabel() {\n    setLabelEdit(false);\n    const trimmed = labelVal.trim();\n    if (trimmed && trimmed !== field.fieldName) update({ fieldName: trimmed });\n    else setLabelVal(field.fieldName);\n  }\n\n  async function onCollectionChange(col) {\n    update({ lookup: { ...field.lookup, collection: col, displayField: '', valueField: '', projectFields: [] } });\n    const f = await onFetchCollFields(col);\n    setCollFields(f);\n  }\n\n  async function onLookupFieldChange(fKey, patch) {\n    update({ lookup: { ...field.lookup, ...patch } });\n    if (patch.valueField) {\n      try { setSubfields(await getArraySubfields(moduleKey, fKey)); } catch { setSubfields([]); }\n    }\n  }\n\n  function addSecondaryField(val) {\n    const arr = field.secondaryFields ?? [];\n    if (!val || arr.includes(val)) return;\n    update({ secondaryFields: [...arr, val] });\n  }\n  function removeSecondaryField(v) { update({ secondaryFields: (field.secondaryFields ?? []).filter((x) => x !== v) }); }\n\n  function addActionButton() {\n    const btns = field.actionButtons ?? [];\n    if (btns.length >= 3) return;\n    update({ actionButtons: [...btns, { name: '', iconUrl: '', iconPath: '', type: 'page', routeUrl: '', permissionKey: '' }] });\n  }\n  function updateActionButton(i, patch) {\n    const btns = [...(field.actionButtons ?? [])];\n    btns[i] = { ...btns[i], ...patch };\n    update({ actionButtons: btns });\n  }\n  function removeActionButton(i) {\n    const btns = [...(field.actionButtons ?? [])];\n    btns.splice(i, 1);\n    update({ actionButtons: btns });\n  }\n\n  return (\n    <>\n      <div\n        draggable\n        onDragStart={handleDragStart} onDragEnd={handleDragEnd}\n        onDragOver={handleDragOver} onDragLeave={handleDragLeave} onDrop={handleDrop}\n        className={`uss-field-row${over ? ' drag-over' : ''}${dragging ? ' dragging' : ''}`}\n        style={{ gridTemplateColumns: '24px 1fr 80px 56px' }}\n      >\n        <span className=\"uss-drag-handle\"><HolderOutlined /></span>\n\n        <span className=\"uss-field-name\">\n          {field.isVirtual && <span className=\"uss-virtual-tag\">virtual</span>}\n          {labelEdit ? (\n            <input autoFocus value={labelVal}\n              onChange={(e) => setLabelVal(e.target.value)} onBlur={commitLabel}\n              onKeyDown={(e) => { if (e.key === 'Enter') commitLabel(); if (e.key === 'Escape') { setLabelEdit(false); setLabelVal(field.fieldName); } }}\n              onClick={(e) => e.stopPropagation()} />\n          ) : (\n            <Tooltip title=\"Double-click to rename\">\n              <span style={{ cursor: 'text', borderBottom: '1px dashed var(--color-border-muted)' }}\n                onDoubleClick={(e) => { e.stopPropagation(); setLabelEdit(true); }}>\n                {field.fieldName}\n              </span>\n            </Tooltip>\n          )}\n          <span className=\"uss-field-key\">{field.fieldKey}</span>\n        </span>\n\n        <span className=\"uss-toggle-cell\">\n          <Switch size=\"small\" checked={field.isVisible} onChange={(v) => update({ isVisible: v })} />\n        </span>\n\n        <span className=\"uss-toggle-cell\">\n          <Button type=\"text\" size=\"small\"\n            icon={expanded ? <DownOutlined /> : <RightOutlined />}\n            onClick={() => setExpanded((p) => !p)}\n            style={{ color: 'var(--color-text-muted)' }} />\n        </span>\n      </div>\n\n      {expanded && (\n        <div className=\"uss-detail-panel\">\n          {configType === 'listView' ? (\n            <ListViewDetails\n              field={field} collections={collections}\n              collFields={collFields} subfields={subfields}\n              onCollectionChange={onCollectionChange}\n              onLookupFieldChange={onLookupFieldChange}\n              addSecondaryField={addSecondaryField}\n              removeSecondaryField={removeSecondaryField}\n              addActionButton={addActionButton}\n              updateActionButton={updateActionButton}\n              removeActionButton={removeActionButton}\n              moduleKey={moduleKey} fieldKey={field.fieldKey}\n              update={update}\n            />\n          ) : (\n            <FormFilterDetails\n              field={field}\n              update={update}\n              configType={configType}\n              collections={collections}\n              collFields={collFields}\n              onCollectionChange={onCollectionChange}\n              onLookupFieldChange={onLookupFieldChange}\n              availableFields={availableFields}\n            />\n          )}\n        </div>\n      )}\n    </>\n  );\n}\n\n// ─────────────────────────────────────────────────────────────\n// Module field config (modal body) — role-scoped\n// ─────────────────────────────────────────────────────────────\nexport default function ModuleFieldConfigEditor({ role, configType }) {\n  const [moduleFields, setModuleFields] = useState({});\n  const [dataVisibilityModes, setDataVisibilityModes] = useState({});\n  const [dataOwnerFields, setDataOwnerFields] = useState({});\n  const [moduleTabs, setModuleTabs] = useState(DEFAULT_MODULE_TABS);\n  const [loading, setLoading] = useState(false);\n  const [saving, setSaving] = useState({});\n  const [activeModule, setActiveModule] = useState('job');\n  const [collections, setCollections] = useState([]);\n  const collFieldsCache = useRef({});\n  const dragFromRef = useRef(null);\n\n  const loadFieldConfig = useCallback(async (currentRole = role, currentConfigType = configType) => {\n    const [rawModules, colls] = await Promise.all([\n      getAvailableModules().catch(() => []),\n      getAvailableCollections(),\n    ]);\n\n    const tabs = normalizeModuleTabs(rawModules);\n    if (!currentConfigType || currentConfigType === 'listView') {\n      const configByModule = await getRoleModuleFieldsWithMeta(currentRole, currentConfigType, tabs);\n      const fields = Object.fromEntries(Object.entries(configByModule).map(([key, value]) => [key, value.fields]));\n      const visibilityModes = Object.fromEntries(Object.entries(configByModule).map(([key, value]) => [key, value.dataVisibilityMode ?? 'all']));\n      const ownerFields = Object.fromEntries(Object.entries(configByModule).map(([key, value]) => [key, value.dataOwnerField ?? 'createdBy']));\n      return { tabs, colls, fields, visibilityModes, ownerFields };\n    }\n    const fields = await getRoleModuleFields(currentRole, currentConfigType, tabs);\n    return { tabs, colls, fields, visibilityModes: {}, ownerFields: {} };\n  }, [configType, role]);\n\n  useEffect(() => {\n    if (!role) return;\n    let cancelled = false;\n    queueMicrotask(() => {\n      setLoading(true);\n      (async () => {\n        try {\n          const { tabs, colls, fields, visibilityModes, ownerFields } = await loadFieldConfig();\n          if (cancelled) return;\n\n          setModuleTabs(tabs);\n          setCollections(colls);\n          setActiveModule((current) => (\n            tabs.some((tab) => tab.key === current) ? current : tabs[0]?.key ?? ''\n          ));\n          setModuleFields(fields);\n          setDataVisibilityModes(visibilityModes ?? {});\n          setDataOwnerFields(ownerFields ?? {});\n        } catch {\n          if (!cancelled) message.error('Failed to load field config');\n        } finally {\n          if (!cancelled) setLoading(false);\n        }\n      })();\n    });\n    return () => { cancelled = true; };\n  }, [loadFieldConfig, role]);\n\n  const fields = moduleFields[activeModule] ?? [];\n\n  function setFields(module, updater) {\n    setModuleFields((prev) => ({\n      ...prev,\n      [module]: typeof updater === 'function' ? updater(prev[module] ?? []) : updater,\n    }));\n  }\n\n  function handleUpdate(idx, patch) {\n    setFields(activeModule, (prev) => prev.map((f, i) => i === idx ? { ...f, ...patch } : f));\n  }\n\n  function handleReorder(from, to) {\n    setFields(activeModule, (prev) => {\n      const arr = [...prev];\n      const [moved] = arr.splice(from, 1);\n      arr.splice(to, 0, moved);\n      return arr.map((f, i) => ({ ...f, order: i }));\n    });\n  }\n\n  async function fetchCollFields(collection) {\n    if (collFieldsCache.current[collection]) return collFieldsCache.current[collection];\n    try {\n      const f = await getCollectionFields(collection);\n      collFieldsCache.current[collection] = f;\n      return f;\n    } catch { return []; }\n  }\n\n  async function handleSave() {\n    const mod = activeModule;\n    setSaving((p) => ({ ...p, [mod]: true }));\n    try {\n      await updateRoleModuleFieldConfig(\n        role, mod, fields, configType, moduleTabs,\n        dataVisibilityModes[mod] ?? 'all',\n        dataOwnerFields[mod] ?? 'createdBy',\n      );\n      message.success('Saved');\n    } catch {\n      message.error('Save failed');\n    } finally {\n      setSaving((p) => ({ ...p, [mod]: false }));\n    }\n  }\n\n  return (\n    <Spin spinning={loading}>\n      <Tabs size=\"small\" activeKey={activeModule} onChange={setActiveModule}\n        items={moduleTabs.map((t) => ({ key: t.key, label: t.label }))} />\n      {(!configType || configType === 'listView') && (\n        <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '4px 0 14px' }}>\n          <Text strong style={{ minWidth: 120 }}>Data Visibility</Text>\n          <Select\n            size=\"small\"\n            style={{ width: 290 }}\n            value={dataVisibilityModes[activeModule] ?? 'all'}\n            onChange={(value) => setDataVisibilityModes((prev) => ({ ...prev, [activeModule]: value }))}\n            options={[\n              { value: 'all', label: 'All Data' },\n              { value: 'reportingManager', label: 'Reporting Manager Wise' },\n              { value: 'self', label: 'My Created Data' },\n            ]}\n          />\n          <Text type=\"secondary\">\n            Reporting Manager Wise shows data owned by the user and users reporting under them.\n          </Text>\n        </div>\n      )}\n      {(!configType || configType === 'listView') && (\n        <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '-4px 0 14px' }}>\n          <Text strong style={{ minWidth: 120 }}>Created By Field</Text>\n          <Input\n            size=\"small\"\n            style={{ width: 290 }}\n            value={dataOwnerFields[activeModule] ?? 'createdBy'}\n            placeholder=\"createdBy\"\n            onChange={(event) => setDataOwnerFields((prev) => ({\n              ...prev,\n              [activeModule]: event.target.value,\n            }))}\n            onBlur={() => setDataOwnerFields((prev) => ({\n              ...prev,\n              [activeModule]: String(prev[activeModule] || '').trim() || 'createdBy',\n            }))}\n          />\n          <Text type=\"secondary\">\n            Defaults to createdBy. Change this only when the module stores its creator/owner user ID in another field.\n          </Text>\n        </div>\n      )}\n      <div className=\"uss-field-header\" style={{ gridTemplateColumns: '24px 1fr 80px 56px' }}>\n        <span /><span>Field</span>\n        <span style={{ textAlign: 'center' }}>Visible</span>\n        <span />\n      </div>\n      <div className=\"uss-field-list\">\n        {fields.length === 0 && !loading && <div className=\"uss-empty\">No fields found.</div>}\n        {fields.map((field, idx) => (\n          <FieldRow key={`${field.fieldKey ?? idx}-${activeModule}`}\n            field={field} index={idx}\n            configType={configType} moduleKey={activeModule}\n            onUpdate={handleUpdate} onReorder={handleReorder}\n            collections={collections} onFetchCollFields={fetchCollFields}\n            dragFromRef={dragFromRef}\n            availableFields={fields}\n          />\n        ))}\n      </div>\n      <div className=\"uss-modal-footer\">\n        <Button type=\"primary\" size=\"small\" loading={saving[activeModule]} onClick={handleSave}>\n          Save {moduleTabs.find((t) => t.key === activeModule)?.label}\n        </Button>\n      </div>\n    </Spin>\n  );\n}\n","// Shared module-option normalization used by every Admin Configurations screen\n// (Form Groups, Detail Groups, Row Actions, Module Action Rules, Templates,\n// Role Configuration) so there is exactly one place that turns whatever shape\n// the backend returns (menus collection docs, modules collection docs, or a\n// bare string) into a consistent { value, label } option list.\n\nexport function moduleTitle(value) {\n  return String(value || '')\n    .replace(/[-_]/g, ' ')\n    .replace(/\\b\\w/g, (c) => c.toUpperCase())\n    .trim();\n}\n\n// The menus collection is read by two screens that normalize it DIFFERENTLY:\n// the Menus tab maps it to snake_case (menu_key/menu_name — see adminCoreApi's\n// normalizeMenu), while the Configurations screens hand the RAW document here.\n// Real documents carry that key in any of three spellings depending on how old\n// the record is and which service wrote it, so all three are accepted. Missing\n// one is not a cosmetic problem: an unrecognised shape returns null and the\n// module is silently DROPPED from the picker, which is how a menu could be\n// listed under Menus and yet be unconfigurable under Actions.\nconst KEY_SPELLINGS = [\n  'menuKey', 'menu_key', 'MENUKEY',\n  'module', 'key', 'moduleKey', 'value', 'apiModule',\n  'name', 'modulename',\n  'menuName', 'menu_name', 'MENUNAME',\n];\n\nconst LABEL_SPELLINGS = [\n  'menuName', 'menu_name', 'MENUNAME',\n  'label', 'moduleLabel', 'moduleName', 'name', 'modulename',\n];\n\nfunction firstSpelling(source, spellings) {\n  for (const key of spellings) {\n    const raw = source?.[key];\n    if (raw === undefined || raw === null) continue;\n    const value = String(raw).trim();\n    if (value) return value;\n  }\n  return undefined;\n}\n\nexport function normalizeModuleOption(module) {\n  if (typeof module === 'string') {\n    return { value: module, label: moduleTitle(module) };\n  }\n  const value = firstSpelling(module, KEY_SPELLINGS);\n  if (!value) return null;\n  return {\n    value,\n    label: firstSpelling(module, LABEL_SPELLINGS) ?? moduleTitle(value),\n  };\n}\n\nexport function normalizeModuleOptions(modules) {\n  const seen = new Set();\n  return (Array.isArray(modules) ? modules : [])\n    .map(normalizeModuleOption)\n    .filter(Boolean)\n    .filter((module) => {\n      if (seen.has(module.value)) return false;\n      seen.add(module.value);\n      return true;\n    });\n}\n","// ─────────────────────────────────────────────────────────────────────────\n// RoleFormPermissionsEditor — Role Configure → Form tab.\n//\n// Unlike ModuleFieldConfigEditor (List View / Filter tabs, an independently\n// seeded flat field list), this tab's structure comes straight from Form\n// Groups: GET /admin/role-form-permissions derives the group/field tree from\n// the module's current Form Groups config and overlays this role's saved\n// grants. Form Groups stays the single source of truth — new/renamed/removed\n// groups and fields sync here automatically, and a role can only ever narrow\n// what's globally enabled, never widen it (enforced again server-side on save\n// via ClampFormPermissionFieldsToGlobal).\n// ─────────────────────────────────────────────────────────────────────────\nimport { useCallback, useEffect, useState } from 'react';\nimport { Button, Empty, Space, Spin, Switch, Tabs, Tooltip, Typography, message } from 'antd';\nimport { LockOutlined } from '@ant-design/icons';\nimport { getAvailableModules, getRoleFormPermissions, saveRoleFormPermissions } from '../../../../services/adminApi';\n\n// Stable reference so the load effect below doesn't re-run every render.\nconst EMPTY_SCOPE = Object.freeze({ clientId: '', region: '' });\nimport { normalizeModuleOptions } from '../../../../utils/moduleOptions';\nimport '../../../../styles/UserSettingsSection.css';\nimport '../../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\nfunction withGroupEnabled(group, enabled) {\n  return {\n    ...group,\n    enabled,\n    fields: group.fields.map((f) => ({ ...f })),\n  };\n}\n\nfunction withGroupEditable(group, editable) {\n  return {\n    ...group,\n    editable,\n    fields: group.fields.map((f) => ({ ...f })),\n  };\n}\n\nexport default function RoleFormPermissionsEditor({ role }) {\n  const [moduleTabs, setModuleTabs]     = useState([]);\n  const [activeModule, setActiveModule] = useState('');\n  const [groups, setGroups]             = useState([]);\n  const [loading, setLoading]           = useState(false);\n  const [saving, setSaving]             = useState(false);\n  // Role form permissions are configured against the module's DEFAULT Form\n  // Groups config. Client-scoped overrides are not selectable here: a role's\n  // field permissions are role-wide, and scoping them per client made the\n  // screen show a different field list than the one being saved. Client-scoped\n  // FORM structure is still configured in Admin → Form Groups.\n  const scope = EMPTY_SCOPE;\n\n  const loadModules = useCallback(async () => {\n    const raw = await getAvailableModules().catch(() => []);\n    return normalizeModuleOptions(raw).map(({ value, label }) => ({ key: value, label }));\n  }, []);\n\n  useEffect(() => {\n    let cancelled = false;\n    queueMicrotask(() => {\n      loadModules().then((tabs) => {\n        if (cancelled) return;\n        setModuleTabs(tabs);\n        setActiveModule((current) => (tabs.some((t) => t.key === current) ? current : tabs[0]?.key ?? ''));\n      });\n    });\n    return () => { cancelled = true; };\n  }, [loadModules]);\n\n  const loadGroups = useCallback(async (module, currentScope) => {\n    if (!role || !module) { setGroups([]); return; }\n    setLoading(true);\n    try {\n      const data = await getRoleFormPermissions(role, module, currentScope);\n      setGroups(Array.isArray(data) ? data : []);\n    } catch {\n      message.error('Failed to load form permissions');\n      setGroups([]);\n    } finally {\n      setLoading(false);\n    }\n  }, [role]);\n\n  useEffect(() => {\n    queueMicrotask(() => { loadGroups(activeModule, scope); });\n  }, [activeModule, scope, loadGroups]);\n\n  function toggleGroup(groupName, enabled) {\n    setGroups((prev) => prev.map((g) => (g.name === groupName ? withGroupEnabled(g, enabled) : g)));\n  }\n\n  function toggleGroupEditable(groupName, editable) {\n    setGroups((prev) => prev.map((g) => (g.name === groupName ? withGroupEditable(g, editable) : g)));\n  }\n\n  function toggleField(groupName, fieldKey, enabled) {\n    setGroups((prev) => prev.map((g) => (\n      g.name !== groupName ? g : {\n        ...g,\n        fields: g.fields.map((f) => (f.field === fieldKey ? { ...f, enabled } : f)),\n      }\n    )));\n  }\n\n  function toggleFieldEditable(groupName, fieldKey, editable) {\n    setGroups((prev) => prev.map((g) => (\n      g.name !== groupName ? g : {\n        ...g,\n        fields: g.fields.map((f) => (f.field === fieldKey ? { ...f, editable } : f)),\n      }\n    )));\n  }\n\n  async function handleSave() {\n    setSaving(true);\n    try {\n      await saveRoleFormPermissions(role, activeModule, groups);\n      message.success('Saved');\n    } catch {\n      message.error('Save failed');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  return (\n    <Spin spinning={loading}>\n      <Tabs\n        size=\"small\"\n        activeKey={activeModule}\n        onChange={setActiveModule}\n        items={moduleTabs.map((t) => ({ key: t.key, label: t.label }))}\n      />\n      <div className=\"fg-expanded-fields\" style={{ marginTop: 8 }}>\n        {groups.length === 0 && !loading && <Empty description=\"No form groups configured for this module.\" />}\n        {groups.map((group) => (\n          <div key={group.name} className=\"fg-field-card\" style={{ flexDirection: 'column', alignItems: 'stretch' }}>\n            <div className=\"fg-field-card-inner\" style={{ padding: '8px 12px' }}>\n              <span className=\"uss-field-name\" style={{ flex: 1 }}>\n                <strong>{group.label}</strong>\n                {group.locked && (\n                  <Tooltip title=\"Every field in this group is disabled globally in Form Groups\">\n                    <LockOutlined style={{ marginLeft: 6, color: 'var(--color-text-muted)' }} />\n                  </Tooltip>\n                )}\n              </span>\n              <Space size={16}>\n                <span className=\"uss-toggle-pair\">\n                  <Text type=\"secondary\" style={{ fontSize: 11, marginRight: 6 }}>Show</Text>\n                  <Switch\n                    size=\"small\"\n                    checked={group.enabled}\n                    disabled={group.locked}\n                    checkedChildren=\"On\"\n                    unCheckedChildren=\"Off\"\n                    onChange={(v) => toggleGroup(group.name, v)}\n                  />\n                </span>\n                <span className=\"uss-toggle-pair\">\n                  <Text type=\"secondary\" style={{ fontSize: 11, marginRight: 6 }}>Editable</Text>\n                  <Switch\n                    size=\"small\"\n                    checked={group.editable !== false}\n                    disabled={group.locked || !group.enabled}\n                    checkedChildren=\"Yes\"\n                    unCheckedChildren=\"No\"\n                    onChange={(v) => toggleGroupEditable(group.name, v)}\n                  />\n                </span>\n              </Space>\n            </div>\n            <div className=\"fg-expanded-fields\" style={{ padding: '4px 12px 10px 28px', opacity: group.enabled ? 1 : 0.5 }}>\n              {group.fields.map((field) => (\n                <div key={field.field} className=\"fg-field-row\" style={{ justifyContent: 'space-between' }}>\n                  <span className=\"fg-field-row-info\">\n                    <span className=\"fg-field-row-label\">{field.label}</span>\n                    <span className=\"fg-field-row-key\">{field.field}</span>\n                    {field.locked && (\n                      <Tooltip title=\"Disabled globally in Form Groups — a role can never re-enable it\">\n                        <LockOutlined style={{ color: 'var(--color-text-muted)' }} />\n                      </Tooltip>\n                    )}\n                  </span>\n                  <Space size={16}>\n                    <span className=\"uss-toggle-pair\">\n                      <Text type=\"secondary\" style={{ fontSize: 11, marginRight: 6 }}>Show</Text>\n                      <Switch\n                        size=\"small\"\n                        checked={field.enabled}\n                        disabled={field.locked || !group.enabled}\n                        checkedChildren=\"On\"\n                        unCheckedChildren=\"Off\"\n                        onChange={(v) => toggleField(group.name, field.field, v)}\n                      />\n                    </span>\n                    <span className=\"uss-toggle-pair\">\n                      <Text type=\"secondary\" style={{ fontSize: 11, marginRight: 6 }}>Editable</Text>\n                      <Switch\n                        size=\"small\"\n                        checked={field.editable !== false}\n                        disabled={field.locked || !group.enabled || !field.enabled || group.editable === false}\n                        checkedChildren=\"Yes\"\n                        unCheckedChildren=\"No\"\n                        onChange={(v) => toggleFieldEditable(group.name, field.field, v)}\n                      />\n                    </span>\n                  </Space>\n                </div>\n              ))}\n            </div>\n          </div>\n        ))}\n      </div>\n      {groups.length > 0 && (\n        <div className=\"uss-modal-footer\">\n          <Button type=\"primary\" size=\"small\" loading={saving} onClick={handleSave}>\n            Save {moduleTabs.find((t) => t.key === activeModule)?.label}\n          </Button>\n        </div>\n      )}\n      <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 8 }}>\n        Groups and fields are read from Form Groups. <b>Show</b> hides a group/field from the\n        add &amp; edit form; <b>Editable</b> keeps it visible but read-only (disabled). Everything\n        is shown and editable by default. A role can only ever narrow what Form Groups already\n        enables — never re-enable something disabled globally.\n      </Text>\n    </Spin>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n  Alert, Button, Popconfirm, Select, Space, Spin, Switch, Table, Tag, Typography, message,\n} from 'antd';\nimport { ReloadOutlined, SaveOutlined, UndoOutlined } from '@ant-design/icons';\nimport {\n  createRowActionConfig,\n  deleteRowActionConfig,\n  getActionConfigModules,\n  getRowActionConfigs,\n  updateRowActionConfig,\n} from '../../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../../utils/moduleOptions';\n\nconst { Text, Title } = Typography;\n\n// Composite key for a child action so two groups can share a child key.\nconst childId = (parentKey, key) => `${parentKey}::${key}`;\n\n// Mirrors the backend's detailVariantBase (models/rowActionConfig.go): a\n// module's DETAIL surface can be served under its own config key, and a role\n// override authored on the base module now also applies there (subtractively).\n// Used only to TELL the admin how far this override reaches — the resolution\n// itself is entirely backend-side.\nconst norm = (value) => String(value ?? '').trim().toLowerCase();\nfunction detailVariantBase(module) {\n  const key = norm(module);\n  for (const suffix of ['details', 'detail']) {\n    if (key.endsWith(suffix)) {\n      const base = key.slice(0, -suffix.length);\n      if (base) return base;\n    }\n  }\n  return '';\n}\n// Two keys are the same module family if one is a detail variant of the other,\n// tolerating the singular/plural spellings the backend's aliases also accept.\nfunction sameFamily(a, b) {\n  const [x, y] = [norm(a), norm(b)];\n  const singular = (v) => v.replace(/s$/, '');\n  return singular(detailVariantBase(x)) === singular(y)\n    || singular(detailVariantBase(y)) === singular(x);\n}\n\nfunction enabledSetFromActions(actions) {\n  const set = new Set();\n  (actions ?? []).forEach((a) => {\n    set.add(a.key);\n    (a.children ?? []).forEach((c) => set.add(childId(a.key, c.key)));\n  });\n  return set;\n}\n\n/**\n * Per-role row-action configuration, embedded in the \"Configure User Type\"\n * modal (Admin → User Types → Config → Actions).\n *\n * The action LIBRARY (what each action does) lives in the roleId-0 default\n * config, managed in Configurations → Actions. This editor only decides which\n * of those actions a specific role gets: saving writes a roleId-scoped\n * rowActionConfig containing the enabled subset — the same doc the runtime\n * (models.GetRowActions) already prefers over the roleId-0 fallback.\n */\nexport default function RoleActionsEditor({ role }) {\n  const roleId = Number(role?.roleId ?? 0);\n  const [modules, setModules] = useState([]);\n  const [selectedModule, setSelectedModule] = useState('');\n  const [configs, setConfigs] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [saving, setSaving] = useState(false);\n  const [enabled, setEnabled] = useState(new Set());\n  const [dirty, setDirty] = useState(false);\n  const [allModuleKeys, setAllModuleKeys] = useState([]);\n\n  // Sibling surfaces this override also reaches (see sameFamily).\n  const familyKeys = useMemo(\n    () => allModuleKeys.filter((key) => sameFamily(key, selectedModule)),\n    [allModuleKeys, selectedModule],\n  );\n\n  useEffect(() => {\n    getActionConfigModules()\n      .then((mods) => {\n        const unique = normalizeModuleOptions(mods).map((m) => m.value);\n        setModules(unique);\n        setSelectedModule((current) => current || unique[0] || '');\n      })\n      .catch(() => setModules([]));\n    // Every configured module key, used only to show which sibling surfaces\n    // (e.g. a detail-view config) this role override will also cover.\n    getRowActionConfigs()\n      .then((all) => setAllModuleKeys([...new Set(\n        (Array.isArray(all) ? all : []).map((c) => String(c?.module ?? '').trim()).filter(Boolean),\n      )]))\n      .catch(() => setAllModuleKeys([]));\n  }, []);\n\n  const loadConfigs = useCallback(async () => {\n    if (!selectedModule) return;\n    setLoading(true);\n    try {\n      const data = await getRowActionConfigs(selectedModule);\n      setConfigs(Array.isArray(data) ? data : []);\n    } catch (e) {\n      message.error(e.message);\n      setConfigs([]);\n    } finally {\n      setLoading(false);\n    }\n  }, [selectedModule]);\n\n  useEffect(() => { queueMicrotask(() => { loadConfigs(); }); }, [loadConfigs]);\n\n  // Prefer the exact module key over alias variants (job/jobs), same as\n  // RowActionsSection, so we never edit a legacy duplicate.\n  const pickConfig = useCallback((rid) => {\n    const forRole = configs.filter((c) => c.roleId === rid);\n    return forRole.find((c) => c.module === selectedModule) ?? forRole[0] ?? null;\n  }, [configs, selectedModule]);\n\n  const baseConfig = useMemo(() => pickConfig(0), [pickConfig]);\n  const roleConfig = useMemo(() => pickConfig(roleId), [pickConfig, roleId]);\n\n  // The library shown is the default (All Roles) config; if only a role\n  // config exists, fall back to it so its actions stay visible/editable.\n  const libraryActions = useMemo(\n    () => baseConfig?.rowActions ?? roleConfig?.rowActions ?? [],\n    [baseConfig, roleConfig],\n  );\n\n  // No role override yet → the role inherits everything from the default.\n  useEffect(() => {\n    queueMicrotask(() => {\n      setEnabled(enabledSetFromActions(roleConfig ? roleConfig.rowActions : libraryActions));\n      setDirty(false);\n    });\n  }, [roleConfig, libraryActions]);\n\n  function toggle(id, on, childIds = []) {\n    setEnabled((prev) => {\n      const next = new Set(prev);\n      if (on) {\n        next.add(id);\n        childIds.forEach((c) => next.add(c));\n      } else {\n        next.delete(id);\n        childIds.forEach((c) => next.delete(c));\n      }\n      return next;\n    });\n    setDirty(true);\n  }\n\n  async function handleSave() {\n    const rowActions = libraryActions\n      .filter((a) => enabled.has(a.key))\n      .map((a) => (a.children?.length\n        ? { ...a, children: a.children.filter((c) => enabled.has(childId(a.key, c.key))) }\n        : a));\n    setSaving(true);\n    try {\n      if (roleConfig) {\n        await updateRowActionConfig(roleConfig.id ?? roleConfig._id, rowActions);\n      } else {\n        await createRowActionConfig({ module: selectedModule, roleId, rowActions });\n      }\n      message.success(`Actions saved for ${role?.roleName ?? 'role'}`);\n      await loadConfigs();\n    } catch (e) {\n      message.error(e.message);\n      if (String(e.message ?? '').toLowerCase().includes('already exists')) loadConfigs();\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  async function handleResetToDefault() {\n    if (!roleConfig) return;\n    setSaving(true);\n    try {\n      await deleteRowActionConfig(roleConfig.id ?? roleConfig._id);\n      message.success('Role override removed — this role now inherits the default actions');\n      await loadConfigs();\n    } catch (e) {\n      message.error(e.message);\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  const columns = [\n    { title: 'Action', key: 'identity', render: (_, a) => (\n      <Space direction=\"vertical\" size={0}>\n        <Text strong>{a.label || a.key}</Text>\n        <Text type=\"secondary\" code>{a.key}</Text>\n      </Space>\n    ) },\n    { title: 'Behaviour', key: 'behaviour', width: 220, render: (_, a) => (\n      <Space direction=\"vertical\" size={0}>\n        <Tag color=\"blue\" style={{ width: 'fit-content' }}>{a.actionType}</Tag>\n        <Text type=\"secondary\" ellipsis={{ tooltip: true }} style={{ maxWidth: 190 }}>\n          {a.actionType === 'group'\n            ? `${(a.children ?? []).length} child action(s)`\n            : (a.popupKey || a.routeTemplate || a.apiPath || a.copyField || a.documentField || '—')}\n        </Text>\n      </Space>\n    ) },\n    { title: 'Enabled for this role', key: 'enabled', width: 160, render: (_, a) => (\n      <Switch\n        checked={enabled.has(a.key)}\n        onChange={(on) => toggle(a.key, on, (a.children ?? []).map((c) => childId(a.key, c.key)))}\n      />\n    ) },\n  ];\n\n  const childColumns = (parent) => [\n    { title: 'Child Action', key: 'identity', render: (_, c) => (\n      <Space direction=\"vertical\" size={0}>\n        <Text strong>{c.label || c.key}</Text>\n        <Text type=\"secondary\" code>{c.key}</Text>\n      </Space>\n    ) },\n    { title: 'Behaviour', key: 'behaviour', width: 220, render: (_, c) => (\n      <Text type=\"secondary\">{c.popupKey || c.routeTemplate || c.apiPath || c.actionType}</Text>\n    ) },\n    { title: 'Enabled', key: 'enabled', width: 160, render: (_, c) => (\n      <Switch\n        disabled={!enabled.has(parent.key)}\n        checked={enabled.has(childId(parent.key, c.key))}\n        onChange={(on) => toggle(childId(parent.key, c.key), on)}\n      />\n    ) },\n  ];\n\n  return (\n    <section className=\"admin-editor\">\n      <div className=\"admin-section-head\">\n        <div>\n          <Title level={4}>Role Actions</Title>\n          <Text type=\"secondary\">\n            Enable or disable row actions for {role?.roleName ?? 'this role'}. The action\n            library itself is managed in Configurations → Actions.\n          </Text>\n        </div>\n        <Space>\n          {roleConfig && (\n            <Popconfirm\n              title=\"Remove this role's override and inherit the default actions?\"\n              okText=\"Reset\"\n              okType=\"danger\"\n              onConfirm={handleResetToDefault}\n            >\n              <Button icon={<UndoOutlined />} loading={saving}>Reset to Default</Button>\n            </Popconfirm>\n          )}\n          <Button icon={<ReloadOutlined />} onClick={loadConfigs} loading={loading}>Reload</Button>\n          <Button\n            type=\"primary\"\n            icon={<SaveOutlined />}\n            loading={saving}\n            disabled={!dirty || !selectedModule}\n            onClick={handleSave}\n          >\n            Save\n          </Button>\n        </Space>\n      </div>\n\n      <Space style={{ marginBottom: 12 }} wrap>\n        <label>\n          <Text type=\"secondary\" style={{ display: 'block', marginBottom: 4, fontSize: 12 }}>Module</Text>\n          <Select\n            showSearch\n            optionFilterProp=\"label\"\n            style={{ width: 220 }}\n            mode=\"tags\"\n            maxCount={1}\n            value={selectedModule ? [selectedModule] : []}\n            placeholder=\"Pick or type a module key\"\n            onChange={(v) => setSelectedModule(String(v[v.length - 1] ?? '').trim())}\n            options={modules.map((m) => ({ value: m, label: m }))}\n          />\n        </label>\n        <div style={{ paddingTop: 20 }}>\n          {roleConfig\n            ? <Tag color=\"green\">Role override active</Tag>\n            : <Tag color=\"orange\">Inheriting default (All Roles) — Save creates an override</Tag>}\n          {dirty && <Text type=\"warning\" style={{ marginLeft: 8 }}>Unsaved changes</Text>}\n        </div>\n      </Space>\n\n      {familyKeys.length > 0 && (\n        <Alert\n          type=\"info\"\n          showIcon\n          style={{ marginBottom: 12 }}\n          message={`This override also applies to: ${familyKeys.join(', ')}`}\n          description={\n            'Those surfaces (e.g. the detail view) keep their own extra actions — only the '\n            + 'ones you turn off here are hidden from them.'\n          }\n        />\n      )}\n\n      {!loading && !libraryActions.length && (\n        <Alert\n          type=\"info\"\n          showIcon\n          style={{ marginBottom: 12 }}\n          message=\"No actions configured for this module yet.\"\n          description=\"Define the actions first in Configurations → Actions (Action library), then enable them per role here.\"\n        />\n      )}\n\n      <Spin spinning={loading}>\n        <Table\n          dataSource={libraryActions.map((a, i) => ({ ...a, _rowKey: a.key || i }))}\n          rowKey=\"_rowKey\"\n          columns={columns}\n          pagination={false}\n          size=\"small\"\n          expandable={{\n            rowExpandable: (r) => r.actionType === 'group' && (r.children ?? []).length > 0,\n            expandedRowRender: (r) => (\n              <Table\n                dataSource={(r.children ?? []).map((c, i) => ({ ...c, _rowKey: c.key || i }))}\n                rowKey=\"_rowKey\"\n                columns={childColumns(r)}\n                pagination={false}\n                size=\"small\"\n              />\n            ),\n          }}\n        />\n      </Spin>\n    </section>\n  );\n}\n","// Admin-facing option lists for the condition operators implemented by\n// `conditionMatches` in conditionalFieldLabel.js. They live next to the matcher\n// on purpose: every admin screen that authors a condition (Form Groups showIf /\n// labelWhen, Detail Groups conditional label) reads from here, so adding an\n// operator to the matcher and forgetting to offer it — or offering one the\n// matcher does not implement — cannot happen silently.\nexport const CONDITION_OPERATORS = [\n  { label: 'Equals (=)', value: 'eq' },\n  { label: 'Not equals (≠)', value: 'neq' },\n  { label: 'Has any value', value: 'truthy' },\n  { label: 'Is empty', value: 'falsy' },\n  { label: 'Is one of (comma-separated)', value: 'in' },\n  { label: 'Is not one of (comma-separated)', value: 'notIn' },\n  { label: 'Has at least one row (addRow group)', value: 'notEmpty' },\n];\n\n// Operators that carry a comparison value; the rest are unary, so the admin\n// screens hide the Value input for them and the save path drops any stale one.\nexport const CONDITION_VALUE_OPERATORS = ['eq', 'neq', 'in', 'notIn'];\n\nexport const operatorNeedsValue = (operator) => CONDITION_VALUE_OPERATORS.includes(operator ?? 'eq');\n","// ── Unique-value validation config (pure logic) ───────────────────────────────\n//\n// The admin authors \"this field must be unique\" from Form Groups → Field →\n// Validations. It is stored as an ordinary entry in the field's existing\n// `validations` array, so nothing about persistence, reordering or duplicating\n// fields had to change:\n//\n//   { type: 'unique', message: 'Email already present',\n//     value: { collectionField: 'email', normalizer: 'email',\n//              skipBlank: true, validateOn: 'blur' } }\n//\n// The rule's `value` is an OBJECT rather than a scalar. That works because\n// buildFieldPayload only coerces `rule.value` with Number() when the validation\n// type declares `valueType: 'number'` — an object valueType therefore rides\n// through a save untouched — and initFieldValues loads it back with\n// `v.value ?? ''`, which passes objects through unchanged.\n//\n// This module holds every piece of logic that does not need React, because\n// FormGroupsSection.jsx imports AddFormV1 → react-pdf, which cannot be imported\n// under jsdom (no DOMMatrix). Keeping the rules here is what makes them\n// testable at all.\n//\n// NOTHING here knows about any particular module, collection or field name.\n\nexport const UNIQUE_VALIDATION_TYPE = 'unique';\n\n// Normalizers must match the backend's `models/uniqueValidation.go` names\n// exactly — the admin picks the token, the server implements it. A value the\n// server does not recognise falls back to `exact` there, so an unknown token\n// can never widen a uniqueness check into \"no check\".\nexport const UNIQUE_NORMALIZERS = [\n  { label: 'Exact (compare as stored)', value: 'exact' },\n  { label: 'Trim whitespace',           value: 'trim' },\n  { label: 'Trim + lowercase',          value: 'trimLower' },\n  { label: 'Email (trim + lowercase)',  value: 'email' },\n  { label: 'Digits only (phone/ID)',    value: 'digitsOnly' },\n];\n\n// Blur is the recommended trigger: it gives the admin's error message the best\n// chance of being seen next to the field the user just typed in. \"Submit only\"\n// exists for fields where a per-blur round trip is unwanted. Submit-time\n// enforcement happens for BOTH — the trigger only controls the preflight probe.\nexport const UNIQUE_VALIDATION_TRIGGERS = [\n  { label: 'On blur (recommended)', value: 'blur' },\n  { label: 'On submit only',        value: 'submit' },\n];\n\n// Defaults deliberately mirror what the RUNTIME falls back to when a stored\n// config omits the key (components/form/uniqueFieldValidation.js): 'trim' and\n// 'blur'. If the editor defaulted to anything else it would DISPLAY a setting\n// the form does not actually apply, and then bake that lie in on the next save.\nexport const DEFAULT_UNIQUE_NORMALIZER = 'trim';\nexport const DEFAULT_UNIQUE_TRIGGER = 'blur';\n\n// How the constraint is applied. \"field\" is the default and what almost every\n// rule should use: the check reads the field it names, and the record stores\n// nothing extra.\n//\n// \"index\" additionally keeps a tidied-up copy of the value in a hidden __uniq\n// section of the record and relies on a database rule over it. That copy is a\n// SECOND place the same value lives, kept in step by a handful of write paths —\n// and one that forgets leaves the database enforcing a value the record no\n// longer has. It buys one thing only: protection against two people creating\n// the identical value in the same instant. Off unless that is a real risk, and\n// it needs cmd/ensure-unique-indexes to have created the index.\nexport const UNIQUE_ENFORCEMENT_MODES = [\n  { label: 'Look at the field (recommended)', value: 'field' },\n  { label: 'Also keep a hidden copy',         value: 'index' },\n];\nexport const DEFAULT_UNIQUE_ENFORCEMENT = 'field';\n\nconst ACCEPTED_ENFORCEMENT = new Set(UNIQUE_ENFORCEMENT_MODES.map((m) => m.value));\n\n// Triggers the editor OFFERS are blur and submit. The set it ACCEPTS is wider:\n// the runtime also understands 'change', so a config carrying it must survive a\n// save from this screen untouched rather than being quietly downgraded to blur.\nconst ACCEPTED_TRIGGERS = new Set(['blur', 'submit', 'change']);\n\n// v1 compares a single scalar against a single stored scalar. Anything holding\n// a list (or rich markup, whose \"equality\" is meaningless to a user) is out of\n// scope until the backend grows an element-wise comparison, and the editor must\n// say so rather than saving a rule that would silently never match.\nconst UNSUPPORTED_FIELD_TYPES = new Set(['file', 'text-editor', 'checkbox']);\n\nexport const UNIQUE_SCALAR_ONLY_HINT = 'Uniqueness currently supports scalar values only —'\n  + ' a single value compared against a single stored value.';\n\n// uniqueFieldTypeSupport reports whether a unique rule may be configured on the\n// field currently being edited, and WHY not when it may not. `field` is the raw\n// field-editor row (post initFieldValues), not the saved document.\nexport function uniqueFieldTypeSupport(field = {}) {\n  const type = String(field.type ?? 'text');\n  const deny = (reason) => ({ supported: false, reason: `${reason} ${UNIQUE_SCALAR_ONLY_HINT}` });\n\n  if (UNSUPPORTED_FIELD_TYPES.has(type)) {\n    const label = type === 'text-editor' ? 'Rich text' : type === 'file' ? 'File' : 'Checkbox';\n    return deny(`${label} fields cannot be checked for uniqueness.`);\n  }\n  if (type === 'tagify') return deny('Tag fields store a list of values.');\n  if (field.multiSelect) return deny('Multi-select fields store a list of values.');\n  if (field.multiple) return deny('Multi-value fields store a list of values.');\n  if (field.addRow) return deny('Repeatable fields store one value per row.');\n  if (Array.isArray(field.subFields) && field.subFields.length) {\n    return deny('Fields with sub-fields store one object per row.');\n  }\n  if (field.dataType === 'array') return deny('Fields sent as an array store a list of values.');\n  return { supported: true, reason: '' };\n}\n\n// ── Stored-path safety ────────────────────────────────────────────────────────\n//\n// `collectionField` becomes a Mongo query key server-side. A dotted path is\n// legitimate and useful (`passport.passportNumber`), but `$`-prefixed segments\n// would be read as operators, a NUL byte can truncate a key, and an empty\n// segment (`a..b`, `.b`, `a.`) is not a path at all. Reject all three here so a\n// malformed path is never written to config in the first place — the backend\n// validates independently, this is only the earliest, clearest failure point.\nconst SEGMENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;\n\nexport function collectionFieldPathError(path) {\n  const raw = String(path ?? '');\n  if (!raw.trim()) return 'Collection field is required';\n  if (raw !== raw.trim()) return 'Remove the surrounding spaces';\n  if (raw.includes('\\0')) return 'Path contains a null byte';\n  if (raw.includes('$')) return 'Path may not contain \"$\"';\n  const segments = raw.split('.');\n  for (const segment of segments) {\n    if (!segment) return 'Path has an empty segment — use a.b, not a..b';\n    if (!SEGMENT_RE.test(segment)) {\n      return `Invalid path segment \"${segment}\" — letters, digits, _ and - only`;\n    }\n  }\n  return '';\n}\n\nexport function isSafeCollectionFieldPath(path) {\n  return collectionFieldPathError(path) === '';\n}\n\n// ── Config shaping ────────────────────────────────────────────────────────────\n\n// defaultCollectionField mirrors the backend's resolution order for \"which key\n// does this form field actually land on in the document\": payloadKey wins when\n// present (it IS the stored key), otherwise the field key.\nexport function defaultCollectionField(field = {}) {\n  const payloadKey = String(field.payloadKey ?? '').trim();\n  if (payloadKey) return payloadKey;\n  return String(field.field ?? '').trim();\n}\n\nexport function defaultUniqueConfig(field = {}) {\n  return {\n    collectionField: defaultCollectionField(field),\n    normalizer: DEFAULT_UNIQUE_NORMALIZER,\n    // Blank optional values must never conflict with one another — two records\n    // that both left the field empty are not duplicates. Default ON.\n    skipBlank: true,\n    validateOn: DEFAULT_UNIQUE_TRIGGER,\n    enforcement: DEFAULT_UNIQUE_ENFORCEMENT,\n  };\n}\n\nconst KNOWN_NORMALIZERS = new Set(UNIQUE_NORMALIZERS.map((n) => n.value));\n\n// normalizeUniqueConfig fills in the defaults for a stored (or half-typed)\n// config WITHOUT dropping anything it does not recognise. Unknown keys are\n// preserved verbatim so a config seeded by a backend migration — or written by\n// a newer version of this screen — survives an unrelated save by an older\n// client. That property is what makes load → edit → reorder → duplicate → save\n// lossless.\nexport function normalizeUniqueConfig(raw, field = {}) {\n  const source = raw && typeof raw === 'object' && !Array.isArray(raw) ? raw : {};\n  const defaults = defaultUniqueConfig(field);\n  const collectionField = String(source.collectionField ?? '').trim() || defaults.collectionField;\n  const normalizer = KNOWN_NORMALIZERS.has(source.normalizer) ? source.normalizer : defaults.normalizer;\n  const validateOn = ACCEPTED_TRIGGERS.has(source.validateOn) ? source.validateOn : defaults.validateOn;\n  // skipBlank is a genuine tri-state on read: absent means \"never configured\",\n  // which takes the safe default (true). An explicit `false` must survive —\n  // this is the same trap the Go side guards with a *bool.\n  const skipBlank = source.skipBlank === undefined || source.skipBlank === null\n    ? defaults.skipBlank\n    : Boolean(source.skipBlank);\n  // An unrecognised value falls back to \"field\" rather than being preserved:\n  // this key decides whether a mirror gets written into every record, and\n  // guessing at a typo's intent would start writing one nobody asked for.\n  const enforcement = ACCEPTED_ENFORCEMENT.has(source.enforcement)\n    ? source.enforcement\n    : defaults.enforcement;\n  const out = { ...source, collectionField, normalizer, skipBlank, validateOn, enforcement };\n  const alsoCheck = normalizeAlsoCheck(source.alsoCheck);\n  // Only materialised when the admin actually configured one, so every rule\n  // saved before this feature existed round-trips byte-identical.\n  if (alsoCheck.length) out.alsoCheck = alsoCheck;\n  else delete out.alsoCheck;\n  return out;\n}\n\n// ── Additional collections (alsoCheck) ────────────────────────────────────────\n//\n// \"Unique\" is not always a property of one collection. When a value is\n// PROVISIONED out of a record into somewhere else — a contact row that becomes a\n// login, a code mirrored into a master list — the value is only really free when\n// BOTH are clear, and checking just the record's own collection would hand out a\n// value that the second collection then rejects (or silently duplicates).\n//\n//   alsoCheck: [{ module | collection, collectionField, normalizer?, message?,\n//                 excludeFrom: { path, matchField } }]\n//\n// `module` is preferred and resolved to a collection through the module registry\n// SERVER-SIDE; `collection` is the escape hatch for a collection that is not a\n// registered module, and is accepted only from this admin config — never from a\n// request (the preflight endpoint rejects those keys outright).\n//\n// excludeFrom is the part that decides whether the feature is usable at all: see\n// alsoCheckExclusionHint.\nexport const ALSO_CHECK_EXCLUSION_HINT = 'Path is read on the record being edited'\n  + ' (array paths allowed, e.g. recruiters.accountUserId); Match field is the key those'\n  + ' ids are stored under in the other collection (blank = _id). Without it, every record'\n  + ' that has already provisioned a value there becomes impossible to edit.';\n\nexport function defaultAlsoCheckEntry() {\n  return { module: '', collection: '', collectionField: '', normalizer: '', message: '', excludeFrom: { path: '', matchField: '' } };\n}\n\nfunction normalizeAlsoCheckEntry(raw) {\n  const source = raw && typeof raw === 'object' && !Array.isArray(raw) ? raw : {};\n  const excludeSource = source.excludeFrom && typeof source.excludeFrom === 'object' ? source.excludeFrom : {};\n  const entry = {\n    ...source,\n    module: String(source.module ?? '').trim(),\n    collection: String(source.collection ?? '').trim(),\n    collectionField: String(source.collectionField ?? '').trim(),\n    normalizer: String(source.normalizer ?? '').trim(),\n    message: String(source.message ?? '').trim(),\n  };\n  const path = String(excludeSource.path ?? '').trim();\n  const matchField = String(excludeSource.matchField ?? '').trim();\n  if (path) entry.excludeFrom = { ...excludeSource, path, matchField };\n  else delete entry.excludeFrom;\n  return entry;\n}\n\nexport function normalizeAlsoCheck(raw) {\n  if (!Array.isArray(raw)) return [];\n  return raw\n    .map(normalizeAlsoCheckEntry)\n    // A row naming no target is an empty row left in the editor, not config.\n    .filter((entry) => entry.module || entry.collection);\n}\n\n// alsoCheckEntryErrors returns every reason ONE additional-collection row may\n// not be saved. A bad row is rejected here rather than saved and then silently\n// dropped by the backend resolver, where nobody would ever see it.\nexport function alsoCheckEntryErrors(entry = {}) {\n  const errors = [];\n  const moduleName = String(entry.module ?? '').trim();\n  const collection = String(entry.collection ?? '').trim();\n  if (!moduleName && !collection) {\n    errors.push('Name a module (preferred) or a collection to also check.');\n  }\n  if (collection && !moduleName) {\n    // A raw collection name is a bare identifier — never a path, never an operator.\n    if (collection.includes('.')) errors.push('Collection must be a single name, not a path.');\n    else if (collectionFieldPathError(collection)) errors.push(`Collection: ${collectionFieldPathError(collection)}`);\n  }\n  const storedField = String(entry.collectionField ?? '').trim();\n  if (storedField && collectionFieldPathError(storedField)) {\n    errors.push(`Field in that collection: ${collectionFieldPathError(storedField)}`);\n  }\n  const path = String(entry.excludeFrom?.path ?? '').trim();\n  if (path && collectionFieldPathError(path)) errors.push(`Exclusion path: ${collectionFieldPathError(path)}`);\n  const matchField = String(entry.excludeFrom?.matchField ?? '').trim();\n  if (matchField && collectionFieldPathError(matchField)) {\n    errors.push(`Exclusion match field: ${collectionFieldPathError(matchField)}`);\n  }\n  return errors;\n}\n\n// uniqueRuleErrors returns every reason the given rule may not be saved.\n// Returns [] when the rule is valid — or when it is not a unique rule at all.\nexport function uniqueRuleErrors(rule, field = {}) {\n  if (!rule || rule.type !== UNIQUE_VALIDATION_TYPE) return [];\n  const errors = [];\n  const support = uniqueFieldTypeSupport(field);\n  if (!support.supported) errors.push(support.reason);\n  if (!String(rule.message ?? '').trim()) {\n    errors.push('An error message is required — it is what the user sees.');\n  }\n  const config = rule.value && typeof rule.value === 'object' ? rule.value : {};\n  const pathError = collectionFieldPathError(config.collectionField);\n  if (pathError) errors.push(pathError);\n  (Array.isArray(config.alsoCheck) ? config.alsoCheck : []).forEach((entry, i) => {\n    // An untouched row the admin added and abandoned is not an error — it is\n    // dropped by normalizeAlsoCheck. Only a row that says SOMETHING is validated.\n    const touched = Object.entries(entry ?? {}).some(([key, value]) => (\n      key === 'excludeFrom'\n        ? Boolean(String(value?.path ?? '').trim() || String(value?.matchField ?? '').trim())\n        : Boolean(String(value ?? '').trim())\n    ));\n    if (!touched) return;\n    alsoCheckEntryErrors(entry).forEach((err) => errors.push(`Also check #${i + 1}: ${err}`));\n  });\n  return errors;\n}\n\nexport function isUniqueRule(rule) {\n  return Boolean(rule) && rule.type === UNIQUE_VALIDATION_TYPE;\n}\n\n// hasUniqueValidation answers \"does this SAVED field carry a unique rule\" — used\n// by Detail Groups to render a read-only tag. It must never mutate anything.\nexport function hasUniqueValidation(field) {\n  return (field?.validations ?? []).some(isUniqueRule);\n}\n\nexport function uniqueValidationOf(field) {\n  return (field?.validations ?? []).find(isUniqueRule) ?? null;\n}\n\n// ── Resolved target ───────────────────────────────────────────────────────────\n//\n// The admin never types a collection name. The target MODULE is the group's\n// Target Collection (`group.moduleName`) when set — the fields of such a group\n// are written to that module through moduleWrites, so its collection, not the\n// primary module's, is where the value must be unique — otherwise the primary\n// module the group belongs to. The COLLECTION is then looked up from module\n// configuration (adminApi's module registry), never derived from user input.\nexport function resolveUniqueTarget({\n  primaryModule = '',\n  groupTargetModule = '',\n  field = {},\n  config = {},\n  collectionForModule,\n} = {}) {\n  const module = String(groupTargetModule ?? '').trim() || String(primaryModule ?? '').trim();\n  const collection = typeof collectionForModule === 'function'\n    ? String(collectionForModule(module) ?? '').trim()\n    : '';\n  const formField = String(field.field ?? '').trim();\n  const storedField = String(config.collectionField ?? '').trim() || defaultCollectionField(field);\n  return {\n    module,\n    // Blank collection = the registry has not been loaded (or the module is not\n    // registered). The UI shows an explicit \"resolved on the server\" note in\n    // that case rather than inventing a name.\n    collection,\n    formField,\n    storedField,\n    // True when the group writes somewhere other than the module being edited,\n    // which is worth calling out in the UI — it is the surprising case.\n    isCrossModule: Boolean(String(groupTargetModule ?? '').trim())\n      && String(groupTargetModule).trim() !== String(primaryModule ?? '').trim(),\n  };\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { Alert, Button, Input, Modal, Typography, message } from 'antd';\nimport { SafetyCertificateOutlined } from '@ant-design/icons';\nimport { applyConfigDefault, requestConfigOtp } from '../../services/adminApi';\n\nconst { Paragraph, Text } = Typography;\n\n// OtpGateModal gates a sensitive admin-config action behind an emailed OTP.\n// On open it requests a code (scope + action), lets the user enter it, and on\n// confirm verifies + performs the action server-side in one call. The parent is\n// notified via onVerified(result) so it can refresh, and via onCancel to close.\n//\n//   scope:   'formGroups' | 'detailConfig'\n//   action:  'reset' | 'save' | 'restore'\nexport default function OtpGateModal({\n  open,\n  scope,\n  action,\n  title,\n  description,\n  confirmLabel = 'Confirm',\n  danger = false,\n  onCancel,\n  onVerified,\n  // onConfirm(otp): when provided, called instead of the built-in\n  // applyConfigDefault — lets a caller run its OWN OTP-gated save (e.g. Default\n  // Fields) while reusing the same request-OTP + code-entry UX. Must return a\n  // promise; its resolved value is passed to onVerified.\n  onConfirm,\n}) {\n  const [otp, setOtp] = useState('');\n  const [sentTo, setSentTo] = useState('');\n  const [sending, setSending] = useState(false);\n  const [verifying, setVerifying] = useState(false);\n  const [error, setError] = useState('');\n  const requestedRef = useRef(false);\n\n  async function sendOtp() {\n    if (!scope || !action) return;\n    setSending(true);\n    setError('');\n    try {\n      const res = await requestConfigOtp(scope, action);\n      setSentTo(res?.data?.email || res?.email || 'the registered approver');\n      message.success('OTP sent');\n    } catch (e) {\n      setError(e?.message || 'Could not send the OTP');\n    } finally {\n      setSending(false);\n    }\n  }\n\n  // Request a fresh code once each time the modal opens; reset state on close so\n  // the next open starts clean.\n  useEffect(() => {\n    if (open && !requestedRef.current) {\n      requestedRef.current = true;\n      setOtp('');\n      setError('');\n      setSentTo('');\n      sendOtp();\n    }\n    if (!open) requestedRef.current = false;\n  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  async function confirm() {\n    if (!otp.trim()) {\n      setError('Enter the OTP sent to your email');\n      return;\n    }\n    setVerifying(true);\n    setError('');\n    try {\n      const res = onConfirm\n        ? await onConfirm(otp.trim())\n        : await applyConfigDefault(scope, action, otp.trim());\n      message.success(res?.data?.message || res?.message || 'Done');\n      onVerified?.(res);\n    } catch (e) {\n      setError(e?.message || 'Verification failed — check the code and try again');\n    } finally {\n      setVerifying(false);\n    }\n  }\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onCancel}\n      title={<span><SafetyCertificateOutlined /> {title}</span>}\n      destroyOnClose\n      maskClosable={!verifying}\n      footer={[\n        <Button key=\"cancel\" onClick={onCancel} disabled={verifying}>Cancel</Button>,\n        <Button key=\"ok\" type=\"primary\" danger={danger} loading={verifying} onClick={confirm}>\n          {confirmLabel}\n        </Button>,\n      ]}\n    >\n      {description && (\n        <Paragraph type=\"secondary\" style={{ fontSize: 13, marginBottom: 8 }}>{description}</Paragraph>\n      )}\n      <Paragraph type=\"secondary\" style={{ fontSize: 13 }}>\n        This is a protected action. A one-time code has been emailed to{' '}\n        <Text strong>{sentTo || '…'}</Text>. Enter it below to continue.\n      </Paragraph>\n      <Input\n        size=\"large\"\n        inputMode=\"numeric\"\n        placeholder=\"Enter OTP\"\n        value={otp}\n        maxLength={6}\n        onChange={(e) => setOtp(e.target.value.replace(/\\D/g, ''))}\n        onPressEnter={confirm}\n        autoFocus\n      />\n      {error && <Alert type=\"error\" showIcon message={error} style={{ marginTop: 12 }} />}\n      <div style={{ marginTop: 12 }}>\n        <Button type=\"link\" size=\"small\" loading={sending} onClick={sendOtp} style={{ padding: 0 }}>\n          Resend code\n        </Button>\n      </div>\n    </Modal>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Alert, Button, Empty, Select, Space, Spin, Tag, Typography, message } from 'antd';\nimport { SafetyCertificateOutlined, SaveOutlined } from '@ant-design/icons';\nimport AppCard from '../../../../components/cards/AppCard';\nimport OtpGateModal from '../../../../components/admin/OtpGateModal';\nimport { getAdminFormGroups, getModuleDefaultFields, saveModuleDefaultFields } from '../../../../services/adminApi';\n\nconst { Text } = Typography;\n\n// DefaultFieldsPanel — Form Groups → Default Fields tab.\n// Pick, per module, the form fields that must ALWAYS be shown and required.\n// These fields' Show/Required toggles are then locked in the field editor and\n// forced on at render (AddFormV1/EditFormV1), so no one can turn them off.\n// Adding/updating the list is OTP-gated (code emailed to the approver).\nexport default function DefaultFieldsPanel({ moduleOptions = [] }) {\n  const [module, setModule] = useState('');\n  const [fieldOptions, setFieldOptions] = useState([]);\n  const [selected, setSelected] = useState([]);\n  const [saved, setSaved] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [gateOpen, setGateOpen] = useState(false);\n\n  useEffect(() => {\n    if (!module && moduleOptions.length) setModule(moduleOptions[0].value);\n  }, [moduleOptions, module]);\n\n  const load = useCallback(async (mod) => {\n    if (!mod) return;\n    setLoading(true);\n    try {\n      const [groups, defaults] = await Promise.all([\n        getAdminFormGroups(mod).catch(() => []),\n        getModuleDefaultFields(mod).catch(() => []),\n      ]);\n      // Flatten the module's form-group fields into a de-duplicated option list.\n      const seen = new Set();\n      const opts = [];\n      (Array.isArray(groups) ? groups : []).forEach((g) => {\n        (g.fields ?? []).forEach((f) => {\n          const key = String(f.field ?? '').trim();\n          if (!key || seen.has(key)) return;\n          seen.add(key);\n          opts.push({ value: key, label: `${f.label ?? key} · ${key}`, group: g.label ?? g.name });\n        });\n      });\n      setFieldOptions(opts);\n      setSaved(defaults);\n      setSelected(defaults);\n    } catch (e) {\n      message.error(e?.message || 'Could not load default fields');\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  useEffect(() => { queueMicrotask(() => { load(module); }); }, [module, load]);\n\n  const dirty = useMemo(() => {\n    if (selected.length !== saved.length) return true;\n    const a = [...selected].sort();\n    const b = [...saved].sort();\n    return a.some((v, i) => v !== b[i]);\n  }, [selected, saved]);\n\n  async function doSave(otp) {\n    const res = await saveModuleDefaultFields(module, selected, otp);\n    setSaved(selected);\n    return res;\n  }\n\n  return (\n    <AppCard\n      icon={<SafetyCertificateOutlined />}\n      title=\"Default Fields\"\n      extra={(\n        <Space>\n          <Select\n            size=\"small\"\n            showSearch\n            optionFilterProp=\"label\"\n            style={{ width: 220 }}\n            placeholder=\"Module\"\n            value={module || undefined}\n            options={moduleOptions}\n            onChange={setModule}\n          />\n          <Button\n            type=\"primary\"\n            size=\"small\"\n            icon={<SaveOutlined />}\n            disabled={!module || !dirty}\n            onClick={() => setGateOpen(true)}\n          >\n            Save (OTP)\n          </Button>\n        </Space>\n      )}\n    >\n      <div className=\"admin-accent-bar\" />\n      <Text type=\"secondary\" style={{ fontSize: 13, display: 'block', marginBottom: 12 }}>\n        Fields chosen here are <b>always shown and always required</b> on this module&apos;s add &amp; edit form.\n        Their Show / Required switches are locked in Form Groups so no one can turn them off. Changing this\n        list requires an OTP emailed to the approver.\n      </Text>\n\n      <Spin spinning={loading}>\n        <Select\n          mode=\"multiple\"\n          allowClear\n          showSearch\n          optionFilterProp=\"label\"\n          style={{ width: '100%' }}\n          placeholder=\"Select the fields that must always show + be required\"\n          value={selected}\n          options={fieldOptions}\n          onChange={setSelected}\n          maxTagCount=\"responsive\"\n        />\n        <div style={{ marginTop: 12 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Currently enforced ({saved.length}): </Text>\n          {saved.length\n            ? saved.map((f) => <Tag key={f} color=\"blue\" style={{ marginTop: 4 }}>{f}</Tag>)\n            : <Text type=\"secondary\" style={{ fontSize: 12 }}>none</Text>}\n        </div>\n        {!loading && fieldOptions.length === 0 && (\n          <Alert style={{ marginTop: 12 }} type=\"info\" showIcon\n            message=\"This module has no form-group fields yet — configure its Form Groups first.\" />\n        )}\n      </Spin>\n\n      <OtpGateModal\n        open={gateOpen}\n        scope=\"defaultFields\"\n        action=\"save\"\n        title=\"Confirm Default Fields change\"\n        description=\"Adding or updating a module's default (always-shown + required) fields is a protected action.\"\n        confirmLabel=\"Verify & Save\"\n        onCancel={() => setGateOpen(false)}\n        onConfirm={doSave}\n        onVerified={() => { setGateOpen(false); load(module); }}\n      />\n    </AppCard>\n  );\n}\n","// Sanitiser for the static Label/Value option editor, extracted so the rule\n// below can be tested without mounting the whole admin page.\n\n// cleanOptions drops half-typed rows and normalises what the option editor\n// writes.\n//\n// `module` needs the care. It is optional, and an empty string is NOT the same\n// as absent: blank means \"this option uses the form's own module\", which the\n// consumer expresses by falling back when the key is missing. Storing \"\" would\n// leave every option of every form carrying a meaningless key, and the next\n// person reading the document could not tell a deliberate blank from an\n// untouched field.\nexport function cleanOptions(options) {\n  return (options ?? [])\n    .filter((option) => option?.label || option?.value)\n    .map((option) => {\n      const next = { ...option };\n      const module = String(next.module ?? '').trim();\n      if (module) next.module = module;\n      else delete next.module;\n      return next;\n    });\n}\n\nexport default cleanOptions;\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Alert,\n  AutoComplete,\n  Badge,\n  Button,\n  Checkbox,\n  Drawer,\n  Dropdown,\n  Empty,\n  Form,\n  Input,\n  InputNumber,\n  message,\n  Modal,\n  Popconfirm,\n  Radio,\n  Select,\n  Space,\n  Spin,\n  Switch,\n  Table,\n  Tabs,\n  Tag,\n  Tooltip,\n  Typography,\n} from 'antd';\nimport {\n  AppstoreAddOutlined,\n  CheckCircleOutlined,\n  CloudDownloadOutlined,\n  CopyOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  EyeOutlined,\n  HolderOutlined,\n  InfoCircleOutlined,\n  MinusCircleOutlined,\n  PlusOutlined,\n  ReloadOutlined,\n  SafetyCertificateOutlined,\n  SaveOutlined,\n  SnippetsOutlined,\n  MoreOutlined,\n  RightOutlined,\n  DownOutlined,\n  ThunderboltOutlined,\n} from '@ant-design/icons';\nimport {\n  createAdminFormGroup,\n  createCustomForm,\n  deleteAdminFormGroup,\n  deleteCustomForm,\n  getAdminClients,\n  getAdminFormGroups,\n  getAvailableModules,\n  getCustomForms,\n  getModuleFields,\n  getModuleDefaultFields,\n  getModuleCollectionMap,\n  getLookupRecordOptions,\n  updateAdminFormGroup,\n  updateCustomForm,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\nimport { quickCreateLabel, quickEditLabel } from '../../../components/form/quickActionLabels';\nimport AddFormV1 from '../../../components/AddFormV1';\nimport AppCard from '../../../components/cards/AppCard';\nimport { INPUT_VALIDATOR_TYPES } from '../../../components/form/inputValidator';\nimport { UPLOAD_ACCEPT_OPTIONS } from '../../../components/form/uploadAccept';\nimport { CONDITION_OPERATORS, CONDITION_VALUE_OPERATORS } from '../../../components/form/conditionOperators';\nimport { parseLockFieldKeys } from '../../../components/form/verifyLockState';\nimport {\n  UNIQUE_VALIDATION_TYPE,\n  UNIQUE_NORMALIZERS,\n  UNIQUE_ENFORCEMENT_MODES,\n  UNIQUE_VALIDATION_TRIGGERS,\n  ALSO_CHECK_EXCLUSION_HINT,\n  alsoCheckEntryErrors,\n  collectionFieldPathError,\n  defaultAlsoCheckEntry,\n  defaultUniqueConfig,\n  normalizeUniqueConfig,\n  resolveUniqueTarget,\n  uniqueFieldTypeSupport,\n  uniqueRuleErrors,\n} from './uniqueValidationConfig';\nimport OtpGateModal from '../../../components/admin/OtpGateModal';\nimport DefaultFieldsPanel from './components/DefaultFieldsPanel';\nimport { BOOLEAN_PARSEABLE_API_KEYS, isBooleanParsable } from '../../../components/searchBuilder/booleanQueryUtils';\nimport { cleanOptions } from './formOptions';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\n// OTP-gated config actions surfaced as buttons next to \"New Group\". Each opens\n// the OtpGateModal which mails a code and performs the action on verification.\nconst CONFIG_GATE_META = {\n  reset:   { action: 'reset',   title: 'Reset all form groups',    confirmLabel: 'Reset All',       danger: true,\n    description: 'This reseeds every module in this workspace back to the built-in default groups, discarding current customizations.' },\n  save:    { action: 'save',    title: 'Save current as default',  confirmLabel: 'Save Default',    danger: false,\n    description: 'Snapshots the current form groups for all modules as the saved default you can restore to later.' },\n  restore: { action: 'restore', title: 'Restore saved default',    confirmLabel: 'Restore Default', danger: true,\n    description: 'Replaces the current form groups for all modules with the last saved default.' },\n};\n\nconst TAB_COLORS = ['#0053a5', '#52c41a', '#722ed1', '#fa8c16', '#eb2f96', '#13c2c2'];\n\nconst FIELD_TYPES = [\n  { label: 'Text',        value: 'text' },\n  { label: 'Number',      value: 'number' },\n  { label: 'Email',       value: 'email' },\n  { label: 'Date',        value: 'date' },\n  { label: 'Time Picker', value: 'time' },\n  { label: 'Location',    value: 'location' },\n  { label: 'Select',      value: 'select' },\n  { label: 'Radio',       value: 'radio' },\n  { label: 'Checkbox',    value: 'checkbox' },\n  { label: 'Tagify',      value: 'tagify' },\n  { label: 'Textarea',    value: 'textarea' },\n  { label: 'Text Editor', value: 'text-editor' },\n  { label: 'File',        value: 'file' },\n];\n\n// Input types only SearchBuilderV1 renders. Kept out of FIELD_TYPES so an\n// add/edit form can never be authored with a control its engine cannot draw.\nconst SEARCH_ONLY_FIELD_TYPES = [\n  { label: 'Multi Select', value: 'multiselect' },\n  { label: 'Date Range',   value: 'daterange' },\n  { label: 'Range Slider', value: 'range' },\n  { label: 'Date Range (with presets)', value: 'daterangePreset' },\n];\n\n// Mirrors BooleanSearchRequest in Be_Auth_DevOps models/boolean_search.go.\nconst BOOLEAN_API_KEY_OPTIONS = [\n  { label: 'query (all search fields)', value: 'query' },\n  { label: 'skills',                    value: 'skills' },\n  { label: 'jobTitle',                  value: 'jobTitle' },\n  { label: 'designation',               value: 'designation' },\n  { label: 'currentLocation',           value: 'currentLocation' },\n  { label: 'experience.from',           value: 'experience.from' },\n  { label: 'experience.to',             value: 'experience.to' },\n  { label: 'experience.from + to (range)', value: 'experience.from,experience.to' },\n  { label: 'workExperienceYears',       value: 'workExperienceYears' },\n  { label: 'sourceType',                value: 'sourceType' },\n  { label: 'createdFrom + createdTo (date range)', value: 'createdFrom,createdTo' },\n];\n\n// Types whose control can be swapped for a boolean expression box. Matches the\n// booleanEligible flags in components/searchBuilder/fieldTypeRegistry.jsx.\nconst BOOLEAN_ELIGIBLE_TYPES = ['text', 'email', 'textarea', 'tagify', 'select', 'multiselect'];\n\n// How a Range Slider field presents itself — teams that do not want the\n// horizontal drag bar can switch it to plain From / To boxes.\nconst RANGE_DISPLAY_OPTIONS = [\n  { label: 'Slider + From/To', value: 'both' },\n  { label: 'Slider only',      value: 'slider' },\n  { label: 'From / To only',   value: 'inputs' },\n];\n\nconst DROPDOWN_SOURCES = [\n  { label: 'Static (define options here)', value: 'static' },\n  { label: 'Masters collection',           value: 'master' },\n  { label: 'Module data (distinct)',        value: 'module' },\n  { label: 'Collection lookup (FK)',        value: 'lookup' },\n  { label: 'Group value',                  value: 'group'  },\n  { label: 'Location Master (Country/State/City)', value: 'locationMaster' },\n];\n\nconst LOCATION_MASTER_LEVELS = [\n  { label: 'Country', value: 'country' },\n  { label: 'State (needs a Country field)', value: 'state' },\n  { label: 'City (needs a Country + State field)', value: 'city' },\n];\n\nconst VALIDATION_TYPES = [\n  { label: 'Required',          value: 'required',        hasValue: false },\n  { label: 'Min length/value',  value: 'min',             hasValue: true, valueType: 'number', placeholder: 'e.g. 2' },\n  { label: 'Max length/value',  value: 'max',             hasValue: true, valueType: 'number', placeholder: 'e.g. 100' },\n  { label: 'Pattern (regex)',   value: 'pattern',         hasValue: true, valueType: 'text',   placeholder: '^[A-Za-z]+$' },\n  { label: 'Email (reject numeric-only address)', value: 'email', hasValue: false },\n  { label: 'Phone format',      value: 'phone',           hasValue: false },\n  { label: 'On or after another date field',  value: 'dateAfterField',  hasValue: true, valueType: 'text', placeholder: 'startDate', dateOnly: true, messageOptional: true },\n  { label: 'On or before another date field', value: 'dateBeforeField', hasValue: true, valueType: 'text', placeholder: 'endDate', dateOnly: true, messageOptional: true },\n  { label: 'Before another time field', value: 'timeBeforeField', hasValue: true, valueType: 'text', placeholder: 'endTime', messageOptional: true },\n  { label: 'After another time field',  value: 'timeAfterField',  hasValue: true, valueType: 'text', placeholder: 'startTime', messageOptional: true },\n  { label: 'File types allowed',value: 'fileType',        hasValue: true, valueType: 'text',   placeholder: 'pdf,doc,jpg', messageOptional: true },\n  { label: 'Max file size (MB)',value: 'fileSize',        hasValue: true, valueType: 'number', placeholder: 'e.g. 5',     messageOptional: true },\n  { label: 'Max files count',   value: 'maxFiles',        hasValue: true, valueType: 'number', placeholder: 'e.g. 3',     messageOptional: true },\n  { label: 'Greater than or equal to field', value: 'greaterThanField',       hasValue: true, valueType: 'text', placeholder: 'experienceRequiredFrom' },\n  { label: 'Greater than field (strict)',     value: 'strictGreaterThanField', hasValue: true, valueType: 'text', placeholder: 'numberOfPosition' },\n  { label: 'Less than field (strict)',        value: 'strictLessThanField',    hasValue: true, valueType: 'text', placeholder: 'experienceRequiredTo' },\n  { label: 'Less than or equal to field',     value: 'lessThanOrEqualField',   hasValue: true, valueType: 'text', placeholder: 'experienceRequiredTo' },\n  // Comma-separated, in priority order: the FIRST entry holding a positive\n  // number becomes the cap (an empty or 0 entry means \"no ceiling here\" and\n  // falls through to the next). A DOTTED entry is an absolute field path, so it\n  // can reach a value parked outside this field's own container; a bare entry\n  // is looked up as a sibling of this field.\n  { label: 'Max field with fallback',         value: 'maxFieldWithFallback',  hasValue: true, valueType: 'text', placeholder: 'group.preferredToField,group.fallbackFromField' },\n  { label: 'Disable previous dates', value: 'noPastDate',   hasValue: false, messageOptional: true, dateOnly: true },\n  { label: 'Disable future dates',   value: 'noFutureDate', hasValue: false, messageOptional: true, dateOnly: true },\n  { label: 'Min age (years)',        value: 'minAge',       hasValue: true, valueType: 'number', placeholder: 'e.g. 18', messageOptional: true, dateOnly: true },\n  // maxFromField is the ONLY rule whose target lives in `rule.field` instead of\n  // `rule.value`. It exists because the cap is another FIELD, not a constant:\n  // \"a relevant skill's years of experience may not exceed the candidate's\n  // overall experience\". The Go model (FieldValidation.Field) and the runtime\n  // matcher (components/form/crossFieldRules.js) both key off `field`, so the\n  // editor must persist `field` — writing it into `value` would silently\n  // disable the rule. `hasValue: false` keeps the generic value input hidden;\n  // `needsField: true` swaps in the sibling-field picker instead.\n  { label: 'Max from another field', value: 'maxFromField', hasValue: false, needsField: true, messageOptional: true },\n  // The ONLY rule whose `value` is an OBJECT rather than a scalar: uniqueness\n  // needs four settings (which stored key to compare, how to normalise before\n  // comparing, whether blanks participate, when to probe), and cramming them\n  // into one string would make them unparseable for both the editor and Go.\n  // `valueType: 'object'` is load-bearing — buildFieldPayload runs Number() over\n  // the value ONLY for `valueType: 'number'`, so declaring an object type is\n  // what keeps the config from being coerced to NaN on save. The message is\n  // deliberately NOT optional: \"already present\" errors are the ones a user\n  // must be able to act on, so the admin has to write one.\n  { label: 'Unique value / Already present check', value: UNIQUE_VALIDATION_TYPE, hasValue: true, valueType: 'object' },\n];\n\n// Shared with the Detail Groups conditional-label editor and kept beside the\n// matcher that implements them — see components/form/conditionOperators.js.\nconst SHOW_IF_OPERATORS = CONDITION_OPERATORS;\nconst SHOW_IF_VALUE_OPERATORS = CONDITION_VALUE_OPERATORS;\n\n// ── Payload-engine config option lists ──────────────────────────────────────────\n// These drive the config-driven payload transformer (CORE-THEME/src/components/\n// form/payloadTransformer.js). Admin controls payload shape with NO frontend code.\nconst DATA_TYPES = [\n  { label: 'Auto (infer from field)', value: 'auto' },\n  { label: 'String',  value: 'string' },\n  { label: 'Number',  value: 'number' },\n  { label: 'Boolean', value: 'boolean' },\n  { label: 'Array',   value: 'array' },\n  { label: 'Object',  value: 'object' },\n  { label: 'Date (ISO)', value: 'date' },\n];\n\nconst ELEMENT_TYPES = [\n  { label: '(none)',  value: '' },\n  { label: 'String',  value: 'string' },\n  { label: 'Number',  value: 'number' },\n  { label: 'Boolean', value: 'boolean' },\n];\n\nconst PAYLOAD_MODES = [\n  { label: 'Auto (value as-is)',            value: 'auto' },\n  { label: 'Value only — { key: id }',      value: 'value' },\n  { label: 'Label only — { key: \"India\" }', value: 'label' },\n  { label: 'Full object — { id, name }',    value: 'object' },\n  { label: 'Custom template',               value: 'custom' },\n  { label: 'Skip (never send)',             value: 'skip' },\n];\n\nconst VALIDATION_TAG_COLOR = {\n  required: 'red', min: 'orange', max: 'gold', pattern: 'purple',\n  email: 'blue', phone: 'cyan', dateAfterField: 'volcano', dateBeforeField: 'orange',\n  fileType: 'cyan', fileSize: 'blue', maxFiles: 'geekblue',\n  greaterThanField: 'lime', strictGreaterThanField: 'green', strictLessThanField: 'cyan',\n  lessThanOrEqualField: 'blue', maxFieldWithFallback: 'purple', maxFromField: 'volcano',\n  noPastDate: 'geekblue', noFutureDate: 'magenta', minAge: 'green',\n  unique: 'magenta',\n};\n\nfunction validationMeta(type) {\n  return VALIDATION_TYPES.find((v) => v.value === type) ?? { hasValue: false };\n}\n\nfunction buildModuleTabs(apiModules) {\n  const all = { key: 'all', label: 'All', color: '#8c8c8c' };\n  const rest = apiModules.map((m, i) => ({\n    key: m.key, label: m.label, color: TAB_COLORS[i % TAB_COLORS.length],\n  }));\n  return [all, ...rest];\n}\n\nfunction initModuleState(tabs) {\n  return Object.fromEntries(tabs.map(({ key }) => [key, { groups: [], loading: false, loaded: false, error: '' }]));\n}\n\n// ── Shared helpers ────────────────────────────────────────────────────────────\n\n// safeParseObject parses an admin-entered JSON string into an object. Returns\n// undefined for blank/invalid input so the key is simply omitted (the backend\n// model stores these as objects, never strings).\nfunction safeParseObject(input) {\n  if (input == null) return undefined;\n  if (typeof input === 'object') return input;\n  const str = String(input).trim();\n  if (!str) return undefined;\n  try {\n    const parsed = JSON.parse(str);\n    return parsed && typeof parsed === 'object' ? parsed : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\n// stringifyObject renders a stored object config back to pretty JSON for editing.\nfunction stringifyObject(value) {\n  if (value == null) return '';\n  if (typeof value === 'string') return value;\n  try {\n    return JSON.stringify(value, null, 2);\n  } catch {\n    return '';\n  }\n}\n\n// applyPayloadConfig copies the payload-engine config off a raw field-editor row\n// onto the outgoing payload, omitting empty/default values so docs stay lean.\nfunction applyPayloadConfig(fp, f) {\n  if (f.payloadKey)  fp.payloadKey  = f.payloadKey;\n  if (f.prefillFrom) fp.prefillFrom = f.prefillFrom;\n  // prefillAsHint SHOWS a prefilled value under the field instead of filling it\n  // in. Only written when ON, so every field that never opts in stays byte-\n  // identical to what it was before this key existed.\n  if (f.prefillAsHint) {\n    fp.prefillAsHint = true;\n    if (String(f.prefillHintLabel ?? '').trim()) fp.prefillHintLabel = String(f.prefillHintLabel).trim();\n  }\n  if (f.prefillFromModule) fp.prefillFromModule = f.prefillFromModule;\n  // A \"clear\" row deliberately carries NO setValue — it exists to EMPTY the\n  // field, not to fill it — so it must survive the completeness filter that\n  // (rightly) drops half-typed set rows. Without this exception the round trip\n  // silently ate every clear rule the admin saved.\n  const prefillWhenRows = (Array.isArray(f.prefillWhen) ? f.prefillWhen : [])\n    .filter((r) => r && r.field && r.value !== undefined && r.value !== ''\n      && (r.clearValue ? true : (r.setValue !== undefined && r.setValue !== '')))\n    .map((r) => (r.clearValue\n      // Persist a clear row as exactly {field, value, clearValue} — a stale\n      // setValue/label left over from flipping the switch would be misleading\n      // config and, worse, would read back as a set rule if clearValue were\n      // ever dropped by an older backend.\n      ? { field: r.field, value: r.value, clearValue: true }\n      : r));\n  if (prefillWhenRows.length) {\n    fp.prefillWhen = prefillWhenRows;\n    // Default is \"reset\" (on) — explicitly persist `false` only when the admin\n    // opted out, so existing configs saved before this toggle existed keep the\n    // safer, expected behavior without needing a re-save.\n    if (f.prefillWhenReset === false) fp.prefillWhenReset = false;\n    // Default is OFF (every value a rule can set stays offerable, i.e. today's\n    // behaviour), so only an explicit opt-in is persisted — nothing is written\n    // into configs that never turned it on.\n    if (f.prefillWhenExclusive === true) fp.prefillWhenExclusive = true;\n  }\n  if (f.dataType && f.dataType !== 'auto')       fp.dataType = f.dataType;\n  if (f.elementType)                              fp.elementType = f.elementType;\n  if (f.payloadMode && f.payloadMode !== 'auto') fp.payloadMode = f.payloadMode;\n  if (f.valueKey)    fp.valueKey    = f.valueKey;\n  if (f.displayKey)  fp.displayKey  = f.displayKey;\n  if (f.defaultValue !== undefined && f.defaultValue !== '') fp.defaultValue = f.defaultValue;\n  if (f.richValue)   fp.richValue   = true;\n  if (f.omitEmpty)   fp.omitEmpty   = true;\n  const tpl = safeParseObject(f.payloadTemplate);\n  if (tpl) fp.payloadTemplate = tpl;\n  const tr = safeParseObject(f.transformRule);\n  if (tr) fp.transformRule = tr;\n  return fp;\n}\n\n// ── Dropdown conditions (FormField.lookupFilters) ───────────────────────────\n//\n// The legacy \"Filter Field\"/\"Filter Value From\" pair expresses exactly ONE\n// equality against a sibling FORM field, so a rule like \"users whose role is\n// recruiter AND who report to me\" was impossible to author — which is why the\n// Jobs \"Assign to\" picker used to list everybody. `lookupFilters` is a LIST of\n// conditions the lookup endpoint AND-s onto its query server-side.\n//\n// The stored shape is nested ({field, op, value|valueFrom|valuesFrom}); the\n// editor keeps it FLAT (one row = one condition, with a \"value comes from\"\n// selector) because antd Form.List rows are far easier to author flat. These\n// two helpers are the only place the two shapes meet.\nconst LOOKUP_FILTER_OPS = [\n  { label: 'equals',      value: 'eq' },\n  { label: 'not equals',  value: 'ne' },\n  { label: 'in',          value: 'in' },\n  { label: 'not in',      value: 'nin' },\n  { label: 'is not empty', value: 'notEmpty' },\n  { label: 'is empty',     value: 'empty' },\n];\n\n// Identity tokens the BACKEND resolves from the auth context. They are listed\n// here for discoverability only — the server rejects any token it does not\n// know, so a stale option cannot silently drop a condition (which would leak\n// rows).\nconst LOOKUP_FILTER_IDENTITY_TOKENS = [\n  'currentUserId', 'currentRoleId', 'currentUserName',\n  'currentUserEmail', 'currentReportingId',\n  'tenantId', 'businessId', 'businessUnitId',\n];\n\nfunction lookupFiltersToRows(stored) {\n  if (!Array.isArray(stored)) return [];\n  return stored.filter((f) => f && f.field).map((f) => {\n    const src = f.valuesFrom ?? null;\n    const matchField = src && src.match ? Object.keys(src.match)[0] ?? '' : '';\n    const rawMatch = matchField ? src.match[matchField] : undefined;\n    const isToken = rawMatch && typeof rawMatch === 'object' && typeof rawMatch.$valueFrom === 'string';\n    // A match value written by a seeder (or by hand) may already be a Mongo\n    // operator object — {$in:[…]} / {$eq:v}. The backend accepts that shape, but\n    // this editor renders the value into a TEXT INPUT, so leaving it as an\n    // object showed \"[object Object]\" and the next save wrote that literal\n    // string back, silently destroying the condition. Unwrap the common\n    // single-operator forms into the comma-separated text this editor round-\n    // trips; anything more exotic is left alone rather than half-rendered.\n    const unwrapMatch = (v) => {\n      if (!v || typeof v !== 'object' || Array.isArray(v)) return v;\n      const keys = Object.keys(v);\n      if (keys.length === 1 && (keys[0] === '$in' || keys[0] === '$eq')) return v[keys[0]];\n      return v;\n    };\n    const plainMatch = isToken ? '' : unwrapMatch(rawMatch);\n    return {\n      field: f.field ?? '',\n      op: f.op ?? 'eq',\n      valueSource: src ? 'collection' : (f.valueFrom ? 'identity' : 'literal'),\n      value: Array.isArray(f.value) ? f.value.join(', ') : (f.value ?? ''),\n      valueFrom: f.valueFrom ?? '',\n      srcCollection: src?.collection ?? '',\n      srcValueField: src?.valueField ?? '',\n      srcMatchField: matchField,\n      srcMatchValue: Array.isArray(plainMatch) ? plainMatch.join(', ') : (plainMatch ?? ''),\n      srcMatchValueFrom: isToken ? rawMatch.$valueFrom : '',\n      srcRecursive: src?.recursive ?? false,\n      srcRecursiveField: src?.recursiveField ?? '',\n    };\n  });\n}\n\nfunction lookupFiltersFromRows(rows) {\n  if (!Array.isArray(rows)) return [];\n  const out = [];\n  for (const r of rows) {\n    const field = String(r?.field ?? '').trim();\n    if (!field) continue;\n    const op = String(r?.op ?? 'eq').trim() || 'eq';\n    const cond = { field, op };\n\n    // notEmpty/empty are value-less by definition.\n    if (op === 'notEmpty' || op === 'empty') { out.push(cond); continue; }\n\n    const source = r.valueSource ?? (r.srcCollection ? 'collection' : (r.valueFrom ? 'identity' : 'literal'));\n    if (source === 'collection') {\n      const collection = String(r.srcCollection ?? '').trim();\n      if (!collection) continue;\n      const valuesFrom = { collection, valueField: String(r.srcValueField ?? '').trim() || '_id' };\n      const matchField = String(r.srcMatchField ?? '').trim();\n      if (matchField) {\n        const token = String(r.srcMatchValueFrom ?? '').trim();\n        const literal = String(r.srcMatchValue ?? '').trim();\n        // An identity token wins: it is the only value the server will not\n        // take from the client.\n        if (token) valuesFrom.match = { [matchField]: { $valueFrom: token } };\n        else if (literal) valuesFrom.match = { [matchField]: literal.includes(',') ? literal.split(',').map((s) => s.trim()).filter(Boolean) : literal };\n      }\n      if (r.srcRecursive) {\n        valuesFrom.recursive = true;\n        const rf = String(r.srcRecursiveField ?? '').trim() || matchField;\n        if (rf) valuesFrom.recursiveField = rf;\n      }\n      cond.valuesFrom = valuesFrom;\n    } else if (source === 'identity') {\n      const token = String(r.valueFrom ?? '').trim();\n      if (!token) continue;\n      cond.valueFrom = token;\n    } else {\n      const raw = r.value;\n      if (raw === undefined || raw === null || String(raw).trim() === '') continue;\n      const str = String(raw).trim();\n      cond.value = str.includes(',') ? str.split(',').map((s) => s.trim()).filter(Boolean) : str;\n    }\n    out.push(cond);\n  }\n  return out;\n}\n\n// collectUniqueRuleErrors is the SAVE-TIME backstop for uniqueness config.\n//\n// The per-control antd rules can only run for a field card that is currently\n// expanded — collapsed cards are unmounted for speed and their values are read\n// straight out of the form store — so a malformed unique rule authored in one\n// card, then collapsed, would otherwise reach the document unchecked. This walks\n// the values actually about to be saved. Returns [] when everything is fine.\nfunction collectUniqueRuleErrors(fields = []) {\n  const problems = [];\n  for (const f of fields ?? []) {\n    const name = f?.label || f?.field || 'field';\n    for (const v of f?.validations ?? []) {\n      for (const err of uniqueRuleErrors(v, f)) problems.push(`${name}: ${err}`);\n    }\n  }\n  return problems;\n}\n\n// cleanConfirmMessages keeps only the wording an admin actually typed, so an\n// untouched prompt stores nothing and keeps using the built-in sentences.\nfunction cleanConfirmMessages(messages) {\n  const out = {};\n  ['title', 'body', 'ok', 'cancel'].forEach((key) => {\n    const value = String(messages?.[key] ?? '').trim();\n    if (value) out[key] = value;\n  });\n  return Object.keys(out).length ? out : null;\n}\n\n// Used only when someone switches a rule ON for a group that has none yet.\n// An existing rule is always carried through as-is instead of being replaced.\n// Used only when someone switches the row hierarchy ON for a field that has\n// no rule yet. An existing rule is always carried through as-is.\nconst DEFAULT_ROW_HIERARCHY = Object.freeze({\n  mode: 'newestFirst',\n  startField: 'startDate',\n  endField: 'endDate',\n});\n\nconst DEFAULT_ORDER_BY = Object.freeze({\n  field: 'startDate',\n  tieBreak: 'endDate',\n  direction: 'desc',\n  inProgressField: 'currentStudyingHere',\n  inProgressFirst: true,\n  confirmMove: true,\n});\n\nconst DEFAULT_LEVEL_RULE = Object.freeze({\n  levelField: 'qualification',\n  requireBelow: true,\n  message: 'You have entered only a higher qualification — {missing} is also required.',\n});\n\nfunction buildFieldPayload(fields = []) {\n  // A row with a blank field key would save an unrenderable field — skip it.\n  return fields.filter((f) => String(f?.field ?? '').trim() !== '').map((f, idx) => {\n    const validations = (f.validations ?? [])\n      .filter((v) => v?.type)\n      .map((v) => {\n        const meta = validationMeta(v.type);\n        const rule = { type: v.type, message: v.message ?? '' };\n        if (meta.hasValue && v.value !== '' && v.value !== undefined && v.value !== null) {\n          // An OBJECT-valued rule (uniqueness) must reach the document as an\n          // object. Number()/String() would destroy it, so the coercion below\n          // stays scoped to the numeric types it was written for. The object is\n          // re-normalised rather than passed through raw so the defaults are\n          // materialised (and an explicit skipBlank:false survives) — normalize\n          // preserves every key it does not own, so nothing is lost.\n          if (meta.valueType === 'object') {\n            rule.value = v.type === UNIQUE_VALIDATION_TYPE\n              ? normalizeUniqueConfig(v.value, f)\n              : v.value;\n          } else {\n            rule.value = meta.valueType === 'number' ? Number(v.value) : v.value;\n          }\n        } else if (meta.valueType === 'object' && v.type === UNIQUE_VALIDATION_TYPE) {\n          // A unique rule whose config was never opened still needs a config —\n          // saving `{type:'unique'}` alone would leave the backend guessing at\n          // the stored key. Seed it from the field itself.\n          rule.value = defaultUniqueConfig(f);\n        }\n        // Rules that cap this field against ANOTHER field (maxFromField) carry\n        // their target in `field`. Kept separate from `value` on purpose — the\n        // runtime resolves it as a form path (row-scoped inside an addRow\n        // group), which is a different thing from a literal comparison value.\n        if (meta.needsField) {\n          const target = String(v.field ?? '').trim();\n          if (target) rule.field = target;\n        }\n        // Date-pair options (components/form/dateRules.js). Each is written\n        // ONLY when it carries a real setting, so an untouched rule keeps its\n        // existing document shape instead of gaining a wall of empty keys —\n        // and an absent option means exactly the pre-feature behaviour.\n        if (v.type === 'dateAfterField' || v.type === 'dateBeforeField') {\n          if (v.strict) rule.strict = true;\n          const gapValue = Number(v.minGap?.value);\n          if (Number.isFinite(gapValue) && gapValue > 0) {\n            rule.minGap = { value: gapValue, unit: v.minGap?.unit || 'month' };\n          }\n          const gapFrom = String(v.minGapFrom ?? '').trim();\n          if (gapFrom) rule.minGapFrom = gapFrom;\n        }\n        return rule;\n      });\n\n    const fp = {\n      label: f.label, field: f.field, type: f.type ?? 'text',\n      show: f.show ? 1 : 0, req: f.req ? 1 : 0, edit: f.edit ? 1 : 0,\n      // Persist the field's position so the form renders in the SAME order the\n      // admin arranged by drag-and-drop. Both forms sort fields by `order`, so\n      // without this a reorder in the editor never reached the rendered form.\n      order: idx,\n      formatter: f.formatter ?? '', validations,\n    };\n    if (f.showOnAdd === false) fp.showOnAdd = false;\n    if (f.addRow) {\n      fp.addRow = true;\n      if (f.minRows !== undefined && f.minRows !== '' && Number(f.minRows) > 0) fp.minRows = Number(f.minRows);\n      if (f.maxRows !== undefined && f.maxRows !== '' && Number(f.maxRows) > 0) fp.maxRows = Number(f.maxRows);\n      if (f.initialRows !== undefined && f.initialRows !== '') fp.initialRows = Number(f.initialRows);\n      if (f.addLabel) fp.addLabel = f.addLabel;\n      // Sub-fields → repeat a GROUP of fields together (e.g. question + answer).\n      // Only rows with a key are kept.\n      const subs = (f.subFields ?? []).filter((s) => s && s.field);\n      if (subs.length) {\n        fp.subFields = subs.map((s) => {\n          // show:1 / edit:1 are REQUIRED — the Go FormGroupField serializes\n          // show/edit as 0 when absent (no omitempty), and the form engine reads\n          // edit:0 as \"not editable\", disabling the control. Sub-fields have no\n          // show/edit admin toggle, so they are always visible + editable.\n          const sp = {\n            field: String(s.field).trim(),\n            label: s.label ?? s.field,\n            type: s.type ?? 'text',\n            show: 1,\n            edit: 1,\n            req: s.req ? 1 : 0,\n          };\n          if (s.col !== undefined && s.col !== '' && Number(s.col) > 0) sp.col = Number(s.col);\n          if (s.payloadKey) sp.payloadKey = String(s.payloadKey).trim();\n          // A sub-field of type select/radio/checkbox needs the SAME dataSource\n          // config as a normal field, or its control renders with no options —\n          // it uses the same FormGroupField struct, so every key here reaches\n          // the runtime FieldControl unchanged.\n          if (['select', 'radio', 'checkbox'].includes(sp.type)) {\n            const sds = s.dataSource ?? 'static';\n            sp.dataSource = sds;\n            if (sp.type === 'select') sp.multiSelect = s.multiSelect ?? false;\n            if (sds === 'master') sp.masterName = s.masterName ?? '';\n            if (sds === 'group') sp.groupName = s.groupName ?? '';\n            if (sds === 'static') sp.options = cleanOptions(s.options);\n            if (sds === 'lookup') {\n              sp.lookupCollection = s.lookupCollection ?? '';\n              sp.displayField = s.displayField ?? '';\n              if (s.displayField2) sp.displayField2 = s.displayField2;\n              sp.valueField = s.valueField ?? '_id';\n              if (s.lookupFilterField && s.lookupFilterValueFrom) {\n                sp.lookupFilterField = s.lookupFilterField;\n                sp.lookupFilterValueFrom = s.lookupFilterValueFrom;\n              }\n            }\n          }\n          return sp;\n        });\n      }\n    }\n    if (f.placeholder) fp.placeholder = f.placeholder;\n    if (f.hidePlaceholder) fp.hidePlaceholder = true;\n\n    if (f.combineKey) fp.combineKey = f.combineKey;\n    if (f.combineLabel) fp.combineLabel = f.combineLabel;\n    if (f.combineRole) fp.combineRole = f.combineRole;\n    if (f.combineToggleLabel) fp.combineToggleLabel = f.combineToggleLabel;\n    if (f.combineToggleTarget) fp.combineToggleTarget = f.combineToggleTarget;\n    if (f.combineWidth !== undefined && f.combineWidth !== '' && Number(f.combineWidth) > 0) fp.combineWidth = Number(f.combineWidth);\n    if (f.combineWrap) fp.combineWrap = true;\n    if (f.combineSpan !== undefined && f.combineSpan !== '' && [12, 24].includes(Number(f.combineSpan))) fp.combineSpan = Number(f.combineSpan);\n    if (f.defaultOnEdit) fp.defaultOnEdit = true;\n    if (f.noPrefill) fp.noPrefill = true;\n    if (f.emptyValues !== undefined && f.emptyValues !== '') {\n      fp.emptyValues = String(f.emptyValues).split(',').map((v) => v.trim()).filter((v) => v !== '');\n    }\n    if (f.valuePaths !== undefined && f.valuePaths !== '') {\n      fp.valuePaths = String(f.valuePaths).split(',').map((v) => v.trim()).filter((v) => v !== '');\n    }\n    if (f.clientScope) {\n      fp.clientScope = true;\n      if (f.clientGateMessage) fp.clientGateMessage = f.clientGateMessage;\n      if (f.clientGateResetOnChange) fp.clientGateResetOnChange = true;\n    }\n    if (f.visiblePermission) fp.visiblePermission = String(f.visiblePermission).trim();\n    if (f.editablePermission) fp.editablePermission = String(f.editablePermission).trim();\n    if (f.infoEnabled && f.infoText) {\n      fp.infoEnabled = true;\n      fp.infoText = f.infoText;\n    }\n    // `tooltip` is the label-independent help text (see the Help Text block in the\n    // editor). It is written unconditionally of infoEnabled because the runtime\n    // resolver prefers it and it needs no companion switch.\n    if (f.tooltip) fp.tooltip = String(f.tooltip);\n\n    // Search-form boolean config (SearchBuilderV1). `booleanApiKey` is written\n    // whether or not the field is boolean-capable, because plain fields still\n    // have to map onto the boolean request's structured params (sourceType,\n    // currentLocation, experience.*). A comma pair becomes an array so one\n    // composite control can fill several params.\n    if (f.booleanApiKey) {\n      const keys = String(f.booleanApiKey).split(',').map((k) => k.trim()).filter(Boolean);\n      if (keys.length) fp.booleanApiKey = keys.length > 1 ? keys : keys[0];\n    }\n    // The UI already hides \"Boolean capable\" unless the key is one the\n    // backend actually parses (see canBeBooleanCapable below), but that only\n    // stops NEW mistakes — it doesn't erase one saved before this guard\n    // existed, or a switch left on after the key was edited away from a\n    // parseable one without reopening this block. Enforcing it again here,\n    // against the value actually being written, is what makes it a real\n    // guarantee rather than a UI nicety.\n    if (f.booleanCapable && isBooleanParsable(fp.booleanApiKey)) fp.booleanCapable = true;\n    // Only meaningful on a field that actually becomes an expression box —\n    // written against fp.booleanCapable (the value being saved) rather than\n    // f.booleanCapable, so it can never outlive the switch that justifies it.\n    if (fp.booleanCapable && f.booleanPlaceholder) {\n      fp.booleanPlaceholder = String(f.booleanPlaceholder).trim();\n    }\n    if (f.type === 'number' || f.type === 'range') {\n      if (f.min !== undefined && f.min !== '') fp.min = Number(f.min);\n      if (f.max !== undefined && f.max !== '') fp.max = Number(f.max);\n    }\n    if (f.type === 'range') {\n      if (f.display && f.display !== 'both') fp.display = f.display;\n      // Trimmed and written only when non-empty: an empty label would override\n      // the component's \"show the raw bound\" fallback with a blank caption.\n      const minLabel = String(f.minLabel ?? '').trim();\n      const maxLabel = String(f.maxLabel ?? '').trim();\n      const unit = String(f.unit ?? '').trim();\n      if (minLabel) fp.minLabel = minLabel;\n      if (maxLabel) fp.maxLabel = maxLabel;\n      if (unit) fp.unit = unit;\n      const rangeKeys = String(f.rangeKeys ?? '').split(',').map((k) => k.trim()).filter(Boolean);\n      if (rangeKeys.length === 2) fp.rangeKeys = rangeKeys;\n    }\n    if (f.type === 'daterangePreset' && f.filterField) fp.filterField = String(f.filterField).trim();\n    if (f.type === 'checkbox' && f.hideSelectAll) fp.hideSelectAll = true;\n\n    // Payload-engine config (payloadKey / dataType / payloadMode / template / …)\n    applyPayloadConfig(fp, f);\n\n    if (f.type === 'file') {\n      fp.multiple = f.multiple ?? false;\n      fp.maxCount = fp.multiple ? Number(f.maxCount ?? 5) : 1;\n      if (f.fileKey) fp.fileKey = f.fileKey;\n      if (f.fileNameKey) fp.fileNameKey = f.fileNameKey;\n      if (f.fileUrlKey) fp.fileUrlKey = f.fileUrlKey;\n      if (f.accept && f.accept !== 'any') fp.accept = f.accept;\n    }\n\n    const extraShowIf = (Array.isArray(f.showIf?.conditions) ? f.showIf.conditions : [])\n      .filter((c) => c?.field && String(c.field).trim())\n      .map((c) => {\n        const cond = { field: String(c.field).trim(), operator: c.operator ?? 'eq' };\n        if (SHOW_IF_VALUE_OPERATORS.includes(cond.operator) && c.value != null && c.value !== '') cond.value = c.value;\n        return cond;\n      });\n    if (f.showIf?.field || extraShowIf.length) {\n      fp.showIf = {};\n      if (f.showIf?.field) {\n        fp.showIf.field = f.showIf.field;\n        fp.showIf.operator = f.showIf.operator ?? 'eq';\n        if (SHOW_IF_VALUE_OPERATORS.includes(fp.showIf.operator) && f.showIf.value != null && f.showIf.value !== '') {\n          fp.showIf.value = f.showIf.value;\n        }\n      }\n      // Extra conditions (\"add more\") — combined with the leaf by logic (and|or).\n      if (extraShowIf.length) {\n        fp.showIf.conditions = extraShowIf;\n        fp.showIf.logic = f.showIf?.logic === 'or' ? 'or' : 'and';\n      }\n    }\n    if (f.labelWhen?.field && f.labelWhen?.label) {\n      fp.labelWhen = {\n        field: String(f.labelWhen.field).trim(),\n        operator: f.labelWhen.operator ?? 'eq',\n        label: String(f.labelWhen.label).trim(),\n      };\n      if (SHOW_IF_VALUE_OPERATORS.includes(fp.labelWhen.operator)\n          && f.labelWhen.value != null && f.labelWhen.value !== '') {\n        fp.labelWhen.value = f.labelWhen.value;\n      }\n    }\n    // Conditional Width — the editor uses flat inputs; store the array shape the\n    // form engine reads (first matching rule wins). Absent ⇒ cleared by the admin.\n    if (f.colWhenField && Number(f.colWhenCol) > 0) {\n      const rule = {\n        field: String(f.colWhenField).trim(),\n        operator: f.colWhenOperator ?? 'eq',\n        col: Number(f.colWhenCol),\n      };\n      if (SHOW_IF_VALUE_OPERATORS.includes(rule.operator)\n          && f.colWhenValue != null && f.colWhenValue !== '') {\n        rule.value = f.colWhenValue;\n      }\n      fp.colWhen = [rule];\n    }\n    if (f.verifyAction) {\n      fp.verifyAction = f.verifyAction;\n      if (f.verifyResultField) fp.verifyResultField = String(f.verifyResultField).trim();\n      if (f.verifyTimestampField) fp.verifyTimestampField = String(f.verifyTimestampField).trim();\n      if (f.verifyIdleLabel) fp.verifyIdleLabel = String(f.verifyIdleLabel).trim();\n      if (f.verifyRetryLabel) fp.verifyRetryLabel = String(f.verifyRetryLabel).trim();\n      if (f.verifySuccessLabel) fp.verifySuccessLabel = String(f.verifySuccessLabel).trim();\n      // Locked state: sibling keys stored as one normalised comma-separated\n      // string so the value round-trips through the plain Input above and the\n      // consumer only ever has to split on one separator.\n      if (f.verifyLockedWhenFields) {\n        const keys = parseLockFieldKeys(f.verifyLockedWhenFields);\n        if (keys.length) fp.verifyLockedWhenFields = keys.join(',');\n      }\n      if (f.verifyLockedLabel) fp.verifyLockedLabel = String(f.verifyLockedLabel).trim();\n    }\n    if (f.disabledByField) fp.disabledByField = String(f.disabledByField).trim();\n    if (f.requiredIfField) fp.requiredIfField = String(f.requiredIfField).trim();\n    // Override checkbox: the editor holds it as flat inputs (so each one is an\n    // ordinary Form.Item) and it is assembled into the nested object here. A\n    // box that suspends NO validation type is not saved at all — it would\n    // render a control that visibly does nothing.\n    if (f.overrideEnabled) {\n      const skips = String(f.overrideSkipValidations ?? '')\n        .split(',').map((t) => t.trim()).filter(Boolean);\n      if (skips.length) {\n        const oc = { skipValidations: skips };\n        if (f.overrideLabel) oc.label = String(f.overrideLabel).trim();\n        if (f.overrideField) oc.field = String(f.overrideField).trim();\n        if (f.overrideConfirmTitle) oc.confirmTitle = String(f.overrideConfirmTitle).trim();\n        if (f.overrideConfirmBody) oc.confirmBody = String(f.overrideConfirmBody).trim();\n        if (f.overrideConfirmOkText) oc.confirmOkText = String(f.overrideConfirmOkText).trim();\n        if (f.overrideConfirmCancelText) oc.confirmCancelText = String(f.overrideConfirmCancelText).trim();\n        // Stored by default — an explicit false is the only thing worth writing.\n        if (f.overrideStore === false) oc.store = false;\n        fp.overrideCheckbox = oc;\n      }\n    }\n    // Accepts one box or a comma-separated list. Saved as a plain string when\n    // there is one (the original shape, so nothing existing changes) and as an\n    // array when there are several.\n    if (f.linkedClearField) {\n      const keys = String(f.linkedClearField).split(',').map((k) => k.trim()).filter(Boolean);\n      if (keys.length === 1) fp.linkedClearField = keys[0];\n      else if (keys.length > 1) fp.linkedClearField = keys;\n    }\n    if (f.clearGroupOnChange) fp.clearGroupOnChange = true;\n    if (f.splitDialCodeInto) fp.splitDialCodeInto = String(f.splitDialCodeInto).trim();\n    if (f.checkDuplicateOnBlur) fp.checkDuplicateOnBlur = true;\n    // Blank lines are dropped, and a single line is stored as a plain STRING —\n    // the original shape — so a field that only needs one sentence keeps the\n    // document it always had.\n    const helpLines = String(f.helpText ?? '').split('\\n').map((l) => l.trim()).filter(Boolean);\n    if (helpLines.length === 1) fp.helpText = helpLines[0];\n    else if (helpLines.length > 1) fp.helpText = helpLines;\n    // Carried through untouched: the hierarchy is a rule object a seeder tunes\n    // (which date fields bound it, the wording of each clash message), and the\n    // editor only offers an on/off switch. Rewriting it here would flatten it.\n    if (f.rowHierarchyEnabled) fp.rowHierarchy = f.rowHierarchy ?? DEFAULT_ROW_HIERARCHY;\n    if (f.autofillFrom) {\n      try {\n        const parsed = typeof f.autofillFrom === 'string' ? JSON.parse(f.autofillFrom) : f.autofillFrom;\n        if (Array.isArray(parsed) && parsed.length > 0) fp.autofillFrom = parsed;\n      } catch { /* ignore invalid JSON */ }\n    }\n    if (Array.isArray(f.aiActions) && f.aiActions.length > 0) {\n      fp.aiActions = f.aiActions\n        .filter((a) => a?.key && a?.label && a?.serviceKey && a?.endpointPath)\n        .map((a) => ({\n          key: a.key, label: a.label, trigger: a.trigger || 'click',\n          serviceKey: a.serviceKey, endpointPath: a.endpointPath, bodyType: a.bodyType || 'json',\n          inputs: (a.inputs || []).filter((i) => i?.param && i?.sourceField).map((i) => ({\n            param: i.param, sourceField: i.sourceField, kind: i.kind || 'text',\n            ...(i.transform ? { transform: i.transform } : {}),\n            ...(i.group ? { group: i.group } : {}),\n            ...(i.required ? { required: true } : {}),\n            ...(Number(i.minWords) > 0 ? { minWords: Number(i.minWords) } : {}),\n          })),\n          ...(String(a.responseDataPath || '').trim() ? { responseDataPath: String(a.responseDataPath).trim() } : {}),\n          ...(String(a.position || '').trim() ? { position: String(a.position).trim() } : {}),\n          // \"never\" is the engine's own default, so it is left unset rather than\n          // written — an untouched action keeps exactly the document it had.\n          ...(a.confirmWhen && a.confirmWhen !== 'never' ? { confirmWhen: a.confirmWhen } : {}),\n          ...(cleanConfirmMessages(a.confirmMessages) ? { confirmMessages: cleanConfirmMessages(a.confirmMessages) } : {}),\n        }));\n    }\n\n    // Input validator — real-time character restriction from the DB config\n    const validatorType = f.validator?.type;\n    if (validatorType) {\n      fp.validator = { type: validatorType };\n      if (f.validator.title) fp.validator.title = f.validator.title;\n      const ml = Number(f.validator.maxLength);\n      if (!isNaN(ml) && ml > 0) fp.validator.maxLength = ml;\n      const mc = Number(f.validator.maxChars);\n      if (!isNaN(mc) && mc > 0) fp.validator.maxChars = mc;\n    }\n\n    // A location field has no datasource of its own — its options always come\n    // from the location endpoint — so it persists ONLY the single/multi choice.\n    if (f.type === 'location') {\n      fp.multiSelect = f.multiSelect ?? false;\n    }\n\n    if (['select', 'radio', 'checkbox'].includes(f.type)) {\n      const ds = f.dataSource ?? 'static';\n      fp.dataSource = ds;\n      if (f.type === 'select') fp.multiSelect = f.multiSelect ?? false;\n      // Options behaviour — applies to EVERY data source, so it is written here\n      // rather than inside one of the per-source branches below. tokenSeparators\n      // only ships alongside the switch: on its own it configures nothing, and a\n      // leftover value would resurface the day someone re-enables the switch.\n      if (f.allowCustomValues) {\n        fp.allowCustomValues = true;\n        if (f.tokenSeparators !== undefined && String(f.tokenSeparators) !== '') {\n          fp.tokenSeparators = String(f.tokenSeparators);\n        }\n      }\n      if (f.optionsFromField) fp.optionsFromField = String(f.optionsFromField).trim();\n      if (ds === 'master')  fp.masterName       = f.masterName       ?? '';\n      if (ds === 'group') {\n        fp.groupName = f.groupName ?? '';\n        // groupRoleContains — narrow the \"users\" group value to only users\n        // whose role NAME contains this word (e.g. \"manager\" matches Delivery\n        // Manager, Onboarding Manager, Submission Manager, …).\n        if (f.groupRoleContains) fp.groupRoleContains = String(f.groupRoleContains).trim();\n      }\n      if (ds === 'locationMaster') {\n        fp.locationLevel = f.locationLevel || 'country';\n        if (fp.locationLevel === 'state' || fp.locationLevel === 'city') {\n          if (f.locationCountryFrom) fp.locationCountryFrom = String(f.locationCountryFrom).trim();\n        }\n        if (fp.locationLevel === 'city' && f.locationStateFrom) {\n          fp.locationStateFrom = String(f.locationStateFrom).trim();\n        }\n      }\n      if (ds === 'static')  fp.options          = cleanOptions(f.options);\n      if (ds === 'lookup') {\n        fp.lookupCollection = f.lookupCollection ?? '';\n        fp.displayField     = f.displayField     ?? '';\n        if (f.displayField2) fp.displayField2 = f.displayField2;\n        fp.valueField       = f.valueField ?? '_id';\n        if (f.lookupFilterField && f.lookupFilterValueFrom) {\n          fp.lookupFilterField = f.lookupFilterField;\n          fp.lookupFilterValueFrom = f.lookupFilterValueFrom;\n        }\n        // Dropdown conditions — any number of server-evaluated conditions.\n        const lookupFilters = lookupFiltersFromRows(f.lookupFilters);\n        if (lookupFilters.length) fp.lookupFilters = lookupFilters;\n        // Option filters applied in the BROWSER on the returned rows (see\n        // components/form/optionRowFilters.js). They restrict the same way the\n        // Dropdown conditions above do, but survive a backend that does not yet\n        // know lookupFilters. The extraData keys they name are requested\n        // automatically by the form — no separate extraFields entry needed.\n        const requireExtraField = String(f.optionsRequireExtraField ?? '').trim();\n        if (requireExtraField) {\n          fp.optionsRequireExtraField = requireExtraField;\n          const requireExtraValue = String(f.optionsRequireExtraValue ?? '').trim();\n          // Empty is meaningful: it means \"the value must be exactly true\".\n          if (requireExtraValue) fp.optionsRequireExtraValue = requireExtraValue;\n        }\n        const hierarchyParent = String(f.optionsHierarchyParentField ?? '').trim();\n        if (hierarchyParent) {\n          fp.optionsHierarchyParentField = hierarchyParent;\n          fp.optionsHierarchySelfFrom = String(f.optionsHierarchySelfFrom ?? '').trim() || 'currentUserId';\n        }\n        // Quick actions (\"Add More\"/\"Edit\" inside the dropdown). Only emit the\n        // supporting keys when the toggle is on, so clearing a toggle clears them.\n        if (f.quickCreate) {\n          fp.quickCreate = true;\n          if (f.quickCreateModule) fp.quickCreateModule = f.quickCreateModule;\n          // Blank means \"work the wording out from the target list\", which is\n          // the recommended setting. The old literal \"Add More\" is treated the\n          // same way — it is the vague default this replaced, and it is still\n          // stored on live config, so persisting it would keep the old wording\n          // alive forever.\n          if (f.quickCreateLabel && String(f.quickCreateLabel).trim().toLowerCase() !== 'add more') {\n            fp.quickCreateLabel = String(f.quickCreateLabel).trim();\n          }\n          // Post-create notice — only meaningful alongside quickCreate, so it is\n          // written inside this branch: switching quick-create off takes the\n          // notice with it rather than leaving orphaned config behind.\n          const notice = f.quickCreateNotice;\n          if (notice?.enabled) {\n            const out = { enabled: true };\n            // Empty strings are NOT written: absent means \"use the built-in\n            // default\" (notably the approved default message), and writing ''\n            // would instead persist a blank title/message.\n            ['title', 'message', 'recordNameField', 'recordLabel', 'creatorLabel'].forEach((k) => {\n              const v = String(notice[k] ?? '').trim();\n              if (v) out[k] = v;\n            });\n            // Booleans are written explicitly (never omitted) so an admin who\n            // switches a line OFF gets that stored — an omitted false would read\n            // back as the default ON.\n            out.showCreator = notice.showCreator !== false;\n            out.showRecordName = notice.showRecordName !== false;\n            fp.quickCreateNotice = out;\n          }\n        }\n        if (f.quickEdit) {\n          fp.quickEdit = true;\n          if (f.quickEditModule) fp.quickEditModule = f.quickEditModule;\n          // Same rule as the add button: blank (or the old literal \"Add More\",\n          // which live config really does carry on EDIT buttons) means \"work\n          // the wording out from the target list\".\n          if (f.quickEditLabel && String(f.quickEditLabel).trim().toLowerCase() !== 'add more') {\n            fp.quickEditLabel = String(f.quickEditLabel).trim();\n          }\n          if (f.quickEditIdFrom) fp.quickEditIdFrom = f.quickEditIdFrom;\n        }\n      }\n    }\n\n    // Preserve every config key this editor doesn't manage — verifyAction /\n    // verifyResultField / verifyTimestampField, prefillWhen, disabled,\n    // optionsRequireExtraField, extraFields, col, checkboxLabel, and anything\n    // added by future tools/seeds. Without this, saving a group from this\n    // screen silently DESTROYED config authored elsewhere. Keys the editor\n    // owns (already written above, or intentionally clearable) are excluded\n    // so clearing them in the UI still clears them in the DB.\n    for (const [k, v] of Object.entries(f)) {\n      if (v === undefined || v === null || v === '') continue;\n      if (k in fp || FIELD_EDITOR_MANAGED_KEYS.has(k)) continue;\n      fp[k] = v;\n    }\n    return fp;\n  });\n}\n\n// Keys the field editor UI can set OR clear. Their absence from the built\n// payload means \"cleared by the admin\" — never pass them through from the\n// stored field. Everything NOT listed here survives a save untouched.\n\n// Record picker for the field editor's \"Conditional Default\": lists real\n// records from the field's own lookup collection (e.g. employers) so the\n// admin selects the default by NAME instead of pasting a record id. The\n// chosen option's label is kept alongside the id (setValueLabel) so the form\n// can render the default before the lookup resolves.\nfunction LookupRecordSelect({ collection, displayField, valueField, value, labelValue, onChange }) {\n  const [options, setOptions] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const loadedRef = useRef('');\n\n  const load = () => {\n    const key = `${collection}|${displayField}|${valueField}`;\n    if (!collection || !displayField || loadedRef.current === key) return;\n    setLoading(true);\n    getLookupRecordOptions(collection, displayField, valueField || '_id')\n      .then((opts) => { loadedRef.current = key; setOptions(opts); })\n      .catch(() => setOptions([]))\n      .finally(() => setLoading(false));\n  };\n\n  const merged = value && !options.some((o) => o.value === value)\n    ? [{ label: labelValue || value, value }, ...options]\n    : options;\n\n  return (\n    <Select\n      size=\"small\"\n      showSearch\n      allowClear\n      loading={loading}\n      placeholder={collection ? `Pick from ${collection}` : 'Configure a lookup first'}\n      disabled={!collection || !displayField}\n      style={{ width: 220 }}\n      optionFilterProp=\"label\"\n      options={merged}\n      value={value || undefined}\n      onDropdownVisibleChange={(open) => { if (open) load(); }}\n      onChange={(v, option) => onChange(v ?? '', option?.label ?? '')}\n      getPopupContainer={() => document.body}\n    />\n  );\n}\n\nconst FIELD_EDITOR_MANAGED_KEYS = new Set([\n  'label', 'field', 'type', 'show', 'req', 'edit', 'order', 'formatter',\n  'validations', 'showOnAdd', 'addRow', 'minRows', 'maxRows', 'initialRows',\n  'addLabel', 'subFields', 'placeholder', 'hidePlaceholder', 'combineKey',\n  'combineLabel', 'combineRole', 'combineToggleLabel', 'combineToggleTarget',\n  'combineWidth', 'combineWrap', 'combineSpan', 'defaultOnEdit', 'noPrefill', 'emptyValues',\n  'valuePaths', 'clientScope', 'clientGateMessage', 'clientGateResetOnChange',\n  'visiblePermission', 'editablePermission', 'infoEnabled', 'infoText', 'tooltip',\n  'helpText', 'payloadKey', 'prefillFrom', 'prefillFromModule', 'dataType', 'elementType',\n  'prefillAsHint', 'prefillHintLabel',\n  'payloadMode', 'valueKey', 'displayKey', 'defaultValue', 'richValue',\n  'omitEmpty', 'payloadTemplate', 'transformRule', 'multiple', 'maxCount',\n  'fileKey', 'fileNameKey', 'fileUrlKey', 'accept', 'showIf', 'labelWhen',\n  // Conditional Width: the stored array plus the flat editor-only inputs that\n  // build it (the flat keys must never reach the saved document).\n  'colWhen', 'colWhenField', 'colWhenOperator', 'colWhenValue', 'colWhenCol',\n  'verifyAction', 'verifyResultField', 'verifyTimestampField', 'prefillWhen', 'prefillWhenReset',\n  'prefillWhenExclusive',\n  'verifyIdleLabel', 'verifyRetryLabel', 'verifySuccessLabel',\n  'verifyLockedWhenFields', 'verifyLockedLabel',\n  'disabledByField', 'requiredIfField', 'linkedClearField', 'clearGroupOnChange', 'splitDialCodeInto',\n  'overrideCheckbox', 'overrideEnabled', 'overrideLabel', 'overrideField',\n  'overrideSkipValidations', 'overrideConfirmTitle', 'overrideConfirmBody',\n  'overrideConfirmOkText', 'overrideConfirmCancelText', 'overrideStore',\n  'checkDuplicateOnBlur', 'rowHierarchy',\n  'exclusiveInGroup', 'autofillFrom', 'aiActions',\n  'validator', 'dataSource', 'masterName', 'groupName', 'groupRoleContains', 'options',\n  'multiSelect', 'lookupCollection', 'displayField', 'displayField2',\n  'valueField', 'lookupFilterField', 'lookupFilterValueFrom', 'lookupFilters',\n  'locationLevel', 'locationCountryFrom', 'locationStateFrom',\n  'optionsRequireExtraField', 'optionsRequireExtraValue',\n  'optionsHierarchyParentField', 'optionsHierarchySelfFrom',\n  'allowCustomValues', 'tokenSeparators', 'optionsFromField',\n  'quickCreate', 'quickCreateModule', 'quickCreateLabel', 'quickCreateNotice',\n  'quickEdit', 'quickEditModule', 'quickEditLabel', 'quickEditIdFrom',\n  // Runtime-only keys the GET response may carry — never persist them.\n  'value', 'documentPreview', 'displayAs', 'renderType', 'renderOptions',\n]);\n\n// Same idea at GROUP level: keys the group editor sets/clears itself, plus\n// runtime-only keys from the GET response. Anything else on a stored group\n// (payloadKey, sharedRowLabels, showIf, writeRefs variants, …) passes through a\n// save untouched. linkField/linkTypeField/parentRefField ARE managed here (the\n// Linkage section owns them) so switching mode clears the other mode's key.\nconst GROUP_EDITOR_MANAGED_KEYS = new Set([\n  'module', 'name', 'label', 'addRow', 'order', 'fields', 'hideGroup', 'hideGroupInForm',\n  'moduleName', 'linkField', 'linkTypeField', 'parentRefField',\n  'hierarchyLevel', 'hierarchyParent', 'hierarchyLinkField',\n  'writeRefs', 'dependsOn', 'optionalWrite', 'appendHistory',\n  'allowCollapse', 'defaultCollapsed',\n  'historyField', 'historyFields', 'historyTimestampField',\n  'historyLabels', 'historyLabelFrom', 'historyAfterGroup',\n  'historyAmountFields', 'historyCurrencyFields', 'historyUnitFields',\n  'minRows', 'maxRows', 'initialRows',\n  'requireOne', 'requireValidatedField', 'requireValidatedFieldMessage', 'submitDisabledMessage',\n  'allowInProgress', 'inProgressMessage', 'orderBy', 'orderByEnabled',\n  'levelRule', 'levelRuleEnabled', 'regionRules',\n  'linkGroup', 'mergeInto', 'mergePosition', 'infoEnabled',\n  'infoText', 'toggleEnabled', 'toggleLabel', 'toggleField', 'afterSubmit',\n  'showIf', 'showIfField', 'showIfOperator', 'showIfValue',\n  'disabled', 'disabledIf', 'disabledIfField', 'disabledIfOperator', 'disabledIfValue',\n  'formActions',\n  'afterSubmitMode', 'afterSubmitTarget', 'submitMessages',\n  'submitMsgAddSuccess', 'submitMsgEditSuccess', 'submitMsgAddError',\n  'submitMsgEditError', 'submitMsgSuppress',\n  // Runtime-only / identity keys — never persist into the groups array.\n  'id', '_id', 'rows', 'toggleValue',\n]);\n\nfunction initFieldValues(f) {\n  return {\n    ...f,\n    show: f.show === 1, req: f.req === 1, edit: f.edit === 1,\n    showOnAdd: f.showOnAdd !== false,\n    addRow: f.addRow ?? false,\n    minRows: f.minRows ?? '',\n    maxRows: f.maxRows ?? '',\n    initialRows: f.initialRows ?? '',\n    addLabel: f.addLabel ?? '',\n    subFields: Array.isArray(f.subFields) ? f.subFields.map((s) => ({\n      field: s.field ?? '',\n      label: s.label ?? '',\n      type: s.type ?? 'text',\n      req: s.req === 1 || s.req === true,\n      col: s.col ?? '',\n      payloadKey: s.payloadKey ?? '',\n      dataSource: s.dataSource ?? 'static',\n      multiSelect: s.multiSelect ?? false,\n      masterName: s.masterName ?? '',\n      groupName: s.groupName ?? '',\n      options: Array.isArray(s.options) ? s.options : [],\n      lookupCollection: s.lookupCollection ?? '',\n      displayField: s.displayField ?? '',\n      displayField2: s.displayField2 ?? '',\n      valueField: s.valueField ?? '_id',\n      lookupFilterField: s.lookupFilterField ?? '',\n      lookupFilterValueFrom: s.lookupFilterValueFrom ?? '',\n    })) : [],\n    placeholder: f.placeholder ?? '',\n    hidePlaceholder: f.hidePlaceholder ?? false,\n    clientScope:        f.clientScope        ?? false,\n    clientGateMessage:  f.clientGateMessage  ?? '',\n    clientGateResetOnChange: f.clientGateResetOnChange ?? false,\n    visiblePermission:  f.visiblePermission  ?? '',\n    editablePermission: f.editablePermission ?? '',\n    infoEnabled:        f.infoEnabled        ?? false,\n    infoText:         f.infoText         ?? '',\n    tooltip:          f.tooltip          ?? '',\n    // A stored LIST round-trips into the textarea as one line each, so editing\n    // it does not collapse the lines into \"line one,line two\".\n    helpText: Array.isArray(f.helpText) ? f.helpText.join('\\n') : (f.helpText ?? ''),\n    formatter:        f.formatter        ?? '',\n    combineKey:       f.combineKey       ?? '',\n    combineLabel:     f.combineLabel     ?? '',\n    combineRole:      f.combineRole      ?? '',\n    combineToggleLabel:  f.combineToggleLabel  ?? '',\n    combineToggleTarget: f.combineToggleTarget ?? '',\n    combineWidth:        f.combineWidth        ?? '',\n    combineWrap:         f.combineWrap         ?? false,\n    combineSpan:         f.combineSpan         ?? '',\n    defaultOnEdit:       f.defaultOnEdit       ?? false,\n    noPrefill:           f.noPrefill           ?? false,\n    emptyValues:         Array.isArray(f.emptyValues) ? f.emptyValues.join(', ') : (f.emptyValues ?? ''),\n    valuePaths:          Array.isArray(f.valuePaths) ? f.valuePaths.join(', ') : (f.valuePaths ?? ''),\n    booleanCapable:   f.booleanCapable   ?? false,\n    // Stored as an array when one control feeds several params; the editor\n    // shows it as the comma-joined option value.\n    booleanApiKey:    Array.isArray(f.booleanApiKey) ? f.booleanApiKey.join(',') : (f.booleanApiKey ?? ''),\n    booleanPlaceholder: f.booleanPlaceholder ?? '',\n    min:              f.min ?? '',\n    max:              f.max ?? '',\n    display:          f.display ?? 'both',\n    // What the two ends READ AS. Blank means \"show the number itself\", which\n    // is why they load as '' rather than falling back to min/max here — the\n    // component owns that fallback, so changing Max also moves the label.\n    minLabel:         f.minLabel ?? '',\n    maxLabel:         f.maxLabel ?? '',\n    unit:             f.unit ?? '',\n    rangeKeys:        Array.isArray(f.rangeKeys) ? f.rangeKeys.join(',') : (f.rangeKeys ?? ''),\n    filterField:      f.filterField ?? '',\n    hideSelectAll:    f.hideSelectAll ?? false,\n    dataSource:       f.dataSource       ?? 'static',\n    masterName:       f.masterName       ?? '',\n    groupName:        f.groupName        ?? '',\n    groupRoleContains: f.groupRoleContains ?? '',\n    options:          f.options          ?? [],\n    lookupCollection: f.lookupCollection ?? '',\n    displayField:     f.displayField     ?? '',\n    displayField2:    f.displayField2    ?? '',\n    valueField:       f.valueField       ?? '_id',\n    lookupFilterField:     f.lookupFilterField     ?? '',\n    lookupFilterValueFrom: f.lookupFilterValueFrom ?? '',\n    locationLevel:        f.locationLevel        ?? 'country',\n    locationCountryFrom:  f.locationCountryFrom  ?? '',\n    locationStateFrom:    f.locationStateFrom    ?? '',\n    lookupFilters:         lookupFiltersToRows(f.lookupFilters),\n    // Browser-side option filters (optionRowFilters.js). Loaded here so the\n    // editor round-trips config authored by a seeder instead of dropping it —\n    // these keys are now editor-MANAGED, i.e. absence on save means \"cleared\".\n    optionsRequireExtraField:    f.optionsRequireExtraField    ?? '',\n    optionsRequireExtraValue:    f.optionsRequireExtraValue    ?? '',\n    optionsHierarchyParentField: f.optionsHierarchyParentField ?? '',\n    optionsHierarchySelfFrom:    f.optionsHierarchySelfFrom    ?? '',\n    // Options behaviour (works for every data source, not just lookup).\n    allowCustomValues: f.allowCustomValues ?? false,\n    tokenSeparators:   f.tokenSeparators   ?? '',\n    optionsFromField:  f.optionsFromField  ?? '',\n    quickCreate:       f.quickCreate       ?? false,\n    quickCreateModule: f.quickCreateModule ?? '',\n    quickCreateLabel:  f.quickCreateLabel  ?? '',\n    quickEdit:         f.quickEdit         ?? false,\n    quickEditModule:   f.quickEditModule   ?? '',\n    quickEditLabel:    f.quickEditLabel    ?? '',\n    quickEditIdFrom:   f.quickEditIdFrom   ?? '',\n    // Post-create notice. The two \"show\" flags default ON (absent = show), which\n    // is how the runtime reads them too — the editor must not present a\n    // different default from the one the form actually applies.\n    quickCreateNotice: {\n      enabled:         f.quickCreateNotice?.enabled ?? false,\n      title:           f.quickCreateNotice?.title ?? '',\n      message:         f.quickCreateNotice?.message ?? '',\n      showCreator:     f.quickCreateNotice?.showCreator !== false,\n      showRecordName:  f.quickCreateNotice?.showRecordName !== false,\n      recordNameField: f.quickCreateNotice?.recordNameField ?? '',\n      recordLabel:     f.quickCreateNotice?.recordLabel ?? '',\n      creatorLabel:    f.quickCreateNotice?.creatorLabel ?? '',\n    },\n    multiSelect:      f.multiSelect      ?? false,\n    multiple:         f.multiple         ?? false,\n    maxCount:         f.maxCount         ?? 5,\n    accept:           f.accept           ?? 'any',\n    fileKey:          f.fileKey          ?? '',\n    fileNameKey:      f.fileNameKey      ?? '',\n    fileUrlKey:       f.fileUrlKey       ?? '',\n    // Payload-engine config\n    payloadKey:       f.payloadKey       ?? '',\n    prefillFrom:      f.prefillFrom      ?? '',\n    // Read back so it ROUND-TRIPS. A key the editor never loads is a setting\n    // that appears to save and then vanishes on the next edit, because the save\n    // writes back the blank the editor was holding.\n    prefillAsHint:    Boolean(f.prefillAsHint),\n    prefillHintLabel: f.prefillHintLabel ?? '',\n    prefillFromModule: f.prefillFromModule ?? '',\n    prefillWhen:      Array.isArray(f.prefillWhen) ? f.prefillWhen : [],\n    prefillWhenReset: f.prefillWhenReset !== false,\n    prefillWhenExclusive: f.prefillWhenExclusive === true,\n    dataType:         f.dataType         ?? 'auto',\n    elementType:      f.elementType      ?? '',\n    payloadMode:      f.payloadMode      ?? 'auto',\n    valueKey:         f.valueKey         ?? '',\n    displayKey:       f.displayKey       ?? '',\n    defaultValue:     f.defaultValue     ?? '',\n    richValue:        f.richValue        ?? false,\n    omitEmpty:        f.omitEmpty        ?? false,\n    payloadTemplate:  stringifyObject(f.payloadTemplate),\n    transformRule:    stringifyObject(f.transformRule),\n    showIf: (f.showIf?.field || f.showIf?.conditions?.length)\n      ? {\n          field: f.showIf.field ?? '', operator: f.showIf.operator ?? 'eq', value: f.showIf.value ?? '',\n          logic: f.showIf.logic === 'or' ? 'or' : 'and',\n          conditions: Array.isArray(f.showIf.conditions)\n            ? f.showIf.conditions.map((c) => ({ field: c.field ?? '', operator: c.operator ?? 'eq', value: c.value ?? '' }))\n            : [],\n        }\n      : { field: '', operator: 'eq', value: '', logic: 'and', conditions: [] },\n    labelWhen: f.labelWhen?.field\n      ? { field: f.labelWhen.field, operator: f.labelWhen.operator ?? 'eq', value: f.labelWhen.value ?? '', label: f.labelWhen.label ?? '' }\n      : { field: '', operator: 'eq', value: '', label: '' },\n    // Conditional Width — flatten the stored rule list into the editor inputs.\n    colWhenField:    (Array.isArray(f.colWhen) ? f.colWhen[0]?.field : f.colWhen?.field) ?? '',\n    colWhenOperator: (Array.isArray(f.colWhen) ? f.colWhen[0]?.operator : f.colWhen?.operator) ?? 'eq',\n    colWhenValue:    (Array.isArray(f.colWhen) ? f.colWhen[0]?.value : f.colWhen?.value) ?? '',\n    colWhenCol:      (Array.isArray(f.colWhen) ? f.colWhen[0]?.col : f.colWhen?.col) ?? undefined,\n    verifyAction:         f.verifyAction         ?? '',\n    verifyResultField:    f.verifyResultField    ?? '',\n    verifyTimestampField: f.verifyTimestampField ?? '',\n    verifyIdleLabel:      f.verifyIdleLabel      ?? '',\n    verifyRetryLabel:     f.verifyRetryLabel     ?? '',\n    verifySuccessLabel:   f.verifySuccessLabel   ?? '',\n    // Stored as a comma-separated string; an array left by an older seed still\n    // loads into the text input rather than showing \"[object Object]\".\n    verifyLockedWhenFields: parseLockFieldKeys(f.verifyLockedWhenFields).join(', '),\n    verifyLockedLabel:    f.verifyLockedLabel    ?? '',\n    validations: (f.validations ?? []).map((v) => ({\n      // `field` rides alongside `value` so a stored maxFromField rule loads back\n      // into the sibling-field picker instead of silently emptying on the next save.\n      // `value` is a scalar for every rule except `unique`, whose value is a\n      // config OBJECT — `??` passes objects through untouched, and the extra\n      // normalize below only materialises defaults for a config saved before a\n      // setting existed, so the editor never shows a blank where the runtime\n      // would apply a default.\n      type: v.type,\n      value: v.type === UNIQUE_VALIDATION_TYPE ? normalizeUniqueConfig(v.value, f) : (v.value ?? ''),\n      field: v.field ?? '', message: v.message ?? '',\n      // Date-pair options must load back or the next save silently strips them\n      // — the exact failure mode that makes a config screen untrustworthy.\n      strict: Boolean(v.strict),\n      minGap: { value: v.minGap?.value ?? '', unit: v.minGap?.unit ?? 'month' },\n      minGapFrom: v.minGapFrom ?? '',\n    })),\n    validator: {\n      type:      f.validator?.type      ?? '',\n      title:     f.validator?.title     ?? '',\n      maxLength: f.validator?.maxLength ?? '',\n      maxChars:  f.validator?.maxChars  ?? '',\n    },\n    disabledByField:  f.disabledByField  ?? '',\n    requiredIfField:  f.requiredIfField  ?? '',\n    overrideEnabled:           Boolean(f.overrideCheckbox),\n    overrideLabel:             f.overrideCheckbox?.label ?? '',\n    overrideField:             f.overrideCheckbox?.field ?? '',\n    overrideSkipValidations:   Array.isArray(f.overrideCheckbox?.skipValidations)\n      ? f.overrideCheckbox.skipValidations.join(', ')\n      : (f.overrideCheckbox?.skipValidations ?? ''),\n    overrideConfirmTitle:      f.overrideCheckbox?.confirmTitle ?? '',\n    overrideConfirmBody:       f.overrideCheckbox?.confirmBody ?? '',\n    overrideConfirmOkText:     f.overrideCheckbox?.confirmOkText ?? '',\n    overrideConfirmCancelText: f.overrideCheckbox?.confirmCancelText ?? '',\n    overrideStore:             f.overrideCheckbox?.store !== false,\n    // An array round-trips back into the comma-separated text input rather than\n    // rendering as \"[object Object]\".\n    linkedClearField: Array.isArray(f.linkedClearField)\n      ? f.linkedClearField.join(', ')\n      : (f.linkedClearField ?? ''),\n    clearGroupOnChange: Boolean(f.clearGroupOnChange),\n    splitDialCodeInto: f.splitDialCodeInto ?? '',\n    checkDuplicateOnBlur: Boolean(f.checkDuplicateOnBlur),\n    rowHierarchyEnabled: Boolean(f.rowHierarchy),\n    rowHierarchy: f.rowHierarchy ?? null,\n    autofillFrom: Array.isArray(f.autofillFrom) ? JSON.stringify(f.autofillFrom, null, 2) : (f.autofillFrom ?? ''),\n    aiActions: Array.isArray(f.aiActions) ? f.aiActions.map((a) => ({\n      ...a,\n      inputs: (a.inputs ?? []).map((i) => ({ ...i, minWords: i.minWords ?? '' })),\n      responseDataPath: a.responseDataPath ?? '',\n      confirmWhen: a.confirmWhen ?? 'never',\n      confirmMessages: {\n        title: a.confirmMessages?.title ?? '',\n        body: a.confirmMessages?.body ?? '',\n        ok: a.confirmMessages?.ok ?? '',\n        cancel: a.confirmMessages?.cancel ?? '',\n      },\n      position: a.position ?? '',\n    })) : [],\n  };\n}\n\n// ── buildHierarchyChainPreview ────────────────────────────────────────────────\n// Read-only preview line for the Hierarchy block, e.g.\n// \"users → trainers.userId → trainer_availability.trainerId\". Walks parent\n// links across the module's OTHER groups starting from the draft values being\n// edited right now. Returns '' (render nothing) whenever the chain can't be\n// fully resolved — a broken/partial chain is worse than no preview at all.\nfunction buildHierarchyChainPreview(mainModule, ownTarget, hierarchyParent, hierarchyLinkField, siblingGroups) {\n  if (!ownTarget || !hierarchyParent || !String(hierarchyLinkField ?? '').trim()) return '';\n  const byTarget = new Map();\n  siblingGroups.forEach((g) => { if (g.moduleName) byTarget.set(g.moduleName, g); });\n  // Segments closest-ancestor-first; unshift as we walk upward toward the root.\n  const segments = [`${ownTarget}.${hierarchyLinkField.trim()}`];\n  let cursor = hierarchyParent;\n  const seen = new Set([ownTarget]);\n  let guard = 0;\n  while (cursor && cursor !== mainModule && guard < 10) {\n    if (seen.has(cursor)) return ''; // cyclical draft — nothing sensible to preview\n    seen.add(cursor);\n    const g = byTarget.get(cursor);\n    if (!g || !g.hierarchyLinkField) {\n      // Parent collection isn't itself chained any further — it's the root of\n      // what we know; stop here rather than guessing at anything above it.\n      segments.unshift(cursor);\n      return segments.join(' → ');\n    }\n    segments.unshift(`${g.moduleName}.${g.hierarchyLinkField}`);\n    cursor = g.hierarchyParent;\n    guard += 1;\n  }\n  if (cursor === mainModule) segments.unshift(mainModule);\n  else return ''; // unresolved beyond the guard / unknown root\n  return segments.join(' → ');\n}\n\n// ── useModuleCollections ──────────────────────────────────────────────────────\n// Resolves module key → stored collection name for DISPLAY only (the resolved\n// target strip under a uniqueness rule). Sourced from the module registry, so a\n// collection name is never something an admin types and never something this\n// screen invents; when the registry can't be read the resolver returns '' and\n// the UI says the collection is resolved on the server, which it always is.\nfunction useModuleCollections() {\n  const [map, setMap] = useState({});\n  useEffect(() => {\n    let cancelled = false;\n    getModuleCollectionMap()\n      .then((next) => { if (!cancelled) setMap(next ?? {}); })\n      .catch(() => { /* display-only — a failure must never block the editor */ });\n    return () => { cancelled = true; };\n  }, []);\n  return useMemo(\n    () => (moduleKey) => map[String(moduleKey ?? '').trim().toLowerCase()] ?? '',\n    [map],\n  );\n}\n\n// ── renderFieldRows ───────────────────────────────────────────────────────────\n// Shared JSX helper that renders the field editor rows for one group's Form.List.\n// absBase = []                for GroupDrawer  (fields live at form root)\n// absBase = ['groups', gName] for CustomFormDrawer\nfunction renderFieldRows({\n  form, fieldItems, add, remove, move,\n  absBase, moduleFieldOptions,\n  dragIndexRef, dragOverIndex, setDragOverIndex,\n  onFieldKeySelect,\n  expandedFieldKeys,\n  onToggleField,\n  defaultFieldSet = new Set(),\n  // Where a unique rule configured on one of these fields actually lands.\n  // `getTargetModule` is read live (the group's Target Collection can change\n  // while the drawer is open) and `collectionForModule` reads the module\n  // registry — the admin never types a collection name anywhere.\n  uniqueTarget = { primaryModule: '', getTargetModule: () => '', collectionForModule: () => '' },\n}) {\n  const fieldsAbs = [...absBase, 'fields'];\n\n  return (\n    <>\n      {fieldItems.map(({ key, name: rowName, ...restField }, fieldIndex) => {\n        const fAbs = [...fieldsAbs, rowName];\n        const fieldValue = form.getFieldValue(fAbs) ?? {};\n        const isCollapsed = expandedFieldKeys && !expandedFieldKeys.has(fieldIndex);\n        // Search forms are rendered by SearchBuilderV1, which knows a few input\n        // types the add/edit engine does not.\n        const isSearchForm = form.getFieldValue('formType') === 'search';\n        return (\n          <div\n            key={key}\n            draggable\n            onDragStart={() => { dragIndexRef.current = fieldIndex; }}\n            onDragEnd={() => { dragIndexRef.current = null; setDragOverIndex(null); }}\n            onDragOver={(e) => { e.preventDefault(); setDragOverIndex(fieldIndex); }}\n            onDragLeave={() => setDragOverIndex(null)}\n            onDrop={(e) => {\n              e.preventDefault();\n              const from = dragIndexRef.current;\n              if (from !== null && from !== fieldIndex) move(from, fieldIndex);\n              dragIndexRef.current = null;\n              setDragOverIndex(null);\n            }}\n            className={`fg-field-card${dragOverIndex === fieldIndex ? ' fg-drag-over' : ''}`}\n          >\n            <div className=\"fg-field-card-inner\">\n              <span className=\"fg-drag-handle\"><HolderOutlined /></span>\n              {isCollapsed ? (\n                <div className=\"fg-field-summary\">\n                  <button type=\"button\" className=\"fg-field-summary-main\" onClick={() => onToggleField(fieldIndex)}>\n                    <RightOutlined className=\"fg-field-summary-chevron\" />\n                    <span>\n                      <strong>{fieldValue.label || fieldValue.field || `Field ${fieldIndex + 1}`}</strong>\n                      <small>{fieldValue.field || 'Field key not set'} · {fieldValue.type || 'text'}</small>\n                    </span>\n                  </button>\n                  <Space size={4}>\n                    {fieldValue.req && <Tag color=\"red\">Required</Tag>}\n                    {fieldValue.show === false && <Tag>Hidden</Tag>}\n                    <Tooltip title=\"Edit field settings\">\n                      <Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => onToggleField(fieldIndex)} />\n                    </Tooltip>\n                    <Tooltip title=\"Remove field\">\n                      <Button type=\"text\" size=\"small\" danger icon={<MinusCircleOutlined />} onClick={() => remove(rowName)} />\n                    </Tooltip>\n                  </Space>\n                </div>\n              ) : (\n                <>\n              <div className=\"fg-field-body\">\n\n                {expandedFieldKeys && (\n                  <button type=\"button\" className=\"fg-field-collapse-btn\" onClick={() => onToggleField(fieldIndex)}>\n                    <DownOutlined /> Collapse field\n                  </button>\n                )}\n\n                <Form.Item\n                  {...restField}\n                  name={[rowName, 'field']}\n                  label=\"Field\"\n                  style={{ marginBottom: 10 }}\n                  rules={[{ required: true, message: 'Required' }]}\n                >\n                  <AutoComplete\n                    options={moduleFieldOptions}\n                    placeholder=\"Search or type field key…\"\n                    filterOption={(input, opt) => (opt?.searchLabel ?? '').includes(input.toLowerCase())}\n                    onSelect={(val) => onFieldKeySelect(val, rowName)}\n                    className=\"fg-mono-input\"\n                  />\n                </Form.Item>\n\n                <div className=\"fg-field-meta-row\">\n                  <Form.Item {...restField} name={[rowName, 'label']} label=\"Label\"\n                    style={{ marginBottom: 8, flex: 2 }} rules={[{ required: true, message: 'Required' }]}>\n                    <Input size=\"small\" placeholder=\"Display label\" />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'type']} label=\"Type\"\n                    style={{ marginBottom: 8, flex: 2 }} initialValue=\"text\">\n                    <Select size=\"small\" options={isSearchForm ? [...FIELD_TYPES, ...SEARCH_ONLY_FIELD_TYPES] : FIELD_TYPES} />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'formatter']} label=\"Formatter\"\n                    style={{ marginBottom: 8, flex: 2 }}>\n                    <Input size=\"small\" placeholder=\"name / phone…\" />\n                  </Form.Item>\n                </div>\n\n                <div className=\"fg-options-block\">\n                  <span className=\"fg-options-label\">Layout / Combine</span>\n                  <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                    <Form.Item name={[rowName, 'combineKey']} label=\"Combine Key\"\n                      style={{ marginBottom: 0 }}\n                      tooltip=\"Fields with the same key render together as one visual block. Payload stays unchanged.\">\n                      <Input size=\"small\" placeholder=\"e.g. client_rate\" style={{ width: 150 }} className=\"fg-mono-input\" />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineLabel']} label=\"Combined Label\"\n                      style={{ marginBottom: 0 }}>\n                      <Input size=\"small\" placeholder=\"e.g. Client Rate\" style={{ width: 160 }} />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineRole']} label=\"Role\"\n                      style={{ marginBottom: 0 }}>\n                      <Select size=\"small\" style={{ width: 120 }} allowClear options={[\n                        { label: 'Primary', value: 'primary' },\n                        { label: 'From', value: 'from' },\n                        { label: 'To', value: 'to' },\n                        { label: 'Currency', value: 'currency' },\n                        { label: 'Unit', value: 'unit' },\n                      ]} />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineToggleLabel']} label=\"Toggle Label\"\n                      style={{ marginBottom: 0 }}>\n                      <Input size=\"small\" placeholder=\"e.g. Range\" style={{ width: 130 }} />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineToggleTarget']} label=\"Toggle Target\"\n                      style={{ marginBottom: 0 }}\n                      tooltip=\"Field key hidden until the combined-field slider is enabled. Example: clientRateTo.\">\n                      <Input size=\"small\" placeholder=\"target field key\" style={{ width: 150 }} className=\"fg-mono-input\" />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineWidth']} label=\"Width\"\n                      style={{ marginBottom: 0 }}\n                      tooltip=\"Width weight of this box inside the combined block. Set the same key's fields to e.g. 2 & 1 for 2:1, or 1/2/3 for 1:2:3. Blank/0 = equal share.\">\n                      <Input size=\"small\" type=\"number\" min={0} step={0.5} placeholder=\"1\" style={{ width: 80 }} />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineWrap']} label=\"Wrap\" valuePropName=\"checked\"\n                      style={{ marginBottom: 0 }}\n                      tooltip=\"Allow this combined block to wrap to another line. Useful for wider controls such as document upload rows.\">\n                      <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'combineSpan']} label=\"Block Span\"\n                      style={{ marginBottom: 0 }}\n                      tooltip=\"How much row width this combined block uses. Blank keeps the existing automatic layout.\">\n                      <Select size=\"small\" allowClear placeholder=\"Auto\" style={{ width: 110 }} options={[\n                        { label: 'Half', value: 12 },\n                        { label: 'Full', value: 24 },\n                      ]} />\n                    </Form.Item>\n                  </div>\n                </div>\n\n                {/* Boolean search — search forms only, and only once the form-level\n                    \"Enable Boolean Search\" switch is on. That switch is the global\n                    gate the whole feature hangs off (Form Identity section below);\n                    while it's off, a search form has no boolean options to set at\n                    all, matching runtime behaviour exactly (no switch off ⇒ no\n                    per-field capability is ever consulted). */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (getFieldValue('formType') !== 'search') return null;\n                    if (!getFieldValue('booleanSearchEnabled')) return null;\n                    const fType = getFieldValue([...fAbs, 'type']) ?? 'text';\n                    const apiKey = getFieldValue([...fAbs, 'booleanApiKey']);\n                    // Only 4 request params are actually parsed as an expression\n                    // server-side (Be_Auth_DevOps candidateBooleanSearchController.go\n                    // — query/skills/jobTitle/designation). Everything else\n                    // (currentLocation, experience.*, sourceType, …) is a plain\n                    // match, so \"Boolean capable\" is only offered once the field is\n                    // mapped to one of those four — this is what keeps an admin from\n                    // ever authoring \"boolean-capable field whose query is silently\n                    // ignored,\" rather than merely warning about it after the fact.\n                    const canBeBooleanCapable = BOOLEAN_ELIGIBLE_TYPES.includes(fType)\n                      && BOOLEAN_PARSEABLE_API_KEYS.includes(apiKey);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Boolean Search</span>\n                        <div className=\"fg-options-controls\">\n                          <Form.Item name={[rowName, 'booleanApiKey']} label=\"Boolean API key\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Which boolean-search request parameter this field fills. Needed by plain fields too — without it the field is not sent in Boolean mode.\">\n                            <Select size=\"small\" allowClear style={{ width: 240 }}\n                              placeholder=\"Not sent\" options={BOOLEAN_API_KEY_OPTIONS} />\n                          </Form.Item>\n                          {canBeBooleanCapable ? (\n                            <>\n                              <Form.Item name={[rowName, 'booleanCapable']} label=\"Boolean capable\"\n                                valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}\n                                tooltip=\"When the user turns the Boolean toggle on, this field becomes an AND/OR/NOT expression box. Fields left off keep their normal control in both modes.\">\n                                <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                              </Form.Item>\n                              {getFieldValue([...fAbs, 'booleanCapable']) && (\n                                <Form.Item name={[rowName, 'booleanPlaceholder']} label=\"Example expression\"\n                                  style={{ marginBottom: 0 }}\n                                  tooltip=\"Shown inside this field's expression box. Give an example using THIS field's own vocabulary — blank falls back to one generic example shared by every boolean field.\">\n                                  <Input size=\"small\" style={{ width: 360 }}\n                                    placeholder='e.g., (Java OR J2EE) AND \"Spring Boot\" NOT PHP' />\n                                </Form.Item>\n                              )}\n                            </>\n                          ) : (\n                            BOOLEAN_ELIGIBLE_TYPES.includes(fType) && (\n                              <span className=\"fg-options-hint\">\n                                Set the API key to query, skills, jobTitle or designation to allow Boolean mode on this field.\n                              </span>\n                            )\n                          )}\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Select All — search forms only. Automatic, not per-option: any\n                    checkbox field with more than one option gets an \"All\" checkbox\n                    for free (SearchBuilderV1's checkbox renderer synthesizes it —\n                    it is never one of the options above). This is the one opt-out,\n                    on by default, for a field where that doesn't make sense. */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (getFieldValue('formType') !== 'search') return null;\n                    if (getFieldValue([...fAbs, 'type']) !== 'checkbox') return null;\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Select All</span>\n                        <div className=\"fg-options-controls\">\n                          <Form.Item name={[rowName, 'hideSelectAll']} label=\"Show 'All' checkbox\"\n                            valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}\n                            // Field stores hideSelectAll; the switch shows the\n                            // opposite so \"on\" reads as \"the All checkbox shows\".\n                            getValueProps={(checked) => ({ checked: !checked })}\n                            normalize={(checked) => !checked}\n                            tooltip=\"On by default. Turn off if this field's options should never offer a select-everything shortcut.\">\n                            <Switch size=\"small\" checkedChildren=\"Shown\" unCheckedChildren=\"Hidden\" />\n                          </Form.Item>\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Range / number bounds */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const fType = getFieldValue([...fAbs, 'type']);\n                    if (!['range', 'number'].includes(fType)) return null;\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">{fType === 'range' ? 'Range' : 'Bounds'}</span>\n                        <div className=\"fg-options-controls\">\n                          <Form.Item name={[rowName, 'min']} label=\"Min\" style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" type=\"number\" placeholder=\"0\" style={{ width: 90 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'max']} label=\"Max\" style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" type=\"number\" placeholder=\"30\" style={{ width: 90 }} />\n                          </Form.Item>\n                          {fType === 'range' && (\n                            <>\n                              <Form.Item name={[rowName, 'display']} label=\"Show as\"\n                                style={{ marginBottom: 0 }} initialValue=\"both\"\n                                tooltip=\"Drag bar, plain From/To boxes, or both. Switch to From / To if the horizontal slider is not wanted.\">\n                                <Select size=\"small\" style={{ width: 170 }} options={RANGE_DISPLAY_OPTIONS} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'minLabel']} label=\"Start label\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"What the LOW end reads as under the track. Blank shows the Min number itself.\">\n                                <Input size=\"small\" placeholder=\"0\" style={{ width: 110 }} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'maxLabel']} label=\"End label\"\n                                style={{ marginBottom: 0 }}\n                                tooltip={'What the HIGH end reads as under the track. Use it to mark an open ceiling: with Max 30, \"30+\" reads as \"30 or more\" where a bare 30 reads as an exact value. Blank shows the Max number itself.'}>\n                                <Input size=\"small\" placeholder=\"30+\" style={{ width: 110 }} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'unit']} label=\"Unit\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Caption shown after the From / To boxes, e.g. Years. Leave blank when the field label already names the unit.\">\n                                <Input size=\"small\" placeholder=\"Years\" style={{ width: 110 }} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'rangeKeys']} label=\"From / To params\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Comma-separated query params this range fills in normal search, e.g. experienceFrom,experienceTo. Blank uses <field>From / <field>To.\">\n                                <Input size=\"small\" placeholder=\"experienceFrom,experienceTo\"\n                                  style={{ width: 220 }} className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </>\n                          )}\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Created Date-style preset range */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (getFieldValue([...fAbs, 'type']) !== 'daterangePreset') return null;\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Date Filter</span>\n                        <div className=\"fg-options-controls\">\n                          <Form.Item name={[rowName, 'filterField']} label=\"Filter Field\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Mongo field this range filters on, e.g. createdAt. Blank uses the field's own key. Normal search only — in Boolean mode the range is sent via the Boolean API key instead (createdFrom + createdTo), which the boolean-search API accepts but does not filter on yet.\">\n                            <Input size=\"small\" placeholder=\"createdAt\" style={{ width: 200 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* File options */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (getFieldValue([...fAbs, 'type']) !== 'file') return null;\n                    const isMultiple = getFieldValue([...fAbs, 'multiple']);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">File Options</span>\n                        <div className=\"fg-options-controls\">\n                          <Form.Item name={[rowName, 'accept']} label=\"Allowed Content\"\n                            style={{ marginBottom: 0 }} initialValue=\"any\"\n                            tooltip=\"Restrict what this upload accepts. A file outside the selected category is rejected on upload. Overrides the 'File types allowed' validation rule.\">\n                            <Select size=\"small\" style={{ width: 230 }} options={UPLOAD_ACCEPT_OPTIONS} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'multiple']} label=\"Upload Mode\"\n                            valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}>\n                            <Switch size=\"small\" checkedChildren=\"Multiple\" unCheckedChildren=\"Single\" />\n                          </Form.Item>\n                          {isMultiple && (\n                            <Form.Item name={[rowName, 'maxCount']} label=\"Max files\"\n                              style={{ marginBottom: 0 }} initialValue={5}\n                              rules={[{ required: true, message: 'Required' }]}>\n                              <Input size=\"small\" type=\"number\" min={2} placeholder=\"e.g. 5\" style={{ width: 80 }} />\n                            </Form.Item>\n                          )}\n                          <Form.Item name={[rowName, 'fileKey']} label=\"File Key\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Multipart field name sent to the server. Leave blank to use the field key. Set to 'file' for the jobs service.\">\n                            <Input size=\"small\" placeholder=\"e.g. file\" style={{ width: 120 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'fileNameKey']} label=\"Name Key\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Stored object key that contains the uploaded file name. Leave blank for automatic detection.\">\n                            <Input size=\"small\" placeholder=\"e.g. passportUploadName\" style={{ width: 180 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'fileUrlKey']} label=\"URL Key\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Stored object key that contains the file location/path. Leave blank for automatic detection.\">\n                            <Input size=\"small\" placeholder=\"e.g. passportCopyLocation\" style={{ width: 190 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Options / datasource block */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const fType = getFieldValue([...fAbs, 'type']);\n                    if (!['select', 'radio', 'checkbox', 'location'].includes(fType)) return null;\n                    // A location field always sources its options from the\n                    // location endpoint, so it gets no Source picker, no static\n                    // option list and no option-behaviour switches — only the\n                    // single/multi choice, which is the one thing that varies.\n                    const isLocationType = fType === 'location';\n                    const ds = getFieldValue([...fAbs, 'dataSource']) ?? 'static';\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">\n                          {isLocationType ? 'Location selection' : 'Options / Values'}\n                        </span>\n                        <div className=\"fg-options-controls\">\n                          {!isLocationType && (\n                            <Form.Item name={[rowName, 'dataSource']} label=\"Source\"\n                              style={{ marginBottom: 0 }} initialValue=\"static\">\n                              <Select size=\"small\" style={{ width: 190 }} options={DROPDOWN_SOURCES} />\n                            </Form.Item>\n                          )}\n                          {(fType === 'select' || isLocationType) && (\n                            <Form.Item name={[rowName, 'multiSelect']} label=\"Multi Select\"\n                              valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}>\n                              <Switch size=\"small\" checkedChildren=\"Multi\" unCheckedChildren=\"Single\" />\n                            </Form.Item>\n                          )}\n                          {ds === 'master' && (\n                            <Form.Item name={[rowName, 'masterName']} label=\"Master Name\"\n                              style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Enter master name' }]}>\n                              <Input size=\"small\" placeholder=\"e.g. tracker\" style={{ width: 140 }} />\n                            </Form.Item>\n                          )}\n                          {ds === 'group' && (\n                            <>\n                              <Form.Item name={[rowName, 'groupName']} label=\"Group Name\"\n                                style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Enter group name' }]}>\n                                <Input size=\"small\" placeholder=\"e.g. users\" style={{ width: 140 }} />\n                              </Form.Item>\n                              {String(getFieldValue([...fAbs, 'groupName']) ?? '').toLowerCase().trim() === 'users' && (\n                                <Form.Item name={[rowName, 'groupRoleContains']} label=\"Only roles containing\"\n                                  style={{ marginBottom: 0 }}\n                                  tooltip=\"List only users whose role name CONTAINS this word (case-insensitive) — e.g. 'manager' matches Delivery Manager, Onboarding Manager, Submission Manager, etc. Blank = every user.\">\n                                  <Input size=\"small\" placeholder=\"e.g. manager\" style={{ width: 160 }} />\n                                </Form.Item>\n                              )}\n                            </>\n                          )}\n                          {ds === 'locationMaster' && (\n                            <>\n                              <Form.Item name={[rowName, 'locationLevel']} label=\"Level\"\n                                style={{ marginBottom: 0 }} initialValue=\"country\">\n                                <Select size=\"small\" style={{ width: 220 }} options={LOCATION_MASTER_LEVELS} />\n                              </Form.Item>\n                              {['state', 'city'].includes(getFieldValue([...fAbs, 'locationLevel'])) && (\n                                <Form.Item name={[rowName, 'locationCountryFrom']} label=\"Country field\"\n                                  style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Pick the Country field' }]}\n                                  tooltip=\"The sibling field on this form that holds the selected country. This field's options are filtered to that country's states/cities and it stays disabled until that field has a value.\">\n                                  <AutoComplete size=\"small\" style={{ width: 220 }}\n                                    placeholder=\"e.g. address.country\"\n                                    options={(getFieldValue(fieldsAbs) ?? [])\n                                      .map((candidate, index) => ({ candidate, index }))\n                                      .filter(({ candidate, index }) => index !== rowName && candidate?.field)\n                                      .map(({ candidate }) => ({\n                                        value: candidate.field,\n                                        label: `${candidate.label || candidate.field} (${candidate.field})`,\n                                      }))}\n                                    filterOption={(input, option) => String(option?.label ?? '')\n                                      .toLowerCase().includes(String(input).toLowerCase())}\n                                    getPopupContainer={() => document.body} />\n                                </Form.Item>\n                              )}\n                              {getFieldValue([...fAbs, 'locationLevel']) === 'city' && (\n                                <Form.Item name={[rowName, 'locationStateFrom']} label=\"State field\"\n                                  style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Pick the State field' }]}\n                                  tooltip=\"The sibling field on this form that holds the selected state.\">\n                                  <AutoComplete size=\"small\" style={{ width: 220 }}\n                                    placeholder=\"e.g. address.state\"\n                                    options={(getFieldValue(fieldsAbs) ?? [])\n                                      .map((candidate, index) => ({ candidate, index }))\n                                      .filter(({ candidate, index }) => index !== rowName && candidate?.field)\n                                      .map(({ candidate }) => ({\n                                        value: candidate.field,\n                                        label: `${candidate.label || candidate.field} (${candidate.field})`,\n                                      }))}\n                                    filterOption={(input, option) => String(option?.label ?? '')\n                                      .toLowerCase().includes(String(input).toLowerCase())}\n                                    getPopupContainer={() => document.body} />\n                                </Form.Item>\n                              )}\n                            </>\n                          )}\n                        </div>\n\n                        {/* Options behaviour — how the control treats the option list\n                            it just built. Deliberately OUTSIDE the per-source blocks\n                            above: both keys work for a static list, a master, a group\n                            and a lookup, because the runtime applies them after the\n                            options resolve, whatever produced them.\n\n                            • Allow typed values — the field accepts a value that is NOT\n                              in the list (antd mode=\"tags\"). Candidate Skills needs it:\n                              a recruiter must be able to type a skill nobody has entered\n                              before instead of filing a request to extend a master list.\n                            • Restrict options to field — narrows this field's options to\n                              the LIVE value of another field, e.g. the submission's rate\n                              unit may only offer the unit the job was posted in. */}\n                        {!isLocationType && (\n                        <div className=\"fg-options-controls\" style={{ marginTop: 8, flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'allowCustomValues']} label=\"Allow typed values\"\n                            valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}\n                            tooltip=\"Let users enter a value that is not in the option list above. The typed text is stored as-is.\">\n                            <Switch size=\"small\" checkedChildren=\"Typed OK\" unCheckedChildren=\"List only\" />\n                          </Form.Item>\n                          {getFieldValue([...fAbs, 'allowCustomValues']) && (\n                            <Form.Item name={[rowName, 'tokenSeparators']} label=\"Token separators\"\n                              style={{ marginBottom: 0 }}\n                              tooltip=\"Characters that finish the typed entry and start a new one. Default is a comma, so 'React,Node' becomes two values. Leave blank to require Enter.\">\n                              <Input size=\"small\" placeholder=\",\" style={{ width: 90 }} className=\"fg-mono-input\" />\n                            </Form.Item>\n                          )}\n                          <Form.Item name={[rowName, 'optionsFromField']} label=\"Restrict options to field\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Show only the options whose value matches the current value of ANOTHER field on this form. Blank = show every option. Example: point a rate-unit picker at the job's unit field so a recruiter cannot switch units.\">\n                            <AutoComplete size=\"small\" style={{ width: 230 }}\n                              placeholder=\"blank = all options\"\n                              options={(getFieldValue(fieldsAbs) ?? [])\n                                .map((candidate, index) => ({ candidate, index }))\n                                .filter(({ candidate, index }) => index !== rowName && candidate?.field)\n                                .map(({ candidate }) => ({\n                                  value: candidate.field,\n                                  label: `${candidate.label || candidate.field} (${candidate.field})`,\n                                }))}\n                              filterOption={(input, option) => String(option?.label ?? '')\n                                .toLowerCase().includes(String(input).toLowerCase())}\n                              getPopupContainer={() => document.body} />\n                          </Form.Item>\n                        </div>\n                        )}\n                        {!isLocationType && ds === 'static' && (\n                          <div className=\"fg-static-options\">\n                            <span className=\"fg-static-options-hint\">Label / Value pairs</span>\n                            {/* Locked default — search forms only (SearchBuilderV1). Off\n                                by default: no option carries `locked`, so a field behaves\n                                exactly as it does today (nothing pre-selected, everything\n                                freely toggleable). Turning it on pre-selects that option\n                                and disables its checkbox/radio so the user cannot\n                                deselect it — e.g. \"Internal\" always included in Search\n                                Preference. Checkbox/radio only; a locked dropdown option\n                                has no equivalent \"can't deselect\" concept.\n                                (The \"All\" checkbox itself is NOT configured here — it is\n                                automatic for any checkbox field with 2+ options; see the\n                                \"Show 'All' checkbox\" switch above, next to Boolean Search's\n                                own controls.) */}\n                            {['checkbox', 'radio'].includes(fType) && getFieldValue('formType') === 'search' && (\n                              <p className=\"fg-source-hint\" style={{ marginBottom: 6 }}>\n                                Locked options are pre-selected and cannot be unchecked by the user.\n                                Module lets one option answer from a different module, so its\n                                results tab gets that module&apos;s own columns and row actions.\n                              </p>\n                            )}\n                            <Form.List name={[rowName, 'options']}>\n                              {(optItems, { add: addOpt, remove: removeOpt }) => (\n                                <>\n                                  {optItems.map(({ key: oKey, name: oName }) => (\n                                    <div key={oKey} className=\"fg-option-row\">\n                                      <Form.Item name={[oName, 'label']} style={{ marginBottom: 0, flex: 1 }}>\n                                        <Input size=\"small\" placeholder=\"Label\" />\n                                      </Form.Item>\n                                      <Form.Item name={[oName, 'value']} style={{ marginBottom: 0, flex: 1 }}>\n                                        <Input size=\"small\" placeholder=\"Value\" className=\"fg-mono-input\" />\n                                      </Form.Item>\n                                      {['checkbox', 'radio'].includes(fType) && getFieldValue('formType') === 'search' && (\n                                        <>\n                                          {/* Which module answers for this option's results\n                                              tab. Blank is the norm and means \"the form's own\n                                              module\", so every existing option keeps behaving\n                                              exactly as it does now. */}\n                                          <Form.Item name={[oName, 'module']} style={{ marginBottom: 0, flex: 1 }}\n                                            tooltip=\"Module key this option's results tab is served by, e.g. dice. The tab then gets that module's own columns and row actions instead of the form's. Blank = use the form's module.\">\n                                            <Input size=\"small\" placeholder=\"Module (optional)\"\n                                              className=\"fg-mono-input\" />\n                                          </Form.Item>\n                                          <Form.Item name={[oName, 'locked']} valuePropName=\"checked\"\n                                            style={{ marginBottom: 0 }}\n                                            tooltip=\"Pre-selected on load and cannot be unchecked.\">\n                                            <Switch size=\"small\" checkedChildren=\"Locked\" unCheckedChildren=\"Free\" />\n                                          </Form.Item>\n                                        </>\n                                      )}\n                                      <MinusCircleOutlined onClick={() => removeOpt(oName)} className=\"fg-remove-icon\" />\n                                    </div>\n                                  ))}\n                                  <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                                    onClick={() => addOpt({ label: '', value: '' })}\n                                    className=\"fg-add-option-btn\">\n                                    Add Option\n                                  </Button>\n                                </>\n                              )}\n                            </Form.List>\n                          </div>\n                        )}\n                        {ds === 'module' && <p className=\"fg-source-hint\">Options fetched from the module&apos;s distinct field values at runtime.</p>}\n                        {ds === 'group'  && <p className=\"fg-source-hint\">Use &quot;users&quot; to load all users from the MongoDB-backed user collection.</p>}\n                        {ds === 'lookup' && (\n                          <div className=\"fg-lookup-block\">\n                            <p className=\"fg-source-hint\" style={{ marginBottom: 8 }}>Cross-collection lookup &mdash; shows label, stores FK value.</p>\n                            <div className=\"fg-field-meta-row\">\n                              <Form.Item name={[rowName, 'lookupCollection']} label=\"Collection\"\n                                style={{ marginBottom: 0, flex: 1 }} rules={[{ required: true, message: 'Required' }]}>\n                                <Input size=\"small\" placeholder=\"e.g. vendors\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'displayField']} label=\"Display Field\"\n                                style={{ marginBottom: 0, flex: 1 }} rules={[{ required: true, message: 'Required' }]}>\n                                <Input size=\"small\" placeholder=\"e.g. vendorContact.firstName\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'displayField2']} label=\"Display Field 2\"\n                                style={{ marginBottom: 0, flex: 1 }}>\n                                <Input size=\"small\" placeholder=\"e.g. vendorContact.lastName\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'valueField']} label=\"Value Field (FK)\"\n                                style={{ marginBottom: 0, flex: 1 }}>\n                                <Input size=\"small\" placeholder=\"_id\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </div>\n                            <div className=\"fg-field-meta-row\" style={{ marginTop: 8 }}>\n                              <Form.Item name={[rowName, 'lookupFilterField']} label=\"Filter Field\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Optional DB field to filter lookup rows by. Example: _id or clientId.\">\n                                <Input size=\"small\" placeholder=\"e.g. _id\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'lookupFilterValueFrom']} label=\"Filter Value From\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Optional form/scope field that provides the filter value. Example: clientId.\">\n                                <Input size=\"small\" placeholder=\"e.g. clientId\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </div>\n                            {/* Dropdown conditions — any number of conditions the\n                                backend AND-s onto the lookup query. The single\n                                Filter Field pair above can only express ONE\n                                equality against a sibling form field; these can\n                                also read the SIGNED-IN USER (resolved server-side)\n                                and pull values from another collection. */}\n                            <div className=\"fg-lookup-conditions\" style={{ marginTop: 12 }}>\n                              <p className=\"fg-source-hint\" style={{ marginBottom: 6 }}>\n                                <b>Dropdown conditions</b> &mdash; every condition must match (AND). Evaluated on the\n                                server, so they restrict the data, not just the UI.\n                              </p>\n                              <Form.List name={[rowName, 'lookupFilters']}>\n                                {(condFields, { add: addCond, remove: removeCond }) => (\n                                  <>\n                                    {condFields.map(({ key: condKey, name: condName, ...condRest }) => (\n                                      <div key={condKey} className=\"fg-field-meta-row\"\n                                        style={{ marginBottom: 8, alignItems: 'flex-end', flexWrap: 'wrap' }}>\n                                        <Form.Item {...condRest} name={[condName, 'field']} label=\"Field\"\n                                          style={{ marginBottom: 0, flex: 1, minWidth: 140 }}\n                                          tooltip=\"Field on the lookup collection to test. Example: roleId, legacyUserId.\">\n                                          <Input size=\"small\" placeholder=\"e.g. roleId\" className=\"fg-mono-input\" />\n                                        </Form.Item>\n                                        <Form.Item {...condRest} name={[condName, 'op']} label=\"Operator\"\n                                          style={{ marginBottom: 0, width: 130 }} initialValue=\"eq\">\n                                          <Select size=\"small\" options={LOOKUP_FILTER_OPS} />\n                                        </Form.Item>\n                                        <Form.Item {...condRest} name={[condName, 'valueSource']} label=\"Value from\"\n                                          style={{ marginBottom: 0, width: 160 }} initialValue=\"literal\"\n                                          tooltip=\"Literal = a fixed value. Signed-in user = resolved from the auth token on the server. Another collection = a sub-query supplying the values.\">\n                                          <Select size=\"small\" options={[\n                                            { label: 'Literal value', value: 'literal' },\n                                            { label: 'Signed-in user', value: 'identity' },\n                                            { label: 'Another collection', value: 'collection' },\n                                          ]} />\n                                        </Form.Item>\n                                        <Form.Item noStyle shouldUpdate>\n                                          {({ getFieldValue }) => {\n                                            const path = ['fields', rowName, 'lookupFilters', condName];\n                                            const op = getFieldValue([...path, 'op']) ?? 'eq';\n                                            if (op === 'notEmpty' || op === 'empty') {\n                                              return <span className=\"fg-source-hint\" style={{ flex: 1 }}>No value needed.</span>;\n                                            }\n                                            const src = getFieldValue([...path, 'valueSource']) ?? 'literal';\n                                            if (src === 'identity') {\n                                              return (\n                                                <Form.Item {...condRest} name={[condName, 'valueFrom']} label=\"Identity\"\n                                                  style={{ marginBottom: 0, flex: 1, minWidth: 170 }}>\n                                                  <Select size=\"small\" showSearch placeholder=\"currentUserId\"\n                                                    options={LOOKUP_FILTER_IDENTITY_TOKENS.map((t) => ({ label: t, value: t }))} />\n                                                </Form.Item>\n                                              );\n                                            }\n                                            if (src === 'collection') {\n                                              return (\n                                                <>\n                                                  <Form.Item {...condRest} name={[condName, 'srcCollection']} label=\"Collection\"\n                                                    style={{ marginBottom: 0, flex: 1, minWidth: 120 }}>\n                                                    <Input size=\"small\" placeholder=\"e.g. roles\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...condRest} name={[condName, 'srcValueField']} label=\"Value field\"\n                                                    style={{ marginBottom: 0, flex: 1, minWidth: 120 }}>\n                                                    <Input size=\"small\" placeholder=\"_id\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...condRest} name={[condName, 'srcMatchField']} label=\"Where field\"\n                                                    style={{ marginBottom: 0, flex: 1, minWidth: 120 }}>\n                                                    <Input size=\"small\" placeholder=\"e.g. roleName\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...condRest} name={[condName, 'srcMatchValue']} label=\"Equals\"\n                                                    style={{ marginBottom: 0, flex: 1, minWidth: 120 }}\n                                                    tooltip=\"Fixed value. Comma-separate for a list. Ignored when an Identity is chosen next to it.\">\n                                                    <Input size=\"small\" placeholder=\"e.g. RECRUITER\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...condRest} name={[condName, 'srcMatchValueFrom']} label=\"…or identity\"\n                                                    style={{ marginBottom: 0, flex: 1, minWidth: 150 }}\n                                                    tooltip=\"Match against the signed-in user instead of a fixed value — resolved on the server.\">\n                                                    <Select size=\"small\" allowClear placeholder=\"none\"\n                                                      options={LOOKUP_FILTER_IDENTITY_TOKENS.map((t) => ({ label: t, value: t }))} />\n                                                  </Form.Item>\n                                                  <Form.Item {...condRest} name={[condName, 'srcRecursive']} valuePropName=\"checked\"\n                                                    style={{ marginBottom: 0 }}\n                                                    tooltip=\"Keep following the chain outward — e.g. a reporting tree, so the whole downline is included and not just direct reports.\">\n                                                    <Switch size=\"small\" checkedChildren=\"Chain\" unCheckedChildren=\"Direct\" />\n                                                  </Form.Item>\n                                                </>\n                                              );\n                                            }\n                                            return (\n                                              <Form.Item {...condRest} name={[condName, 'value']} label=\"Value\"\n                                                style={{ marginBottom: 0, flex: 1, minWidth: 150 }}\n                                                tooltip=\"Comma-separate for a list.\">\n                                                <Input size=\"small\" placeholder=\"e.g. Active\" className=\"fg-mono-input\" />\n                                              </Form.Item>\n                                            );\n                                          }}\n                                        </Form.Item>\n                                        <Button size=\"small\" danger type=\"text\" onClick={() => removeCond(condName)}>Remove</Button>\n                                      </div>\n                                    ))}\n                                    <Button size=\"small\" type=\"dashed\"\n                                      onClick={() => addCond({ op: 'eq', valueSource: 'literal' })}>\n                                      + Add condition\n                                    </Button>\n                                  </>\n                                )}\n                              </Form.List>\n                            </div>\n                            {/* Option filters applied in the BROWSER, on the rows the\n                                lookup returned. Same restriction as the Dropdown\n                                conditions above, expressed as data carried on each\n                                row — so it keeps working on a backend build that\n                                does not evaluate the conditions. Both may be on at\n                                once; keep them saying the same thing. */}\n                            <div className=\"fg-lookup-row-filters\" style={{ marginTop: 12 }}>\n                              <p className=\"fg-source-hint\" style={{ marginBottom: 6 }}>\n                                <b>Option filters (in-browser)</b> &mdash; narrow the returned options by a value\n                                on each record, and/or to the signed-in user&apos;s reporting line.\n                              </p>\n                              <div className=\"fg-field-meta-row\" style={{ alignItems: 'flex-end' }}>\n                                <Form.Item name={[rowName, 'optionsRequireExtraField']} label=\"Match Field\"\n                                  style={{ marginBottom: 0, flex: 1 }}\n                                  tooltip=\"Field on the looked-up record to test, e.g. roleId. Left empty, no value filter is applied.\">\n                                  <Input size=\"small\" placeholder=\"e.g. roleId\" className=\"fg-mono-input\" />\n                                </Form.Item>\n                                <Form.Item name={[rowName, 'optionsRequireExtraValue']} label=\"Match Value(s)\"\n                                  style={{ marginBottom: 0, flex: 1 }}\n                                  tooltip=\"Allowed value, or several separated by commas (e.g. 10, 13). Empty means the field must be exactly true.\">\n                                  <Input size=\"small\" placeholder=\"empty = must be true\" className=\"fg-mono-input\" />\n                                </Form.Item>\n                              </div>\n                              <div className=\"fg-field-meta-row\" style={{ marginTop: 8, alignItems: 'flex-end' }}>\n                                <Form.Item name={[rowName, 'optionsHierarchyParentField']} label=\"Reports-To Field\"\n                                  style={{ marginBottom: 0, flex: 1 }}\n                                  tooltip=\"Field holding each record's parent id, in the same id space as the Value Field (e.g. reportingId). Set it to show only people below the signed-in user — directly or through any number of levels. The signed-in user is not listed.\">\n                                  <Input size=\"small\" placeholder=\"e.g. reportingId\" className=\"fg-mono-input\" />\n                                </Form.Item>\n                                <Form.Item name={[rowName, 'optionsHierarchySelfFrom']} label=\"Whose Line\"\n                                  style={{ marginBottom: 0, flex: 1 }}\n                                  tooltip=\"Whose reporting line to keep. Defaults to the signed-in user.\">\n                                  <Select size=\"small\" allowClear placeholder=\"currentUserId\"\n                                    options={[{ label: 'Signed-in user (currentUserId)', value: 'currentUserId' }]} />\n                                </Form.Item>\n                              </div>\n                            </div>\n                            {/* Quick actions — buttons inside this dropdown that open the\n                                target module's Add/Edit form in a popup, then refresh the\n                                options so the new record is immediately selectable. */}\n                            <div className=\"fg-field-meta-row\" style={{ marginTop: 8, alignItems: 'flex-end' }}>\n                              <Form.Item name={[rowName, 'quickCreate']} valuePropName=\"checked\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Adds a button inside this dropdown so someone can create a new record without leaving the form. When they save, it is selected here automatically.\">\n                                <Switch size=\"small\" checkedChildren=\"Add button\" unCheckedChildren=\"No add\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateModule']} label=\"What it creates\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Which list the new record is added to. Leave blank to use the Collection set above.\">\n                                <Input size=\"small\" placeholder=\"same as Collection above\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickEdit']} valuePropName=\"checked\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Adds a button so someone can edit the record they have selected, without leaving the form.\">\n                                <Switch size=\"small\" checkedChildren=\"Edit button\" unCheckedChildren=\"No edit\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickEditModule']} label=\"What it edits\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Which list the edited record belongs to. Leave blank to use the Collection set above.\">\n                                <Input size=\"small\" placeholder=\"same as Collection above\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickEditIdFrom']} label=\"Edit which record\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Normally the record chosen in THIS box. If the thing to edit is chosen in a different box, name that box here — e.g. a recruiter row that should edit its employer names employerId.\">\n                                <Input size=\"small\" placeholder=\"e.g. employerId\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </div>\n\n                            {/* Button wording. Blank is the RECOMMENDED setting: the label is\n                                built from the target list, so \"employers\" reads as\n                                \"Add New Employer\" and stays correct if the list is renamed. */}\n                            <Form.Item shouldUpdate style={{ marginBottom: 0 }}>\n                              {({ getFieldValue }) => {\n                                const target = getFieldValue([...fAbs, 'quickCreateModule'])\n                                  || getFieldValue([...fAbs, 'lookupCollection']) || '';\n                                const editTarget = getFieldValue([...fAbs, 'quickEditModule'])\n                                  || getFieldValue([...fAbs, 'lookupCollection']) || '';\n                                return (\n                                  <div className=\"fg-field-meta-row\" style={{ marginTop: 8, alignItems: 'flex-end' }}>\n                                    <Form.Item name={[rowName, 'quickCreateLabel']} label=\"Add button wording\"\n                                      style={{ marginBottom: 0, flex: 1 }}\n                                      tooltip=\"Leave blank and the button names what it adds, worked out from the list above. Only type something here if you want different wording.\">\n                                      <Input size=\"small\"\n                                        placeholder={quickCreateLabel({ quickCreateModule: target }, target)} />\n                                    </Form.Item>\n                                    <Form.Item name={[rowName, 'quickEditLabel']} label=\"Edit button wording\"\n                                      style={{ marginBottom: 0, flex: 1 }}\n                                      tooltip=\"Leave blank and the button names what it edits. The popup heading matches the button, so the two always agree.\">\n                                      <Input size=\"small\"\n                                        placeholder={quickEditLabel({ quickEditModule: editTarget }, editTarget)} />\n                                    </Form.Item>\n                                  </div>\n                                );\n                              }}\n                            </Form.Item>\n                            <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                              Leave both blank unless you need different wording. The buttons name\n                              the thing they act on — &quot;Add New Employer&quot;, &quot;Edit\n                              Employer&quot; — instead of a vague &quot;Add More&quot;, and the\n                              popup heading matches the button that opened it.\n                            </p>\n                            {/* Post-create notice — a popup shown the instant a\n                                record is created through \"Add More\" above, warning\n                                that a brand-new record is not configured yet. It\n                                cannot fire when an EXISTING option is selected:\n                                only a real quick-create reaches that code path. */}\n                            <div className=\"fg-field-meta-row\" style={{ marginTop: 8, alignItems: 'flex-end' }}>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'enabled']} valuePropName=\"checked\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Show a popup right after a record is created here, warning that it still needs an Organization Admin to configure forms, workflows and permissions.\">\n                                <Switch size=\"small\" checkedChildren=\"Notice\" unCheckedChildren=\"No Notice\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'title']} label=\"Notice Title\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Popup title. Default: New record created.\">\n                                <Input size=\"small\" placeholder=\"New record created\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'recordNameField']} label=\"Name Field\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Key on the created record holding its display name. Empty = the Display Field above, then any name-like key.\">\n                                <Input size=\"small\" placeholder=\"defaults to Display Field\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </div>\n                            <div className=\"fg-field-meta-row\" style={{ marginTop: 8, alignItems: 'flex-end' }}>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'showRecordName']} valuePropName=\"checked\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Show the created record's name in the popup.\">\n                                <Switch size=\"small\" checkedChildren=\"Name\" unCheckedChildren=\"No Name\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'recordLabel']} label=\"Name Label\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Label for the record-name line, e.g. Client name. Default: Record name.\">\n                                <Input size=\"small\" placeholder=\"Record name\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'showCreator']} valuePropName=\"checked\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Show who created the record.\">\n                                <Switch size=\"small\" checkedChildren=\"Creator\" unCheckedChildren=\"No Creator\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'quickCreateNotice', 'creatorLabel']} label=\"Creator Label\"\n                                style={{ marginBottom: 0, flex: 1 }}\n                                tooltip=\"Label for the creator line. Default: Created by.\">\n                                <Input size=\"small\" placeholder=\"Created by\" />\n                              </Form.Item>\n                            </div>\n                            <Form.Item name={[rowName, 'quickCreateNotice', 'message']} label=\"Notice Message\"\n                              style={{ marginTop: 8, marginBottom: 0 }}\n                              tooltip=\"Leave empty to use the standard wording asking the recruiter to contact their Organization Admin before proceeding.\">\n                              <Input.TextArea size=\"small\" rows={3} placeholder=\"Leave empty for the standard message\" />\n                            </Form.Item>\n                          </div>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Show / Req / Edit. A Default Field (Form Groups → Default\n                    Fields, OTP-gated) is always shown + required, so its Show\n                    and Req switches are forced ON and locked here. */}\n                <div className=\"fg-toggles-row\">\n                  {(() => {\n                    const isDefault = defaultFieldSet.has(fieldValue.field);\n                    return (\n                      <>\n                        <Form.Item {...restField} name={[rowName, 'show']} valuePropName=\"checked\"\n                          style={{ marginBottom: 0 }} initialValue={true}>\n                          <Switch size=\"small\" checkedChildren=\"Show\" unCheckedChildren=\"Hide\"\n                            checked={isDefault ? true : undefined} disabled={isDefault}\n                            title={isDefault ? 'Locked — Default Field (always shown)' : undefined} />\n                        </Form.Item>\n                        <Form.Item {...restField} name={[rowName, 'req']} valuePropName=\"checked\"\n                          style={{ marginBottom: 0 }} initialValue={false}>\n                          <Switch size=\"small\" checkedChildren=\"Req\" unCheckedChildren=\"Opt\"\n                            checked={isDefault ? true : undefined} disabled={isDefault}\n                            title={isDefault ? 'Locked — Default Field (always required)' : undefined} />\n                        </Form.Item>\n                      </>\n                    );\n                  })()}\n                  <Form.Item {...restField} name={[rowName, 'showOnAdd']} valuePropName=\"checked\"\n                    style={{ marginBottom: 0 }} initialValue={true}\n                    tooltip=\"Show this field on Add. Turn off for edit-only fields.\">\n                    <Switch size=\"small\" checkedChildren=\"Add\" unCheckedChildren=\"No Add\" />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'edit']} valuePropName=\"checked\"\n                    style={{ marginBottom: 0 }} initialValue={true}>\n                    <Switch size=\"small\" checkedChildren=\"Edit\" unCheckedChildren=\"Read\" />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'addRow']} valuePropName=\"checked\"\n                    style={{ marginBottom: 0 }} initialValue={false}\n                    tooltip=\"Let users repeat this single field (add/remove multiple values). Ignored when this field's group is itself Add Row.\">\n                    <Switch size=\"small\" checkedChildren=\"Repeat\" unCheckedChildren=\"Single\" />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'clientScope']} valuePropName=\"checked\"\n                    style={{ marginBottom: 0 }} initialValue={false}\n                    tooltip=\"Use this field as the client-selector gate. It shows as the top 'Select Client' picker and is hidden from the form body (no duplicate client card).\">\n                    <Switch size=\"small\" checkedChildren=\"Client Gate\" unCheckedChildren=\"Client Gate\" />\n                  </Form.Item>\n                  <Form.Item {...restField} name={[rowName, 'infoEnabled']} valuePropName=\"checked\"\n                    style={{ marginBottom: 0 }} initialValue={false}\n                    tooltip=\"Show an info icon next to this field label in add/edit forms.\">\n                    <Switch size=\"small\" checkedChildren=\"Info\" unCheckedChildren=\"Info\" />\n                  </Form.Item>\n                </div>\n\n                {/* Repeat (field-level add row) options — shown only when Repeat is on */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (!getFieldValue([...fAbs, 'addRow'])) return null;\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Repeat Field Options</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'minRows']} label=\"Min Values\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Minimum values the user must keep. Delete is disabled at this count.\">\n                            <Input size=\"small\" type=\"number\" min={0} placeholder=\"0\" style={{ width: 90 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'initialRows']} label=\"Initial Values\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"How many empty inputs to show on a fresh Add (0 = show only the + button).\">\n                            <Input size=\"small\" type=\"number\" min={0} placeholder=\"1\" style={{ width: 90 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'maxRows']} label=\"Max Values\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Maximum values allowed. The + button hides at this count. Blank = unlimited.\">\n                            <Input size=\"small\" type=\"number\" min={0} placeholder=\"∞\" style={{ width: 90 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'addLabel']} label=\"Add Button Label\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Custom text for the add button. Defaults to 'Add <label>'.\">\n                            <Input size=\"small\" placeholder=\"e.g. Add Skill\" style={{ width: 170 }} />\n                          </Form.Item>\n                        </div>\n\n                        {/* Sub-fields — turn this single repeat into a repeatable GROUP of\n                            fields (e.g. Question + Answer). Leave empty to repeat a single\n                            value. Each row then submits as an object, and the field as an\n                            array of objects under its payload key. */}\n                        <div className=\"fg-subfields-block\" style={{ marginTop: 10 }}>\n                          <span className=\"fg-options-label\">\n                            Sub-fields (repeat a group together)\n                            <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                              leave empty to repeat a single value\n                            </span>\n                          </span>\n                          <Form.List name={[rowName, 'subFields']}>\n                            {(subItems, { add: addSub, remove: removeSub }) => (\n                              <div>\n                                {subItems.map(({ key: subKey, name: subName, ...subRest }) => (\n                                  <div key={subKey} className=\"fg-subfield-row\" style={{ marginBottom: 10 }}>\n                                    <div className=\"fg-inline-row\"\n                                      style={{ flexWrap: 'wrap', alignItems: 'flex-end' }}>\n                                      <Form.Item {...subRest} name={[subName, 'field']} label=\"Key\"\n                                        rules={[\n                                          { required: true, message: 'Key' },\n                                          { pattern: /^[a-zA-Z0-9_]+$/, message: 'a-z 0-9 _' },\n                                        ]}\n                                        style={{ marginBottom: 0 }}>\n                                        <Input size=\"small\" placeholder=\"e.g. question\"\n                                          style={{ width: 140 }} className=\"fg-mono-input\" />\n                                      </Form.Item>\n                                      <Form.Item {...subRest} name={[subName, 'label']} label=\"Label\"\n                                        rules={[{ required: true, message: 'Label' }]}\n                                        style={{ marginBottom: 0 }}>\n                                        <Input size=\"small\" placeholder=\"e.g. Question\" style={{ width: 150 }} />\n                                      </Form.Item>\n                                      <Form.Item {...subRest} name={[subName, 'type']} label=\"Type\"\n                                        initialValue=\"text\" style={{ marginBottom: 0 }}>\n                                        <Select size=\"small\" options={FIELD_TYPES} style={{ width: 130 }} />\n                                      </Form.Item>\n                                      <Form.Item {...subRest} name={[subName, 'req']} label=\"Required\"\n                                        valuePropName=\"checked\" initialValue={false} style={{ marginBottom: 0 }}>\n                                        <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                                      </Form.Item>\n                                      <Form.Item {...subRest} name={[subName, 'col']} label=\"Width\"\n                                        tooltip=\"Grid span: 12 = half row, 24 = full row. Blank = 12.\"\n                                        style={{ marginBottom: 0 }}>\n                                        <Input size=\"small\" type=\"number\" placeholder=\"12\" style={{ width: 70 }} />\n                                      </Form.Item>\n                                      <Tooltip title=\"Remove sub-field\">\n                                        <button type=\"button\" className=\"fg-field-remove-btn\"\n                                          onClick={() => removeSub(subName)} aria-label=\"Remove sub-field\">\n                                          <MinusCircleOutlined />\n                                        </button>\n                                      </Tooltip>\n                                    </div>\n\n                                    {/* A sub-field of type select/radio/checkbox needs the SAME\n                                        dataSource config as a normal field (static options, master,\n                                        group, or lookup) — without it the control renders with no\n                                        options. Mirrors the top-level \"Options / Values\" block. */}\n                                    <Form.Item shouldUpdate style={{ marginBottom: 0 }}>\n                                      {() => {\n                                        const subType = getFieldValue([...fAbs, 'subFields', subName, 'type']);\n                                        if (!['select', 'radio', 'checkbox'].includes(subType)) return null;\n                                        const subDs = getFieldValue([...fAbs, 'subFields', subName, 'dataSource']) ?? 'static';\n                                        return (\n                                          <div className=\"fg-options-block\" style={{ marginTop: 6 }}>\n                                            <span className=\"fg-options-label\">Options / Values</span>\n                                            <div className=\"fg-options-controls\">\n                                              <Form.Item name={[subName, 'dataSource']} label=\"Source\"\n                                                style={{ marginBottom: 0 }} initialValue=\"static\">\n                                                <Select size=\"small\" style={{ width: 190 }} options={DROPDOWN_SOURCES} />\n                                              </Form.Item>\n                                              {subType === 'select' && (\n                                                <Form.Item name={[subName, 'multiSelect']} label=\"Multi Select\"\n                                                  valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}>\n                                                  <Switch size=\"small\" checkedChildren=\"Multi\" unCheckedChildren=\"Single\" />\n                                                </Form.Item>\n                                              )}\n                                              {subDs === 'master' && (\n                                                <Form.Item name={[subName, 'masterName']} label=\"Master Name\"\n                                                  style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Enter master name' }]}>\n                                                  <Input size=\"small\" placeholder=\"e.g. tracker\" style={{ width: 140 }} />\n                                                </Form.Item>\n                                              )}\n                                              {subDs === 'group' && (\n                                                <Form.Item name={[subName, 'groupName']} label=\"Group Name\"\n                                                  style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Enter group name' }]}>\n                                                  <Input size=\"small\" placeholder=\"e.g. users\" style={{ width: 140 }} />\n                                                </Form.Item>\n                                              )}\n                                            </div>\n                                            {subDs === 'static' && (\n                                              <div className=\"fg-static-options\">\n                                                <span className=\"fg-static-options-hint\">Label / Value pairs</span>\n                                                <Form.List name={[subName, 'options']}>\n                                                  {(optItems, { add: addOpt, remove: removeOpt }) => (\n                                                    <>\n                                                      {optItems.map(({ key: oKey, name: oName }) => (\n                                                        <div key={oKey} className=\"fg-option-row\">\n                                                          <Form.Item name={[oName, 'label']} style={{ marginBottom: 0, flex: 1 }}>\n                                                            <Input size=\"small\" placeholder=\"Label\" />\n                                                          </Form.Item>\n                                                          <Form.Item name={[oName, 'value']} style={{ marginBottom: 0, flex: 1 }}>\n                                                            <Input size=\"small\" placeholder=\"Value\" className=\"fg-mono-input\" />\n                                                          </Form.Item>\n                                                          <MinusCircleOutlined onClick={() => removeOpt(oName)} className=\"fg-remove-icon\" />\n                                                        </div>\n                                                      ))}\n                                                      <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                                                        onClick={() => addOpt({ label: '', value: '' })}\n                                                        className=\"fg-add-option-btn\">\n                                                        Add Option\n                                                      </Button>\n                                                    </>\n                                                  )}\n                                                </Form.List>\n                                              </div>\n                                            )}\n                                            {subDs === 'group' && <p className=\"fg-source-hint\">Use &quot;users&quot; to load all users from the MongoDB-backed user collection.</p>}\n                                            {subDs === 'lookup' && (\n                                              <div className=\"fg-lookup-block\">\n                                                <p className=\"fg-source-hint\" style={{ marginBottom: 8 }}>Cross-collection lookup &mdash; shows label, stores FK value.</p>\n                                                <div className=\"fg-field-meta-row\">\n                                                  <Form.Item name={[subName, 'lookupCollection']} label=\"Collection\"\n                                                    style={{ marginBottom: 0, flex: 1 }} rules={[{ required: true, message: 'Required' }]}>\n                                                    <Input size=\"small\" placeholder=\"e.g. vendors\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item name={[subName, 'displayField']} label=\"Display Field\"\n                                                    style={{ marginBottom: 0, flex: 1 }} rules={[{ required: true, message: 'Required' }]}>\n                                                    <Input size=\"small\" placeholder=\"e.g. vendorContact.firstName\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item name={[subName, 'displayField2']} label=\"Display Field 2\"\n                                                    style={{ marginBottom: 0, flex: 1 }}>\n                                                    <Input size=\"small\" placeholder=\"e.g. vendorContact.lastName\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item name={[subName, 'valueField']} label=\"Value Field (FK)\"\n                                                    style={{ marginBottom: 0, flex: 1 }}>\n                                                    <Input size=\"small\" placeholder=\"_id\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                </div>\n                                                <div className=\"fg-field-meta-row\" style={{ marginTop: 8 }}>\n                                                  <Form.Item name={[subName, 'lookupFilterField']} label=\"Filter Field\"\n                                                    style={{ marginBottom: 0, flex: 1 }}\n                                                    tooltip=\"Optional DB field to filter lookup rows by. Example: _id or clientId.\">\n                                                    <Input size=\"small\" placeholder=\"e.g. _id\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                  <Form.Item name={[subName, 'lookupFilterValueFrom']} label=\"Filter Value From\"\n                                                    style={{ marginBottom: 0, flex: 1 }}\n                                                    tooltip=\"Optional form/scope field that provides the filter value. Example: clientId.\">\n                                                    <Input size=\"small\" placeholder=\"e.g. clientId\" className=\"fg-mono-input\" />\n                                                  </Form.Item>\n                                                </div>\n                                              </div>\n                                            )}\n                                          </div>\n                                        );\n                                      }}\n                                    </Form.Item>\n                                  </div>\n                                ))}\n                                <Button type=\"dashed\" size=\"small\" icon={<PlusOutlined />}\n                                  onClick={() => addSub({ type: 'text', req: false })}>\n                                  Add Sub-field\n                                </Button>\n                              </div>\n                            )}\n                          </Form.List>\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                <div className=\"fg-field-meta-row\" style={{ marginTop: 8 }}>\n                  <Form.Item name={[rowName, 'placeholder']} label=\"Placeholder\"\n                    style={{ marginBottom: 0, flex: 1 }}>\n                    <Input size=\"small\" placeholder=\"Admin-controlled placeholder\" />\n                  </Form.Item>\n                  <Form.Item name={[rowName, 'hidePlaceholder']} label=\"Hide Placeholder\"\n                    valuePropName=\"checked\" style={{ marginBottom: 0 }}>\n                    <Switch size=\"small\" checkedChildren=\"Hidden\" unCheckedChildren=\"Shown\" />\n                  </Form.Item>\n                </div>\n\n                <div className=\"fg-field-meta-row\" style={{ marginTop: 8 }}>\n                  <Form.Item name={[rowName, 'visiblePermission']} label=\"Visible permission key\"\n                    style={{ marginBottom: 0, flex: 1 }}\n                    tooltip=\"Menu-permission key ('<module>.<key>', e.g. submission.viewRate) gating whether this field is rendered at all. Leave blank to show to everyone (subject to the Show toggle above). Add matching keys in Admin → Permissions.\">\n                    <Input size=\"small\" placeholder=\"e.g. submission.viewRate\" />\n                  </Form.Item>\n                  <Form.Item name={[rowName, 'editablePermission']} label=\"Editable permission key\"\n                    style={{ marginBottom: 0, flex: 1 }}\n                    tooltip=\"Menu-permission key gating whether this field can be edited. Users without it see the field disabled with a tooltip. Leave blank to allow everyone (subject to the Edit toggle above).\">\n                    <Input size=\"small\" placeholder=\"e.g. submission.editRate\" />\n                  </Form.Item>\n                </div>\n\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    if (!getFieldValue([...fAbs, 'clientScope'])) return null;\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Client Gate Message</span>\n                        <Form.Item name={[rowName, 'clientGateMessage']} style={{ marginBottom: 0 }}>\n                          <Input.TextArea\n                            rows={2}\n                            placeholder=\"Message shown below 'Select Client' in the add form (leave blank for default)\"\n                          />\n                        </Form.Item>\n                        <Form.Item\n                          name={[rowName, 'clientGateResetOnChange']}\n                          valuePropName=\"checked\"\n                          style={{ margin: '10px 0 0' }}\n                          tooltip=\"When the selected client changes or is cleared, remove every value already entered in the form before loading the new client configuration.\"\n                        >\n                          <Switch\n                            size=\"small\"\n                            checkedChildren=\"Reset form on client change\"\n                            unCheckedChildren=\"Keep form values\"\n                          />\n                        </Form.Item>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Help text — ONE block covering both config shapes, because they\n                    are the same idea with different reach and presenting them as two\n                    unrelated controls is how a field ends up with two conflicting\n                    texts:\n                      • Tooltip (`tooltip`)  — the field's help text, resolved by\n                        components/form/fieldTooltip.js. Works on EVERY control,\n                        including a field rendered without a label (an inline box in a\n                        combined block, or a group that prints one shared header row),\n                        because the form falls back to wrapping the control itself.\n                      • Info icon (`infoEnabled` + `infoText`) — the original pair. It\n                        renders an info icon INSIDE the field's label, so a label-less\n                        field can never show it. Kept because plenty of config already\n                        uses it.\n                    fieldTooltipText() prefers `tooltip` when both are set, which the\n                    hint below states outright so an admin is never guessing which one\n                    the form will actually show. */}\n                <div className=\"fg-options-block\">\n                  <span className=\"fg-options-label\">\n                    <InfoCircleOutlined /> Help Text\n                  </span>\n                  <Form.Item\n                    {...restField}\n                    name={[rowName, 'tooltip']}\n                    label=\"Tooltip\"\n                    style={{ marginBottom: 8 }}\n                    tooltip=\"Hover help for this field. Works on every control — including fields rendered without a label, where the info icon below cannot appear. Use this one unless you specifically need the icon.\"\n                  >\n                    <Input.TextArea rows={2} placeholder=\"Shown when users hover this field\" />\n                  </Form.Item>\n                  <Form.Item shouldUpdate style={{ marginBottom: 0 }}>\n                    {({ getFieldValue }) => {\n                      if (!getFieldValue([...fAbs, 'infoEnabled'])) return null;\n                      return (\n                        <Form.Item\n                          name={[rowName, 'infoText']}\n                          label=\"Info icon text\"\n                          style={{ marginBottom: 0 }}\n                          rules={[{ required: true, message: 'Enter info message' }]}\n                          tooltip=\"Legacy pair (Info switch above + this text). Renders an icon inside the field label, so it never shows on a label-less field. Ignored when a Tooltip is set.\"\n                        >\n                          <Input.TextArea\n                            rows={2}\n                            placeholder=\"Message shown when users hover the info icon\"\n                          />\n                        </Form.Item>\n                      );\n                    }}\n                  </Form.Item>\n                </div>\n\n                <Form.Item\n                  {...restField}\n                  name={[rowName, 'helpText']}\n                  label=\"Extra Text\"\n                  tooltip=\"Small grey text under the field. Put EACH LINE on its own line — they render stacked. Use one line for the rule (&quot;Supports .pdf, .doc, .docx up to 2MB&quot;) and another for the reason (&quot;Upload the résumé first — we can read the details out of it&quot;). Run together in one paragraph, the second half gets skipped.\"\n                >\n                  <Input.TextArea rows={3} placeholder={'Supports: .pdf, .doc, .docx up to 2MB\\nUpload the résumé first — we can read the details straight from it'} />\n                </Form.Item>\n\n                {/* Duplicate check on blur + the cross-row date hierarchy.\n                    Both are per-field switches over rules configured elsewhere,\n                    so the editor never rewrites the rule object itself. */}\n                <div className=\"fg-options-block\">\n                  <span className=\"fg-options-label\">Checks against other records and other rows</span>\n                  <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                    <Form.Item name={[rowName, 'checkDuplicateOnBlur']} label=\"Check for an existing record\"\n                      valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                      tooltip=\"Put this on the email (or phone) box. When someone finishes typing it, we look for a record that already matches and offer to open it. Catching it here saves them filling in the whole form first. The fields compared are set in Automations → Check for someone already on file.\">\n                      <Switch size=\"small\" checkedChildren=\"On blur\" unCheckedChildren=\"Off\" />\n                    </Form.Item>\n                    <Form.Item name={[rowName, 'rowHierarchyEnabled']} label=\"Keep rows in date order\"\n                      valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                      tooltip=\"For a date inside a repeat section that is listed newest-first. Once the first row has dates, the calendar greys out any date that would overlap it in the rows below — you cannot have finished an earlier course after starting a later one. The user sees what is available while choosing, instead of being told afterwards.\">\n                      <Switch size=\"small\" checkedChildren=\"Enforced\" unCheckedChildren=\"Off\" />\n                    </Form.Item>\n                  </div>\n                  <p className=\"fg-source-hint\">\n                    These two only make sense in the right place: the duplicate check on the box\n                    that identifies a person, and the date order on a start/end date inside a\n                    repeat section that lists the most recent first.\n                  </p>\n                </div>\n\n                {/* Show Condition */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const watchField = getFieldValue([...fAbs, 'showIf', 'field']);\n                    const op = getFieldValue([...fAbs, 'showIf', 'operator']) ?? 'eq';\n                    const needsValue = SHOW_IF_VALUE_OPERATORS.includes(op);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Show Condition</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'showIf', 'field']} label=\"Show only when field\"\n                            style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"field key — blank = always show\"\n                              style={{ width: 210 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          {watchField && (\n                            <>\n                              <Form.Item name={[rowName, 'showIf', 'operator']} label=\"Operator\"\n                                style={{ marginBottom: 0 }} initialValue=\"eq\">\n                                <Select size=\"small\" style={{ width: 130 }} options={SHOW_IF_OPERATORS}\n                                  getPopupContainer={() => document.body} />\n                              </Form.Item>\n                              {needsValue && (\n                                <Form.Item name={[rowName, 'showIf', 'value']} label=\"Value\"\n                                  style={{ marginBottom: 0 }}>\n                                  <Input size=\"small\" placeholder=\"e.g. yes\" style={{ width: 100 }}\n                                    className=\"fg-mono-input\" />\n                                </Form.Item>\n                              )}\n                            </>\n                          )}\n                        </div>\n\n                        {/* Extra conditions (\"add more\") — combined with the base\n                            condition above by the Combine logic. Each is field + operator\n                            (+ value). Field shows only when EVERY / ANY condition matches. */}\n                        {watchField && (\n                          <Form.List name={[rowName, 'showIf', 'conditions']}>\n                            {(condFields, { add, remove }) => (\n                              <div style={{ marginTop: 8 }}>\n                                {condFields.length > 0 && (\n                                  <Form.Item name={[rowName, 'showIf', 'logic']} label=\"Combine when\"\n                                    style={{ marginBottom: 6 }} initialValue=\"and\">\n                                    <Select size=\"small\" style={{ width: 190 }}\n                                      getPopupContainer={() => document.body}\n                                      options={[\n                                        { value: 'and', label: 'All must match (AND)' },\n                                        { value: 'or', label: 'Any can match (OR)' },\n                                      ]} />\n                                  </Form.Item>\n                                )}\n                                {condFields.map((cf) => (\n                                  <Form.Item key={cf.key} shouldUpdate style={{ marginBottom: 6 }}>\n                                    {({ getFieldValue }) => {\n                                      const cop = getFieldValue([...fAbs, 'showIf', 'conditions', cf.name, 'operator']) ?? 'eq';\n                                      const cNeedsValue = SHOW_IF_VALUE_OPERATORS.includes(cop);\n                                      return (\n                                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap', alignItems: 'flex-end' }}>\n                                          <Form.Item name={[cf.name, 'field']} label=\"And field\"\n                                            style={{ marginBottom: 0 }}>\n                                            <Input size=\"small\" placeholder=\"field key\" style={{ width: 180 }}\n                                              className=\"fg-mono-input\" />\n                                          </Form.Item>\n                                          <Form.Item name={[cf.name, 'operator']} label=\"Operator\"\n                                            style={{ marginBottom: 0 }} initialValue=\"eq\">\n                                            <Select size=\"small\" style={{ width: 130 }} options={SHOW_IF_OPERATORS}\n                                              getPopupContainer={() => document.body} />\n                                          </Form.Item>\n                                          {cNeedsValue && (\n                                            <Form.Item name={[cf.name, 'value']} label=\"Value\"\n                                              style={{ marginBottom: 0 }}>\n                                              <Input size=\"small\" placeholder=\"comma for list\" style={{ width: 130 }}\n                                                className=\"fg-mono-input\" />\n                                            </Form.Item>\n                                          )}\n                                          <Button size=\"small\" type=\"text\" danger onClick={() => remove(cf.name)}>\n                                            Remove\n                                          </Button>\n                                        </div>\n                                      );\n                                    }}\n                                  </Form.Item>\n                                ))}\n                                <Button size=\"small\" type=\"dashed\" style={{ marginTop: 4 }}\n                                  onClick={() => add({ field: '', operator: 'eq', value: '' })}>\n                                  + Add condition\n                                </Button>\n                              </div>\n                            )}\n                          </Form.List>\n                        )}\n\n                        {watchField && (\n                          <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                            Hidden until &ldquo;{watchField}&rdquo;\n                            {needsValue\n                              ? ` ${op === 'eq' ? 'equals' : op === 'neq' ? 'does not equal' : op === 'in' ? 'is one of' : 'is not one of'} the value above.`\n                              : ` ${op === 'truthy' ? 'has any value.' : op === 'notEmpty' ? 'has at least one row.' : 'is empty.'}`}\n                            {' '}Add more conditions below to require several at once.\n                          </p>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Conditional Label — changes display text only, never payload. */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const watchField = getFieldValue([...fAbs, 'labelWhen', 'field']);\n                    const op = getFieldValue([...fAbs, 'labelWhen', 'operator']) ?? 'eq';\n                    const needsValue = SHOW_IF_VALUE_OPERATORS.includes(op);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Conditional Label</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'labelWhen', 'field']} label=\"Watch field\"\n                            style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"blank = use normal label\"\n                              style={{ width: 190 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          {watchField && (\n                            <>\n                              <Form.Item name={[rowName, 'labelWhen', 'operator']} label=\"Operator\"\n                                style={{ marginBottom: 0 }} initialValue=\"eq\">\n                                <Select size=\"small\" style={{ width: 130 }} options={SHOW_IF_OPERATORS}\n                                  getPopupContainer={() => document.body} />\n                              </Form.Item>\n                              {needsValue && (\n                                <Form.Item name={[rowName, 'labelWhen', 'value']} label=\"Value\"\n                                  style={{ marginBottom: 0 }}>\n                                  <Input size=\"small\" placeholder=\"comma-separated for one-of\"\n                                    style={{ width: 180 }} className=\"fg-mono-input\" />\n                                </Form.Item>\n                              )}\n                              <Form.Item name={[rowName, 'labelWhen', 'label']} label=\"Alternate label\"\n                                style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Enter alternate label' }]}>\n                                <Input size=\"small\" placeholder=\"e.g. Employer Rate\" style={{ width: 170 }} />\n                              </Form.Item>\n                            </>\n                          )}\n                        </div>\n                        {watchField && (\n                          <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                            Only the displayed label changes. The field key and submitted payload stay unchanged.\n                          </p>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Conditional Width — shrinks this field while a condition holds,\n                    so a field revealed by a Show Condition has room beside it. */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const watchField = getFieldValue([...fAbs, 'colWhenField']);\n                    const op = getFieldValue([...fAbs, 'colWhenOperator']) ?? 'eq';\n                    const needsValue = SHOW_IF_VALUE_OPERATORS.includes(op);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Conditional Width</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'colWhenField']} label=\"Watch field\"\n                            style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"blank = always use Width\"\n                              style={{ width: 190 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          {watchField && (\n                            <>\n                              <Form.Item name={[rowName, 'colWhenOperator']} label=\"Operator\"\n                                style={{ marginBottom: 0 }} initialValue=\"eq\">\n                                <Select size=\"small\" style={{ width: 130 }} options={SHOW_IF_OPERATORS}\n                                  getPopupContainer={() => document.body} />\n                              </Form.Item>\n                              {needsValue && (\n                                <Form.Item name={[rowName, 'colWhenValue']} label=\"Value\"\n                                  style={{ marginBottom: 0 }}>\n                                  <Input size=\"small\" placeholder=\"comma-separated for one-of\"\n                                    style={{ width: 180 }} className=\"fg-mono-input\" />\n                                </Form.Item>\n                              )}\n                              <Form.Item name={[rowName, 'colWhenCol']} label=\"Width when matched\"\n                                style={{ marginBottom: 0 }}\n                                rules={[{ required: true, message: 'Enter a width (1-24)' }]}>\n                                <InputNumber size=\"small\" min={1} max={24} style={{ width: 150 }} placeholder=\"e.g. 6\" />\n                              </Form.Item>\n                            </>\n                          )}\n                        </div>\n                        {watchField && (\n                          <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                            While the condition holds this field uses the width above (24 = full row);\n                            otherwise it falls back to Width. Layout only — the payload is unchanged.\n                          </p>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Verification — generic action/result configuration. */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const action = getFieldValue([...fAbs, 'verifyAction']);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Field Verification</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'verifyAction']} label=\"Action\" style={{ marginBottom: 0 }}>\n                            <Select size=\"small\" allowClear placeholder=\"None\" style={{ width: 130 }} options={[\n                              { label: 'Email', value: 'email' },\n                            ]} />\n                          </Form.Item>\n                          {action && (\n                            <>\n                              <Form.Item name={[rowName, 'verifyResultField']} label=\"Result field\"\n                                style={{ marginBottom: 0 }} rules={[{ required: true, message: 'Result field is required' }]}>\n                                <Input size=\"small\" placeholder=\"e.g. isValid\" style={{ width: 130 }} className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'verifyTimestampField']} label=\"Timestamp field\" style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"e.g. validatedAt\" style={{ width: 150 }} className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'verifyIdleLabel']} label=\"Initial text\" style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"Verify Email\" style={{ width: 130 }} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'verifyRetryLabel']} label=\"Retry text\" style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"Re Verify\" style={{ width: 120 }} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'verifySuccessLabel']} label=\"Success text\" style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"Valid\" style={{ width: 110 }} />\n                              </Form.Item>\n                              <Form.Item\n                                name={[rowName, 'verifyLockedWhenFields']}\n                                label=\"Locked when fields\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Comma-separated sibling field keys on the same row (e.g. isAccountCreate). When ALL of them are true AND the result field is true, the edit form shows a fixed, non-clickable label instead of the Verify button. Blank = never locked.\"\n                              >\n                                <Input size=\"small\" placeholder=\"e.g. isAccountCreate\" style={{ width: 190 }} className=\"fg-mono-input\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'verifyLockedLabel']} label=\"Locked text\" style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"Verified\" style={{ width: 110 }} />\n                              </Form.Item>\n                            </>\n                          )}\n                        </div>\n                        {action && (\n                          <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                            Changing the verified value resets the result and disables any configured validation gate.\n                            &nbsp;Locked-when fields mark a value that can no longer be re-checked (an account already\n                            exists for it) — the edit form then shows the locked text and no button.\n                          </p>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Payload Mapping — config-driven transform engine */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const fType = getFieldValue([...fAbs, 'type']);\n                    const dType = getFieldValue([...fAbs, 'dataType']) ?? 'auto';\n                    const pMode = getFieldValue([...fAbs, 'payloadMode']) ?? 'auto';\n                    const isChoice = ['select', 'radio', 'checkbox'].includes(fType);\n                    const needsKeys = ['label', 'object', 'custom'].includes(pMode);\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Payload Mapping</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'payloadKey']} label=\"Payload Key\"\n                            style={{ marginBottom: 8 }}>\n                            <Input size=\"small\" placeholder=\"defaults to field key\"\n                              style={{ width: 180 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'prefillFrom']} label=\"Prefill From\"\n                            tooltip=\"Source path to inherit this field's value from when the record is created by prefilling another module (e.g. submission ← candidate). Dotted paths allowed, e.g. passport.passportNumber.\"\n                            style={{ marginBottom: 8 }}>\n                            <Input size=\"small\" placeholder=\"source key (cross-module prefill)\"\n                              style={{ width: 200 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'prefillAsHint']} label=\"Show instead of filling\"\n                            valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                            tooltip=\"On: the prefilled value is shown as a note UNDER the field and the box stays empty. Use it for anything that must be decided fresh each time — a rate carried forward looks helpful, but a number already in the box gets submitted unread.\">\n                            <Switch size=\"small\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'prefillHintLabel']} label=\"Note wording\"\n                            style={{ marginBottom: 0 }}\n                            tooltip={'Shown under the field. \"{value}\" is replaced by the previous value. Blank uses \"Last recorded: {value}\".'}>\n                            <Input size=\"small\" style={{ width: 260 }} placeholder=\"Last recorded: {value}\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'prefillFromModule']} label=\"Prefill From Module\"\n                            tooltip=\"Prefill this field from ANOTHER module's record linked in the URL instead of the default source — e.g. 'job' makes Quick Submit fill this field from the current job (with Prefill From naming the job's key, e.g. mspreqId). Leave blank for the normal prefill source.\"\n                            style={{ marginBottom: 8 }}>\n                            <Input size=\"small\" placeholder=\"e.g. job\"\n                              style={{ width: 160 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Form.Item shouldUpdate noStyle>\n                            {({ getFieldValue, setFieldValue }) => {\n                              const rows = getFieldValue(['fields', rowName, 'prefillWhen']) ?? [];\n                              const lookupCollection = getFieldValue(['fields', rowName, 'lookupCollection']);\n                              const displayField = getFieldValue(['fields', rowName, 'displayField']);\n                              const valueField = getFieldValue(['fields', rowName, 'valueField']) || '_id';\n                              const update = (i, patch) => {\n                                const next = rows.map((r, idx) => (idx === i ? { ...r, ...patch } : r));\n                                setFieldValue(['fields', rowName, 'prefillWhen'], next);\n                              };\n                              return (\n                                <div style={{ width: '100%', margin: '4px 0 8px' }}>\n                                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n                                    <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                                      Conditional Default — when a field matches, set this field to a chosen record\n                                      (or tick Clear to empty it instead)\n                                    </Text>\n                                    <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                                      onClick={() => setFieldValue(['fields', rowName, 'prefillWhen'], [...rows, { field: '', value: '', setValue: '' }])}>\n                                      Add\n                                    </Button>\n                                  </div>\n                                  {rows.length > 0 && (\n                                    <Form.Item name={[rowName, 'prefillWhenReset']} valuePropName=\"checked\"\n                                      initialValue={true} style={{ marginBottom: 0, marginTop: 6 }}\n                                      tooltip=\"When the watched field changes to a value with NO matching row above (e.g. Contract Type switches away from W2), clear this field back out — but only if it still holds exactly the default a rule set (a value the admin/user picked themselves is never touched). Off keeps the old default in place.\">\n                                      <Checkbox>Reset this field when the condition no longer matches</Checkbox>\n                                    </Form.Item>\n                                  )}\n                                  {rows.length > 0 && (\n                                    <Form.Item name={[rowName, 'prefillWhenExclusive']} valuePropName=\"checked\"\n                                      initialValue={false} style={{ marginBottom: 0, marginTop: 2 }}\n                                      tooltip=\"Treat each record chosen above as EXCLUSIVE to its condition: it is offered in this dropdown only while its row matches, and is removed from the list entirely the rest of the time (including before the watched field is filled in). Use it when the record is only ever a valid choice under that condition — not merely its default. Off (the default) leaves the dropdown offering everything, as before.\">\n                                      <Checkbox>Offer the chosen record ONLY while its condition matches (hide it otherwise)</Checkbox>\n                                    </Form.Item>\n                                  )}\n                                  {rows.map((row, i) => (\n                                    <div key={i} style={{ display: 'flex', gap: 6, alignItems: 'center', marginTop: 6 }}>\n                                      <Input size=\"small\" placeholder=\"when field (e.g. contractType)\" className=\"fg-mono-input\"\n                                        style={{ width: 180 }} value={row.field}\n                                        onChange={(e) => update(i, { field: e.target.value })} />\n                                      <span style={{ color: '#94a3b8', fontSize: 12 }}>=</span>\n                                      <Input size=\"small\" placeholder=\"value (e.g. W2-Fulltime)\" className=\"fg-mono-input\"\n                                        style={{ width: 150 }} value={row.value}\n                                        onChange={(e) => update(i, { value: e.target.value })} />\n                                      <span style={{ color: '#94a3b8', fontSize: 12 }}>→</span>\n                                      {/* Clear instead of set: the same rule shape, inverted. A cleared\n                                          row has no record to pick, so the lookup select is replaced by\n                                          a plain hint — flipping the switch back restores the picker with\n                                          whatever record was chosen before (setValue is kept in editor\n                                          state and only stripped at save time). */}\n                                      {row.clearValue ? (\n                                        <Text type=\"secondary\" style={{ fontSize: 12, width: 220 }}>\n                                          clear this field\n                                        </Text>\n                                      ) : (\n                                        <LookupRecordSelect\n                                          collection={lookupCollection}\n                                          displayField={displayField}\n                                          valueField={valueField}\n                                          value={row.setValue}\n                                          labelValue={row.setValueLabel}\n                                          onChange={(v, label) => update(i, { setValue: v, setValueLabel: label })}\n                                        />\n                                      )}\n                                      <Checkbox\n                                        checked={Boolean(row.clearValue)}\n                                        onChange={(e) => update(i, { clearValue: e.target.checked })}\n                                      >\n                                        <span style={{ fontSize: 12 }}>Clear</span>\n                                      </Checkbox>\n                                      <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />}\n                                        onClick={() => setFieldValue(['fields', rowName, 'prefillWhen'], rows.filter((_, idx) => idx !== i))} />\n                                    </div>\n                                  ))}\n                                </div>\n                              );\n                            }}\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'dataType']} label=\"Data Type\"\n                            style={{ marginBottom: 8 }} initialValue=\"auto\">\n                            <Select size=\"small\" style={{ width: 170 }} options={DATA_TYPES}\n                              getPopupContainer={() => document.body} />\n                          </Form.Item>\n                          {dType === 'array' && (\n                            <Form.Item name={[rowName, 'elementType']} label=\"Array Element Type\"\n                              style={{ marginBottom: 8 }}>\n                              <Select size=\"small\" style={{ width: 130 }} options={ELEMENT_TYPES}\n                                getPopupContainer={() => document.body} />\n                            </Form.Item>\n                          )}\n                          <Form.Item name={[rowName, 'payloadMode']} label=\"Payload Mode\"\n                            style={{ marginBottom: 8 }} initialValue=\"auto\">\n                            <Select size=\"small\" style={{ width: 210 }} options={PAYLOAD_MODES}\n                              getPopupContainer={() => document.body} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'defaultValue']} label=\"Default Value\"\n                            style={{ marginBottom: 8 }}>\n                            <Input size=\"small\" placeholder=\"optional\" style={{ width: 130 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'defaultOnEdit']} label=\"Default on Edit\"\n                            valuePropName=\"checked\" style={{ marginBottom: 8 }}\n                            tooltip=\"When the stored value is empty, show Default Value in edit form. Keep off for fields that should remain blank on edit.\">\n                            <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'noPrefill']} label=\"No Prefill\"\n                            valuePropName=\"checked\" style={{ marginBottom: 8 }}\n                            tooltip=\"Always render this field blank on edit instead of showing the stored value. For fields that capture a NEW entry each time rather than the record's current state — e.g. Billing Update's Amount Received, where each save records one more client payment.\">\n                            <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'emptyValues']} label=\"Empty Values\"\n                            style={{ marginBottom: 8 }}\n                            tooltip=\"Comma separated stored values that should render as blank in edit form. Example: 0, candidate\">\n                            <Input size=\"small\" placeholder=\"e.g. 0, candidate\" style={{ width: 170 }} />\n                          </Form.Item>\n                          <Form.Item name={[rowName, 'valuePaths']} label=\"Value Paths\"\n                            style={{ marginBottom: 8 }}\n                            tooltip=\"Comma separated read paths for edit/detail prefill. Supports array filters like socialProfiles[type=linkedin].value.\">\n                            <Input size=\"small\" placeholder=\"linkedIn, socialProfiles[type=linkedin].value\"\n                              style={{ width: 300 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                        </div>\n\n                        {(needsKeys || isChoice) && (\n                          <div className=\"fg-field-meta-row\">\n                            <Form.Item name={[rowName, 'valueKey']} label=\"Value Key (id)\"\n                              style={{ marginBottom: 8, flex: 1 }}>\n                              <Input size=\"small\" placeholder=\"e.g. id\" className=\"fg-mono-input\" />\n                            </Form.Item>\n                            <Form.Item name={[rowName, 'displayKey']} label=\"Display Key (label)\"\n                              style={{ marginBottom: 8, flex: 1 }}>\n                              <Input size=\"small\" placeholder=\"e.g. name\" className=\"fg-mono-input\" />\n                            </Form.Item>\n                            {isChoice && (\n                              <Form.Item name={[rowName, 'richValue']} label=\"Keep label\"\n                                valuePropName=\"checked\" style={{ marginBottom: 8 }} initialValue={false}>\n                                <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                              </Form.Item>\n                            )}\n                          </div>\n                        )}\n\n                        {pMode === 'custom' && (\n                          <div style={{ marginBottom: 8 }}>\n                            <span className=\"fg-static-options-hint\">\n                              Payload Template (JSON) — tokens: {'{{value}} {{label}} {{raw.field}}'}\n                            </span>\n                            <Form.Item name={[rowName, 'payloadTemplate']} style={{ marginBottom: 0 }}>\n                              <Input.TextArea rows={2} className=\"fg-mono-input\"\n                                placeholder={'{ \"countryId\": \"{{value}}\", \"countryName\": \"{{label}}\" }'} />\n                            </Form.Item>\n                          </div>\n                        )}\n\n                        <details style={{ marginTop: 4 }}>\n                          <summary className=\"fg-source-hint\" style={{ cursor: 'pointer' }}>\n                            Advanced: transform rule / omit empty\n                          </summary>\n                          <div style={{ marginTop: 6 }}>\n                            <span className=\"fg-static-options-hint\">\n                              Transform Rule (JSON) — e.g. {'{ \"map\": { \"true\": \"high\", \"false\": \"medium\" } }'}\n                            </span>\n                            <Form.Item name={[rowName, 'transformRule']} style={{ marginBottom: 6 }}>\n                              <Input.TextArea rows={2} className=\"fg-mono-input\"\n                                placeholder={'{ \"map\": { \"true\": \"high\" }, \"default\": \"medium\" }'} />\n                            </Form.Item>\n                            <Form.Item name={[rowName, 'omitEmpty']} label=\"Omit when empty\"\n                              valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue={false}>\n                              <Switch size=\"small\" checkedChildren=\"Omit\" unCheckedChildren=\"Send\" />\n                            </Form.Item>\n                          </div>\n                        </details>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Input Validator — real-time character restriction */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const fType = getFieldValue([...fAbs, 'type']);\n                    // Only text-like fields need input restriction\n                    if (['select', 'radio', 'checkbox', 'date', 'time', 'file', 'location'].includes(fType)) return null;\n                    const vType = getFieldValue([...fAbs, 'validator', 'type']);\n                    const needsMaxLen  = vType && !['email', 'websiteUrl', 'jobDescription'].includes(vType);\n                    const needsMaxChar = vType === 'jobDescription';\n                    return (\n                      <div className=\"fg-options-block\">\n                        <span className=\"fg-options-label\">Input Validator</span>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'validator', 'type']} label=\"Type\"\n                            style={{ marginBottom: 0 }}>\n                            <Select\n                              size=\"small\"\n                              allowClear\n                              placeholder=\"None — no char restriction\"\n                              style={{ width: 260 }}\n                              options={INPUT_VALIDATOR_TYPES}\n                            />\n                          </Form.Item>\n                          {needsMaxLen && (\n                            <Form.Item name={[rowName, 'validator', 'maxLength']} label=\"Max Length\"\n                              style={{ marginBottom: 0 }}>\n                              <Input size=\"small\" type=\"number\" min={1} placeholder=\"e.g. 55\" style={{ width: 90 }} />\n                            </Form.Item>\n                          )}\n                          {needsMaxChar && (\n                            <Form.Item name={[rowName, 'validator', 'maxChars']} label=\"Max Chars\"\n                              style={{ marginBottom: 0 }}>\n                              <Input size=\"small\" type=\"number\" min={1} placeholder=\"1500\" style={{ width: 90 }} />\n                            </Form.Item>\n                          )}\n                          {vType && (\n                            <Form.Item name={[rowName, 'validator', 'title']} label=\"Error Title\"\n                              style={{ marginBottom: 0 }}\n                              tooltip=\"Used in error messages. Defaults to the field label when blank.\">\n                              <Input size=\"small\" placeholder={getFieldValue([...fAbs, 'label']) || 'Field'} style={{ width: 180 }} />\n                            </Form.Item>\n                          )}\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* Field Interactions — disabled-by / clear-on-check / autofill */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const fType = getFieldValue([...fAbs, 'type']);\n                    const isChk = fType === 'checkbox';\n                    const isLookup = fType === 'select' && getFieldValue([...fAbs, 'dataSource']) === 'lookup';\n                    if (!isChk && !isLookup) {\n                      return (\n                        <div className=\"fg-options-block\">\n                          <span className=\"fg-options-label\">Grey this out when a tick-box is ticked</span>\n                          <Form.Item name={[rowName, 'disabledByField']} style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"sibling field key (e.g. currentlyPursuing)\"\n                              className=\"fg-mono-input\" style={{ width: 260 }} />\n                          </Form.Item>\n                          <p className=\"fg-source-hint\">\n                            Name a tick-box in the same section. While it is ticked, this box is\n                            greyed out and cannot be typed in. Use it when the answer stops\n                            applying — for example an End Date once &quot;still working here&quot;\n                            is ticked. To HIDE the box completely instead of greying it out, use\n                            Show Condition above with the operator &quot;is empty/false&quot;.\n                          </p>\n\n                          <span className=\"fg-options-label\">Require this once a sibling field has a value</span>\n                          <Form.Item name={[rowName, 'requiredIfField']} style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"sibling field key (e.g. empSigninAuthAlternatePhone)\"\n                              className=\"fg-mono-input\" style={{ width: 260 }} />\n                          </Form.Item>\n                          <p className=\"fg-source-hint\">\n                            Name a field in the same section. This field becomes mandatory only once\n                            that sibling has a value — e.g. an alternate phone&apos;s country code\n                            required only after the alternate phone number itself is entered. Works\n                            independently of the Required toggle above.\n                          </p>\n\n                          {/* Only meaningful for a phone-style box, but shown for any text\n                              field: a tenant may store a number under a key this screen\n                              cannot recognise, and hiding the control would make that\n                              config unreachable. */}\n                          <div style={{ marginTop: 14 }}>\n                            <span className=\"fg-options-label\">Put the country code in its own box</span>\n                            <Form.Item name={[rowName, 'splitDialCodeInto']} style={{ marginBottom: 0 }}>\n                              <Input size=\"small\" placeholder=\"e.g. contactCountryCode\"\n                                className=\"fg-mono-input\" style={{ width: 260 }} />\n                            </Form.Item>\n                            <p className=\"fg-source-hint\">\n                              For phone-number boxes. When a number arrives with its country code\n                              attached — from a parsed résumé, or copied from somewhere else —\n                              the code is put into the box you name here and only the number\n                              stays in this one. Leave blank to keep the value exactly as it\n                              arrives. If a number comes in with no country code, the other box\n                              is left alone rather than being filled with a guess.\n                            </p>\n                          </div>\n                        </div>\n                      );\n                    }\n                    if (isChk) {\n                      return (\n                        <div className=\"fg-options-block\">\n                          <span className=\"fg-options-label\">Empty another box when this is ticked</span>\n                          <Form.Item name={[rowName, 'linkedClearField']} style={{ marginBottom: 0 }}>\n                            <Input size=\"small\" placeholder=\"sibling field key to clear (e.g. endDate)\"\n                              className=\"fg-mono-input\" style={{ width: 260 }} />\n                          </Form.Item>\n                          <p className=\"fg-source-hint\">\n                            Name the box to empty when someone ticks this. Example: ticking\n                            &quot;Currently working here&quot; clears the End Date, so an old date\n                            cannot be left behind by accident. You can name more than one box by\n                            separating them with commas.\n                          </p>\n                          <div style={{ marginTop: 10 }}>\n                            <Form.Item name={[rowName, 'exclusiveInGroup']} valuePropName=\"checked\" style={{ marginBottom: 0 }}>\n                              <Switch size=\"small\" checkedChildren=\"One row only\" unCheckedChildren=\"Any row\" />\n                            </Form.Item>\n                            <p className=\"fg-source-hint\">\n                              Only one row of a repeatable group may have this checked — e.g. Currently\n                              Working Here / Currently Pursuing. Once a row is ticked the box is disabled\n                              on every other row; untick it to move the claim. No effect outside a\n                              repeatable group.\n                            </p>\n                          </div>\n                        </div>\n                      );\n                    }\n                    if (isLookup) {\n                      return (\n                        <div className=\"fg-options-block\">\n                          <span className=\"fg-options-label\">When this changes, clear the rest of the group</span>\n                          <Form.Item name={[rowName, 'clearGroupOnChange']} valuePropName=\"checked\" style={{ marginBottom: 0 }}>\n                            <Switch size=\"small\" checkedChildren=\"Clear\" unCheckedChildren=\"Keep\" />\n                          </Form.Item>\n                          <p className=\"fg-source-hint\">\n                            Turn this on when the other fields in this group describe whatever is\n                            picked here. Example: the Employer box. Email, phone and recruiter all\n                            belong to the employer that was selected, so if someone picks a\n                            different employer those details are now the wrong company&apos;s — and\n                            because the boxes still look filled in, nobody notices. With this on,\n                            they are emptied the moment the selection changes, ready for the new\n                            one. Inside a repeat section only that row is cleared.\n                          </p>\n\n                          <div style={{ marginTop: 14 }}>\n                            <span className=\"fg-options-label\">Autofill Fields (JSON)</span>\n                          <Form.Item name={[rowName, 'autofillFrom']} style={{ marginBottom: 0 }}>\n                            <Input.TextArea rows={3} className=\"fg-mono-input\"\n                              placeholder={'[{\"optionKey\":\"vendorContact.email\",\"targetField\":\"vendorEmail\"}]'} />\n                          </Form.Item>\n                            <p className=\"fg-source-hint\">\n                              Copy details from the record someone picks into other boxes in this\n                              group, so they do not have to type them again. Example: choosing a\n                              recruiter fills in their email and phone. One entry per box:\n                              <b> optionKey</b> is where the value sits on the picked record, and\n                              <b> targetField</b> is the box to put it in.\n                            </p>\n                          </div>\n                        </div>\n                      );\n                    }\n                    return null;\n                  }}\n                </Form.Item>\n\n                {/* Validations */}\n                <div className=\"fg-validations-section\">\n                  <div className=\"fg-validations-header\">\n                    <SafetyCertificateOutlined className=\"fg-val-icon\" />\n                    <span className=\"fg-val-title\">Validations</span>\n                  </div>\n                  <Form.List name={[rowName, 'validations']}>\n                    {(valItems, { add: addVal, remove: removeVal }) => (\n                      <>\n                        {valItems.map(({ key: vKey, name: vName }) => (\n                          <Form.Item shouldUpdate key={vKey} style={{ marginBottom: 6 }}>\n                            {({ getFieldValue }) => {\n                              const vType = getFieldValue([...fieldsAbs, rowName, 'validations', vName, 'type']);\n                              const meta = validationMeta(vType);\n                              const fieldType = getFieldValue([...fieldsAbs, rowName, 'type']);\n                              const isDateRelation = vType === 'dateAfterField' || vType === 'dateBeforeField';\n                              const siblingDateOptions = (getFieldValue(fieldsAbs) ?? [])\n                                .map((candidate, index) => ({ candidate, index }))\n                                .filter(({ candidate, index }) => index !== rowName && candidate?.type === 'date' && candidate?.field)\n                                .map(({ candidate }) => ({\n                                  value: candidate.field,\n                                  label: `${candidate.label || candidate.field} (${candidate.field})`,\n                                }));\n                              // maxFromField's cap can sit anywhere in the module — the\n                              // overall-experience field capping a relevant-skill row lives\n                              // in a DIFFERENT group — so the picker offers every field key\n                              // known to this editor and still accepts free text for a key\n                              // that only exists in another group.\n                              const siblingFieldOptions = (getFieldValue(fieldsAbs) ?? [])\n                                .map((candidate, index) => ({ candidate, index }))\n                                .filter(({ candidate, index }) => index !== rowName && candidate?.field)\n                                .map(({ candidate }) => ({\n                                  value: candidate.field,\n                                  label: `${candidate.label || candidate.field} (${candidate.field})`,\n                                }));\n                              const validationOptions = VALIDATION_TYPES\n                                // A date field is otherwise restricted to date-only rules;\n                                // uniqueness is listed there too because a date IS a scalar\n                                // and uniqueFieldTypeSupport allows it — hiding it here\n                                // would contradict the rule that actually gates saving.\n                                .filter((option) => fieldType === 'date'\n                                  ? option.dateOnly || option.value === 'required' || option.value === UNIQUE_VALIDATION_TYPE\n                                  : !option.dateOnly)\n                                .map((option) => ({ label: option.label, value: option.value }));\n\n                              // ── Uniqueness ────────────────────────────────────────\n                              // The one rule whose value is a config OBJECT, so it\n                              // replaces the single Value input with its own row of\n                              // controls bound to nested paths ([vName,'value',<key>])\n                              // — the same nesting the showIf editor uses.\n                              const isUnique = vType === UNIQUE_VALIDATION_TYPE;\n                              const rowField = getFieldValue([...fieldsAbs, rowName]) ?? {};\n                              const uniqueSupport = uniqueFieldTypeSupport(rowField);\n                              const uniqueValuePath = [...fieldsAbs, rowName, 'validations', vName, 'value'];\n                              const uniqueConfig = isUnique\n                                ? normalizeUniqueConfig(getFieldValue(uniqueValuePath), rowField)\n                                : null;\n                              const uniqueTargetInfo = isUnique\n                                ? resolveUniqueTarget({\n                                    primaryModule: uniqueTarget.primaryModule,\n                                    // Read live: a group whose Target Collection is set\n                                    // writes these fields to THAT module via moduleWrites,\n                                    // so that is the module the value must be unique in.\n                                    groupTargetModule: uniqueTarget.getTargetModule(),\n                                    field: rowField,\n                                    config: uniqueConfig,\n                                    collectionForModule: uniqueTarget.collectionForModule,\n                                  })\n                                : null;\n                              // Suggestions for the stored key. Unlike the cross-field\n                              // rules above, the field's OWN key is the usual answer here\n                              // (the value is compared against where it is stored), so the\n                              // current row is included rather than filtered out.\n                              const uniqueKeyOptions = (getFieldValue(fieldsAbs) ?? [])\n                                .filter((candidate) => candidate?.field)\n                                .map((candidate) => {\n                                  const key = String(candidate.payloadKey ?? '').trim() || candidate.field;\n                                  return { value: key, label: `${candidate.label || candidate.field} (${key})` };\n                                });\n                              return (\n                                <>\n                                <div className=\"fg-val-row\">\n                                  <Form.Item name={[vName, 'type']} style={{ marginBottom: 0 }}\n                                    rules={[\n                                      { required: true, message: 'Pick type' },\n                                      // Uniqueness on a list/rich-text field would save a\n                                      // rule the backend could never evaluate, so it is\n                                      // refused HERE (blocking the save) rather than\n                                      // dropped quietly at build time.\n                                      {\n                                        validator: (_, value) => (value === UNIQUE_VALIDATION_TYPE && !uniqueSupport.supported\n                                          ? Promise.reject(new Error(uniqueSupport.reason))\n                                          : Promise.resolve()),\n                                      },\n                                    ]}>\n                                    <Select size=\"small\" placeholder={fieldType === 'date' ? 'Date condition' : 'Type'} style={{ width: 210 }}\n                                      listHeight={400} getPopupContainer={() => document.body}\n                                      options={validationOptions}\n                                      onChange={(next) => {\n                                        // Seed / clear the object value as the type\n                                        // changes. Without the seed the nested config\n                                        // controls would sit on the empty string the\n                                        // \"Add Validation\" button starts every row with;\n                                        // without the clear, a scalar rule would inherit\n                                        // a leftover object.\n                                        if (next === UNIQUE_VALIDATION_TYPE) {\n                                          const current = form.getFieldValue(uniqueValuePath);\n                                          form.setFieldValue(uniqueValuePath,\n                                            normalizeUniqueConfig(current, form.getFieldValue([...fieldsAbs, rowName]) ?? {}));\n                                        } else if (typeof form.getFieldValue(uniqueValuePath) === 'object') {\n                                          form.setFieldValue(uniqueValuePath, '');\n                                        }\n                                      }} />\n                                  </Form.Item>\n                                  {meta.hasValue && !isUnique && (\n                                    <Form.Item name={[vName, 'value']} style={{ marginBottom: 0 }}>\n                                      {isDateRelation ? (\n                                        <Select\n                                          size=\"small\"\n                                          showSearch\n                                          allowClear\n                                          placeholder=\"Related date field\"\n                                          style={{ width: 210 }}\n                                          options={siblingDateOptions}\n                                          optionFilterProp=\"label\"\n                                          getPopupContainer={() => document.body}\n                                        />\n                                      ) : (\n                                        <Input size=\"small\"\n                                          type={meta.valueType === 'number' ? 'number' : 'text'}\n                                          placeholder={meta.placeholder} style={{ width: 90 }} />\n                                      )}\n                                    </Form.Item>\n                                  )}\n                                  {meta.needsField && (\n                                    <Form.Item name={[vName, 'field']} style={{ marginBottom: 0 }}\n                                      rules={[{ required: true, message: 'Pick the capping field' }]}>\n                                      <AutoComplete size=\"small\" style={{ width: 210 }}\n                                        placeholder=\"capped by field, e.g. totalExperience\"\n                                        options={siblingFieldOptions}\n                                        filterOption={(input, option) => String(option?.label ?? '')\n                                          .toLowerCase().includes(String(input).toLowerCase())}\n                                        getPopupContainer={() => document.body} />\n                                    </Form.Item>\n                                  )}\n                                  <Form.Item name={[vName, 'message']} style={{ marginBottom: 0, flex: 1 }}\n                                    rules={meta.messageOptional\n                                      ? []\n                                      // A blank \"already present\" message leaves the user\n                                      // with no idea what to change, so it is rejected —\n                                      // whitespace included.\n                                      : [{ required: true, whitespace: true, message: 'Message required' }]}>\n                                    <Input size=\"small\"\n                                      placeholder={meta.messageOptional\n                                        ? 'Optional — uses default'\n                                        : isUnique\n                                          ? 'e.g. Email already present'\n                                          : 'Error message shown to user'} />\n                                  </Form.Item>\n                                  <MinusCircleOutlined className=\"fg-remove-icon\" style={{ marginTop: 4 }}\n                                    onClick={() => removeVal(vName)} />\n                                </div>\n                                {/* Date-pair options. Writing the rule on ONE side\n                                    constrains only that picker, so a date range is\n                                    normally configured as a PAIR (start declares\n                                    \"on/before end\", end declares \"on/after start\")\n                                    and these options are set on both. */}\n                                {isDateRelation && (\n                                  <div className=\"fg-options-block\" style={{ marginTop: 6 }}>\n                                    <span className=\"fg-options-label\">Start and end date rules</span>\n                                    <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                                      <Form.Item name={[vName, 'strict']} label=\"Must be different days\"\n                                        valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                                        tooltip=\"On: the start and end cannot be the same day. Pick 7 July as the start and the calendar greys out 7 July and everything before it on the end date. Off: the same day is allowed on both.\"\n                                        >\n                                        <Switch size=\"small\" checkedChildren=\"Different days\" unCheckedChildren=\"Same day OK\" />\n                                      </Form.Item>\n                                      <Form.Item name={[vName, 'minGap', 'value']} label=\"Smallest gap allowed\"\n                                        style={{ marginBottom: 0 }}\n                                        tooltip=\"How far apart the two dates must be at least. The calendar greys out everything closer than this, so it is clear before anyone picks — not an error afterwards. Leave blank if any gap is fine.\">\n                                        <Input size=\"small\" type=\"number\" min={0} placeholder=\"e.g. 6\" style={{ width: 90 }} />\n                                      </Form.Item>\n                                      <Form.Item name={[vName, 'minGap', 'unit']} label=\"Unit\"\n                                        style={{ marginBottom: 0 }} initialValue=\"month\">\n                                        <Select size=\"small\" style={{ width: 110 }}\n                                          getPopupContainer={() => document.body}\n                                          options={[\n                                            { label: 'Days', value: 'day' },\n                                            { label: 'Weeks', value: 'week' },\n                                            { label: 'Months', value: 'month' },\n                                            { label: 'Years', value: 'year' },\n                                          ]} />\n                                      </Form.Item>\n                                      <Form.Item name={[vName, 'minGapFrom']} label=\"Let the user choose the gap\"\n                                        style={{ marginBottom: 0 }}\n                                        tooltip=\"Optional. Name a dropdown on the same row that lets the user pick the gap themselves — for example a Duration box offering '6 months'. Whatever they choose is used instead of the fixed gap above; if they leave it empty, the fixed gap applies.\"\n                                        >\n                                        <AutoComplete size=\"small\" style={{ width: 190 }}\n                                          placeholder=\"e.g. duration\"\n                                          options={siblingFieldOptions}\n                                          filterOption={(input, option) => String(option?.label ?? '')\n                                            .toLowerCase().includes(String(input).toLowerCase())}\n                                          getPopupContainer={() => document.body} />\n                                      </Form.Item>\n                                    </div>\n                                  </div>\n                                )}\n                                {isUnique && (\n                                  <div className=\"fg-options-block\" style={{ marginTop: 6 }}>\n                                    <span className=\"fg-options-label\">Uniqueness settings</span>\n                                    {!uniqueSupport.supported ? (\n                                      <Alert type=\"warning\" showIcon style={{ marginTop: 4 }}\n                                        message=\"Uniqueness is not available for this field type\"\n                                        description={uniqueSupport.reason} />\n                                    ) : (\n                                      <>\n                                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                                          {/* Bound to the NESTED config path — the same\n                                              nesting pattern the showIf editor uses — so\n                                              the whole object round-trips as one value. */}\n                                          <Form.Item name={[vName, 'value', 'collectionField']} label=\"Collection field\"\n                                            style={{ marginBottom: 0 }}\n                                            tooltip=\"The key this value is stored under in the target collection. Dot paths allowed, e.g. passport.passportNumber. Defaults to the field's payload key.\"\n                                            rules={[{\n                                              validator: (_, value) => {\n                                                const err = collectionFieldPathError(value);\n                                                return err ? Promise.reject(new Error(err)) : Promise.resolve();\n                                              },\n                                            }]}>\n                                            <AutoComplete size=\"small\" style={{ width: 220 }}\n                                              className=\"fg-mono-input\"\n                                              placeholder={uniqueTargetInfo?.storedField || 'stored key'}\n                                              options={uniqueKeyOptions}\n                                              filterOption={(input, option) => String(option?.label ?? '')\n                                                .toLowerCase().includes(String(input).toLowerCase())}\n                                              getPopupContainer={() => document.body} />\n                                          </Form.Item>\n                                          <Form.Item name={[vName, 'value', 'normalizer']} label=\"Normalization\"\n                                            style={{ marginBottom: 0 }}\n                                            tooltip=\"How the value is normalised on BOTH sides before comparing. The server applies the same rule.\">\n                                            <Select size=\"small\" style={{ width: 210 }}\n                                              options={UNIQUE_NORMALIZERS}\n                                              getPopupContainer={() => document.body} />\n                                          </Form.Item>\n                                          <Form.Item name={[vName, 'value', 'validateOn']} label=\"Check when\"\n                                            style={{ marginBottom: 0 }}\n                                            tooltip=\"Blur checks as soon as the user leaves the field. Either way the value is re-checked authoritatively on submit.\">\n                                            <Select size=\"small\" style={{ width: 190 }}\n                                              options={UNIQUE_VALIDATION_TRIGGERS}\n                                              getPopupContainer={() => document.body} />\n                                          </Form.Item>\n                                          <Form.Item name={[vName, 'value', 'skipBlank']} label=\"Skip blank\"\n                                            valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                                            tooltip=\"On: two records that both left this field empty are not duplicates. Turn off only when a blank must itself be unique.\">\n                                            <Switch size=\"small\" checkedChildren=\"Skip\" unCheckedChildren=\"Check\" />\n                                          </Form.Item>\n                                          <Form.Item name={[vName, 'value', 'enforcement']} label=\"How it is checked\"\n                                            style={{ marginBottom: 0 }}\n                                            tooltip={'Look at the field: checking email means reading the email of every other record. Nothing extra is stored. Keep a hidden copy: also saves a tidied-up copy of the value on the record and puts a database rule on it — only needed if two people might create the very same value at the exact same moment, and it needs the database rule to be created first.'}>\n                                            <Select size=\"small\" style={{ width: 220 }}\n                                              options={UNIQUE_ENFORCEMENT_MODES}\n                                              getPopupContainer={() => document.body} />\n                                          </Form.Item>\n                                        </div>\n                                        {/* Read-only resolved target. The COLLECTION comes\n                                            from module configuration (the module registry\n                                            via adminApi) — never from anything typed here —\n                                            and the server resolves it again on every\n                                            request, so this strip is informational only. */}\n                                        <p className=\"fg-source-hint\" style={{ marginTop: 6 }}>\n                                          Target module: <code>{uniqueTargetInfo?.module || '—'}</code>\n                                          {' · '}Target collection: <code>{uniqueTargetInfo?.collection || 'resolved on the server'}</code>\n                                          {' · '}Form field: <code>{uniqueTargetInfo?.formField || '—'}</code>\n                                          {' · '}Stored field: <code>{uniqueTargetInfo?.storedField || '—'}</code>\n                                        </p>\n                                        {uniqueTargetInfo?.isCrossModule && (\n                                          <p className=\"fg-source-hint\">\n                                            This group writes to <code>{uniqueTargetInfo.module}</code> through its Target\n                                            Collection, so the value is checked for uniqueness there — not in the module\n                                            you are editing.\n                                          </p>\n                                        )}\n                                        {/* ── Additional collections ──────────────\n                                            The same value checked in MORE than one\n                                            place, because a value provisioned out of\n                                            this record (a contact row that becomes a\n                                            login) is only really free when both are\n                                            clear. Bound to the same nested config\n                                            object, so it saves and loads with the\n                                            rest of the rule. */}\n                                        <Form.List name={[vName, 'value', 'alsoCheck']}>\n                                          {(alsoItems, { add: addAlso, remove: removeAlso }) => (\n                                            <div style={{ marginTop: 8 }}>\n                                              <span className=\"fg-options-label\">\n                                                Also check these collections\n                                              </span>\n                                              {alsoItems.map(({ key: alsoKey, name: alsoName, ...alsoRest }) => (\n                                                <div key={alsoKey} className=\"fg-options-controls\"\n                                                  style={{ flexWrap: 'wrap', alignItems: 'flex-end', marginTop: 4 }}>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'module']} label=\"Module\"\n                                                    style={{ marginBottom: 0 }}\n                                                    tooltip=\"Preferred. Resolved to a collection on the SERVER through the module registry — the browser never names a collection.\">\n                                                    <Input size=\"small\" style={{ width: 150 }}\n                                                      className=\"fg-mono-input\" placeholder=\"e.g. users\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'collection']} label=\"or Collection\"\n                                                    style={{ marginBottom: 0 }}\n                                                    tooltip=\"Only when the target is not a registered module. A single collection name — never a path.\">\n                                                    <Input size=\"small\" style={{ width: 150 }}\n                                                      className=\"fg-mono-input\" placeholder=\"(optional)\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'collectionField']} label=\"Field there\"\n                                                    style={{ marginBottom: 0 }}\n                                                    tooltip=\"The stored key in THAT collection. Defaults to this field's own key.\">\n                                                    <Input size=\"small\" style={{ width: 150 }}\n                                                      className=\"fg-mono-input\" placeholder=\"e.g. email\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'excludeFrom', 'path']}\n                                                    label=\"Exclude ids from\" style={{ marginBottom: 0 }}\n                                                    tooltip={ALSO_CHECK_EXCLUSION_HINT}>\n                                                    <Input size=\"small\" style={{ width: 190 }}\n                                                      className=\"fg-mono-input\" placeholder=\"e.g. recruiters.accountUserId\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'excludeFrom', 'matchField']}\n                                                    label=\"matched on\" style={{ marginBottom: 0 }}\n                                                    tooltip={ALSO_CHECK_EXCLUSION_HINT}>\n                                                    <Input size=\"small\" style={{ width: 140 }}\n                                                      className=\"fg-mono-input\" placeholder=\"_id\" />\n                                                  </Form.Item>\n                                                  <Form.Item {...alsoRest} name={[alsoName, 'message']} label=\"Message\"\n                                                    style={{ marginBottom: 0 }}\n                                                    tooltip=\"Optional override. Blank uses the rule's own message — the user is never told which collection matched.\">\n                                                    <Input size=\"small\" style={{ width: 200 }} placeholder=\"(uses rule message)\" />\n                                                  </Form.Item>\n                                                  <MinusCircleOutlined className=\"fg-remove-icon\"\n                                                    style={{ marginBottom: 6 }}\n                                                    onClick={() => removeAlso(alsoName)} />\n                                                </div>\n                                              ))}\n                                              {(() => {\n                                                // Live feedback: the same checks the\n                                                // save-time backstop runs, shown while\n                                                // the row is still on screen.\n                                                const problems = (uniqueConfig?.alsoCheck ?? [])\n                                                  .flatMap((entry, i) => alsoCheckEntryErrors(entry)\n                                                    .map((err) => `#${i + 1}: ${err}`));\n                                                return problems.length ? (\n                                                  <Alert type=\"error\" showIcon style={{ marginTop: 6 }}\n                                                    message={problems[0]} />\n                                                ) : null;\n                                              })()}\n                                              <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                                                style={{ marginTop: 6 }}\n                                                onClick={() => addAlso(defaultAlsoCheckEntry())}>\n                                                Add collection\n                                              </Button>\n                                              <p className=\"fg-source-hint\" style={{ marginTop: 4 }}>\n                                                {ALSO_CHECK_EXCLUSION_HINT}\n                                              </p>\n                                            </div>\n                                          )}\n                                        </Form.List>\n                                      </>\n                                    )}\n                                  </div>\n                                )}\n                                </>\n                              );\n                            }}\n                          </Form.Item>\n                        ))}\n                        <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                          onClick={() => addVal({ type: '', value: '', field: '', message: '' })}\n                          className=\"fg-add-val-btn\">\n                          Add Validation\n                        </Button>\n                      </>\n                    )}\n                  </Form.List>\n                </div>\n\n                {/* Validation override — a checkbox beside this field's LABEL that\n                    suspends the validation types it names, after an explicit\n                    confirmation. Lives here, under Validations, because that is\n                    what it acts on. See form/validationOverride.js. */}\n                <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                  {({ getFieldValue }) => {\n                    const on = getFieldValue([...fieldsAbs, rowName, 'overrideEnabled']);\n                    // Offer the field's OWN configured validation types, so the\n                    // admin picks from what actually runs here rather than\n                    // typing a type name that may not exist on this field.\n                    const ownTypes = (getFieldValue([...fieldsAbs, rowName, 'validations']) ?? [])\n                      .map((v) => (typeof v === 'string' ? v : v?.type))\n                      .filter(Boolean);\n                    return (\n                      <div className=\"fg-validations-section\">\n                        <div className=\"fg-validations-header\">\n                          <SafetyCertificateOutlined className=\"fg-val-icon\" />\n                          <span className=\"fg-val-title\">Override checkbox</span>\n                        </div>\n                        <div className=\"fg-options-controls\" style={{ flexWrap: 'wrap' }}>\n                          <Form.Item name={[rowName, 'overrideEnabled']} valuePropName=\"checked\"\n                            style={{ marginBottom: 0 }}\n                            tooltip=\"Adds a checkbox beside this field's label that lifts the validations you name below, after asking the user to confirm. Use it where a rule is right almost always and wrong occasionally — e.g. a rate cap a manager has genuinely agreed to exceed.\">\n                            <Switch size=\"small\" checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n                          </Form.Item>\n                          {on && (\n                            <>\n                              <Form.Item name={[rowName, 'overrideSkipValidations']} label=\"Lifts validations\"\n                                style={{ marginBottom: 0 }}\n                                rules={[{ required: true, message: 'Name at least one validation type' }]}\n                                tooltip=\"Which validation TYPES the checkbox suspends. Everything you do NOT name keeps validating — so an override can lift a rate cap without also switching off 'must be a number'.\">\n                                <Select size=\"small\" mode=\"tags\" style={{ minWidth: 260 }}\n                                  placeholder=\"e.g. maxFieldWithFallback\"\n                                  options={ownTypes.map((t) => ({ label: t, value: t }))}\n                                  tokenSeparators={[',']}\n                                  getPopupContainer={() => document.body} />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'overrideLabel']} label=\"Checkbox label\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"Say what becomes allowed, not 'override'. e.g. 'Rate agreed above the job's client rate'.\">\n                                <Input size=\"small\" style={{ width: 280 }}\n                                  placeholder=\"e.g. Rate agreed above the job rate\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'overrideField']} label=\"Stored as\"\n                                style={{ marginBottom: 0 }}\n                                tooltip=\"The record key the flag is stored under. Leave blank for an automatic, collision-free key derived from this field's own key.\">\n                                <Input size=\"small\" className=\"fg-mono-input\" style={{ width: 200 }}\n                                  placeholder=\"blank = automatic\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'overrideStore']} label=\"Record it\"\n                                valuePropName=\"checked\" style={{ marginBottom: 0 }} initialValue\n                                tooltip=\"On (default): the flag is saved on the record, so a value that breaks a documented rule is explained rather than looking like the rule failed. Off: the override applies to this form session only.\">\n                                <Switch size=\"small\" checkedChildren=\"Saved\" unCheckedChildren=\"Session\" />\n                              </Form.Item>\n                            </>\n                          )}\n                        </div>\n                        {on && (\n                          <>\n                            <div className=\"fg-options-controls\" style={{ marginTop: 8, flexWrap: 'wrap' }}>\n                              <Form.Item name={[rowName, 'overrideConfirmTitle']} label=\"Confirm title\"\n                                style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" style={{ width: 300 }}\n                                  placeholder=\"blank = a sensible default\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'overrideConfirmOkText']} label=\"Confirm button\"\n                                style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" style={{ width: 200 }} placeholder=\"e.g. Yes, remove the limit\" />\n                              </Form.Item>\n                              <Form.Item name={[rowName, 'overrideConfirmCancelText']} label=\"Cancel button\"\n                                style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" style={{ width: 200 }} placeholder=\"e.g. Keep the limit\" />\n                              </Form.Item>\n                            </div>\n                            <Form.Item name={[rowName, 'overrideConfirmBody']} label=\"Confirm message\"\n                              style={{ marginBottom: 0, marginTop: 8 }}\n                              tooltip=\"State plainly what is being given up. Blank uses a default that names this field and says the override is recorded.\">\n                              <Input.TextArea size=\"small\" rows={2}\n                                placeholder=\"blank = a sensible default naming this field\" />\n                            </Form.Item>\n                            <p className=\"fg-source-hint\">\n                              Ticking the box asks the user to confirm before the limit comes off;\n                              unticking it restores the limit silently. Either way the field\n                              re-validates immediately.\n                            </p>\n                          </>\n                        )}\n                      </div>\n                    );\n                  }}\n                </Form.Item>\n\n                {/* AI Actions — config-driven \"Generate/Parse\"-style buttons that call\n                    an admin-configured AI/automation service and map its JSON response\n                    onto form fields (scalar fields anywhere, or an addRow group's rows). */}\n                <div className=\"fg-validations-section\">\n                  <div className=\"fg-validations-header\">\n                    <ThunderboltOutlined className=\"fg-val-icon\" />\n                    <span className=\"fg-val-title\">AI Actions</span>\n                  </div>\n                  <Form.List name={[rowName, 'aiActions']}>\n                    {(actionItems, { add: addAction, remove: removeAction }) => (\n                      <>\n                        {actionItems.map(({ key: aKey, name: aName }) => (\n                          <div key={aKey} className=\"fg-ai-action-card\">\n                            <div className=\"fg-val-row\">\n                              <Form.Item name={[aName, 'key']} style={{ marginBottom: 0 }}\n                                rules={[{ required: true, message: 'Key' }]}>\n                                <Input size=\"small\" placeholder=\"key (e.g. generateJD)\" style={{ width: 150 }} />\n                              </Form.Item>\n                              <Form.Item name={[aName, 'label']} style={{ marginBottom: 0 }}\n                                rules={[{ required: true, message: 'Label' }]}>\n                                <Input size=\"small\" placeholder=\"Button label\" style={{ width: 170 }} />\n                              </Form.Item>\n                              <Form.Item name={[aName, 'trigger']} style={{ marginBottom: 0 }} initialValue=\"click\">\n                                <Select size=\"small\" style={{ width: 100 }}\n                                  options={[{ label: 'Click', value: 'click' }, { label: 'Upload', value: 'upload' }]} />\n                              </Form.Item>\n                              <Form.Item name={[aName, 'bodyType']} style={{ marginBottom: 0 }} initialValue=\"json\">\n                                <Select size=\"small\" style={{ width: 110 }}\n                                  options={[{ label: 'JSON', value: 'json' }, { label: 'Multipart', value: 'multipart' }]} />\n                              </Form.Item>\n                              <Form.Item name={[aName, 'position']} style={{ marginBottom: 0 }}>\n                                <Select size=\"small\" style={{ width: 150 }} placeholder=\"Button position\" allowClear\n                                  options={[\n                                    { label: 'Top Left', value: 'top-left' },\n                                    { label: 'Top Center', value: 'top-center' },\n                                    { label: 'Top Right', value: 'top-right' },\n                                    { label: 'Bottom Left', value: 'bottom-left' },\n                                    { label: 'Bottom Center', value: 'bottom-center' },\n                                    { label: 'Bottom Right', value: 'bottom-right' },\n                                  ]} />\n                              </Form.Item>\n                              <MinusCircleOutlined className=\"fg-remove-icon\" style={{ marginTop: 4 }}\n                                onClick={() => removeAction(aName)} />\n                            </div>\n                            <div className=\"fg-val-row\">\n                              <Form.Item name={[aName, 'serviceKey']} style={{ marginBottom: 0 }}\n                                rules={[{ required: true, message: 'Service key' }]}>\n                                <Input size=\"small\" placeholder=\"Service key (e.g. pyOps)\" style={{ width: 170 }} />\n                              </Form.Item>\n                              <Form.Item name={[aName, 'endpointPath']} style={{ marginBottom: 0, flex: 1 }}\n                                rules={[{ required: true, message: 'Endpoint path' }]}>\n                                <Input size=\"small\" placeholder=\"/v1/promtJD\" className=\"fg-mono-input\" />\n                              </Form.Item>\n                            </div>\n\n                            <div className=\"fg-ai-subsection\">\n                              <span className=\"fg-options-label\">\n                                Inputs (form field → request param) — mark an input \"Required\", or\n                                give it a Min Words count, to make the button stay disabled until\n                                that field has a value (or enough words). Inputs sharing the same\n                                \"group\" gate as one unit: either one satisfies it (e.g. a JD file\n                                OR JD text).\n                              </span>\n                              <Form.List name={[aName, 'inputs']}>\n                                {(inputItems, { add: addInput, remove: removeInput }) => (\n                                  <>\n                                    {inputItems.map(({ key: iKey, name: iName }) => (\n                                      <div key={iKey} className=\"fg-val-row\">\n                                        <Form.Item name={[iName, 'param']} style={{ marginBottom: 0 }}>\n                                          <Input size=\"small\" placeholder=\"param\" style={{ width: 100 }} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'sourceField']} style={{ marginBottom: 0 }}>\n                                          <Input size=\"small\" placeholder=\"source field\" className=\"fg-mono-input\" style={{ width: 150 }} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'kind']} style={{ marginBottom: 0 }} initialValue=\"text\">\n                                          <Select size=\"small\" style={{ width: 90 }}\n                                            options={[{ label: 'Text', value: 'text' }, { label: 'File', value: 'file' }]} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'transform']} style={{ marginBottom: 0 }}>\n                                          <Input size=\"small\" placeholder=\"transform\" style={{ width: 120 }} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'group']} style={{ marginBottom: 0 }}>\n                                          <Input size=\"small\" placeholder=\"group (either/or)\" style={{ width: 130 }} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'minWords']} style={{ marginBottom: 0 }}>\n                                          <InputNumber size=\"small\" min={0} placeholder=\"min words\" style={{ width: 100 }} />\n                                        </Form.Item>\n                                        <Form.Item name={[iName, 'required']} valuePropName=\"checked\" style={{ marginBottom: 0 }}>\n                                          <Checkbox>Required</Checkbox>\n                                        </Form.Item>\n                                        <MinusCircleOutlined className=\"fg-remove-icon\" onClick={() => removeInput(iName)} />\n                                      </div>\n                                    ))}\n                                    <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                                      onClick={() => addInput({ kind: 'text' })}>\n                                      Add Input\n                                    </Button>\n                                  </>\n                                )}\n                              </Form.List>\n                            </div>\n\n                            <div className=\"fg-ai-subsection\">\n                              <span className=\"fg-options-label\">\n                                Where the details sit in the reply (optional)\n                              </span>\n                              <Form.Item name={[aName, 'responseDataPath']} style={{ marginBottom: 0 }}>\n                                <Input size=\"small\" placeholder=\"e.g. data\" className=\"fg-mono-input\" style={{ width: 200 }} />\n                              </Form.Item>\n                              <p className=\"fg-source-hint\">\n                                Most services reply with the details wrapped in something, often\n                                called &quot;data&quot;. Name that wrapper here. Leave blank if\n                                the reply IS the details. Whatever comes back is matched to this\n                                form&apos;s boxes by name, exactly the way an Edit form fills\n                                itself in.\n                              </p>\n                            </div>\n\n                            {/* Overwrite policy. This is what makes a résumé upload feel\n                                right in both directions: silent when the form is empty,\n                                asking first when it is not. */}\n                            <div className=\"fg-ai-subsection\">\n                              <span className=\"fg-options-label\">Before filling in the form</span>\n                              <Form.Item name={[aName, 'confirmWhen']} style={{ marginBottom: 0 }}\n                                initialValue=\"targetsFilled\">\n                                <Select size=\"small\" style={{ width: 320 }}\n                                  getPopupContainer={() => document.body}\n                                  options={[\n                                    { value: 'targetsFilled', label: 'Ask only if it would overwrite something (recommended)' },\n                                    { value: 'always', label: 'Always ask first' },\n                                    { value: 'never', label: 'Never ask — just fill it in' },\n                                  ]} />\n                              </Form.Item>\n                              <p className=\"fg-source-hint\">\n                                With the recommended setting, uploading a file to an empty form\n                                just fills it in — no interruption. If someone has already typed\n                                things in and then uploads a file, they are asked before their\n                                work is replaced.\n                              </p>\n                              <Form.Item shouldUpdate style={{ marginBottom: 0 }}>\n                                {({ getFieldValue }) => (\n                                  getFieldValue([...fAbs, 'aiActions', aName, 'confirmWhen']) === 'never'\n                                    ? null\n                                    : (\n                                      <div className=\"fg-field-meta-row\" style={{ marginTop: 8, flexWrap: 'wrap' }}>\n                                        <Form.Item name={[aName, 'confirmMessages', 'title']} label=\"Question heading\"\n                                          style={{ marginBottom: 0, flex: '1 1 220px' }}>\n                                          <Input size=\"small\" placeholder=\"Fill the form from this file?\" />\n                                        </Form.Item>\n                                        <Form.Item name={[aName, 'confirmMessages', 'body']} label=\"Explanation\"\n                                          style={{ marginBottom: 0, flex: '1 1 320px' }}>\n                                          <Input size=\"small\" placeholder=\"We read details from the uploaded file. Applying them will replace what you have already entered.\" />\n                                        </Form.Item>\n                                        <Form.Item name={[aName, 'confirmMessages', 'ok']} label=\"Yes button\"\n                                          style={{ marginBottom: 0, flex: '0 1 160px' }}>\n                                          <Input size=\"small\" placeholder=\"Parse & fill\" />\n                                        </Form.Item>\n                                        <Form.Item name={[aName, 'confirmMessages', 'cancel']} label=\"No button\"\n                                          style={{ marginBottom: 0, flex: '0 1 180px' }}>\n                                          <Input size=\"small\" placeholder=\"Keep what I typed\" />\n                                        </Form.Item>\n                                      </div>\n                                    )\n                                )}\n                              </Form.Item>\n                            </div>\n                          </div>\n                        ))}\n                        <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />}\n                          onClick={() => addAction({ trigger: 'click', bodyType: 'json', inputs: [] })}\n                          className=\"fg-add-val-btn\">\n                          Add AI Action\n                        </Button>\n                      </>\n                    )}\n                  </Form.List>\n                </div>\n\n              </div>\n              <Tooltip title=\"Remove field\">\n                <button type=\"button\" className=\"fg-field-remove-btn\" onClick={() => remove(rowName)}\n                  aria-label=\"Remove field\">\n                  <MinusCircleOutlined />\n                </button>\n              </Tooltip>\n                </>\n              )}\n            </div>\n          </div>\n        );\n      })}\n\n      <Button\n        type=\"dashed\"\n        icon={<PlusOutlined />}\n        onClick={() => {\n          add({ type: 'text', show: true, req: false, edit: true, dataSource: 'static', masterName: '', options: [] });\n          onToggleField?.(fieldItems.length, true);\n        }}\n        block\n        className=\"fg-add-field-btn\"\n      >\n        Add Field\n      </Button>\n    </>\n  );\n}\n\n// ── Group Drawer ──────────────────────────────────────────────────────────────\n// onSaveGroup(payload, editingGroup) — when provided, replaces the default API calls.\nfunction GroupDrawer({ open, editingGroup, defaultModule, moduleOptions, allGroupsByModule, onClose, onSaved, onSaveGroup }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const [formModule, setFormModule] = useState(defaultModule);\n  const [moduleFields, setModuleFields] = useState({});\n  const [fieldsLoading, setFieldsLoading] = useState(false);\n  // Default Fields (Form Groups → Default Fields) for the current module — their\n  // Show/Required toggles are locked ON here so no one can turn a default field\n  // off from the normal field editor.\n  const [defaultFieldSet, setDefaultFieldSet] = useState(() => new Set());\n  const [dragOverIndex, setDragOverIndex] = useState(null);\n  const [expandedFieldKeys, setExpandedFieldKeys] = useState(() => new Set());\n  const [editorTab, setEditorTab] = useState('settings');\n  const [fieldsVisited, setFieldsVisited] = useState(false);\n  const loadedRef = useRef({});\n  const dragIndexRef = useRef(null);\n  const collectionForModule = useModuleCollections();\n\n  useEffect(() => {\n    if (!open || !formModule) return;\n    let cancelled = false;\n    getModuleDefaultFields(formModule)\n      .then((keys) => { if (!cancelled) setDefaultFieldSet(new Set(Array.isArray(keys) ? keys : [])); })\n      .catch(() => { if (!cancelled) setDefaultFieldSet(new Set()); });\n    return () => { cancelled = true; };\n  }, [open, formModule]);\n\n  async function ensureModuleFields(mod) {\n    if (!mod || loadedRef.current[mod]) return;\n    loadedRef.current[mod] = 'loading';\n    setFieldsLoading(true);\n    try {\n      const fields = await getModuleFields(mod);\n      setModuleFields((prev) => ({ ...prev, [mod]: fields }));\n      loadedRef.current[mod] = 'loaded';\n    } catch {\n      delete loadedRef.current[mod]; // allow retry; free-text remains available\n    } finally {\n      setFieldsLoading(false);\n    }\n  }\n\n  useEffect(() => {\n    if (!open) return;\n    const mod = editingGroup?.module ?? defaultModule;\n    setFormModule(mod);\n    if (editingGroup) {\n      form.setFieldsValue({\n        module: editingGroup.module,\n        name:   editingGroup.name,\n        label:  editingGroup.label,\n        addRow: editingGroup.addRow ?? false,\n        hideGroup: editingGroup.hideGroup ?? false,\n        hideGroupInForm: editingGroup.hideGroupInForm ?? false,\n        moduleName: editingGroup.moduleName ?? '',\n        // Linkage between this Target Collection group and the main record. Mode\n        // is derived from which key is set: parentRefField → forward lookup\n        // (this record holds the target's id); otherwise child→parent (target\n        // holds this record's id via linkField / default parentId).\n        linkMode: editingGroup.parentRefField ? 'forward' : 'reverse',\n        linkField: editingGroup.linkField ?? '',\n        linkTypeField: editingGroup.linkTypeField ?? '',\n        parentRefField: editingGroup.parentRefField ?? '',\n        writeRefs: editingGroup.writeRefs ?? [],\n        dependsOn: editingGroup.dependsOn ?? [],\n        optionalWrite: editingGroup.optionalWrite ?? false,\n        // Collection hierarchy — chains this Target Collection under another\n        // collection of the same form instead of always attaching to the main\n        // record. Independent of linkMode above.\n        hierarchyLevel: editingGroup.hierarchyLevel ?? undefined,\n        hierarchyParent: editingGroup.hierarchyParent ?? undefined,\n        hierarchyLinkField: editingGroup.hierarchyLinkField ?? '',\n        allowCollapse: editingGroup.allowCollapse ?? false,\n        defaultCollapsed: editingGroup.defaultCollapsed ?? false,\n        appendHistory: editingGroup.appendHistory ?? false,\n        historyField: [editingGroup.historyField, ...(editingGroup.historyFields ?? [])]\n          .filter(Boolean).filter((v, i, a) => a.indexOf(v) === i).join(', '),\n        historyTimestampField: editingGroup.historyTimestampField ?? '',\n        // Stored as maps, edited as \"container=value\" pairs.\n        historyLabels: Object.entries(editingGroup.historyLabels ?? {})\n          .map(([k, v]) => `${k}=${v}`).join(', '),\n        historyLabelFrom: Object.entries(editingGroup.historyLabelFrom ?? {})\n          .map(([k, v]) => `${k}=${v}`).join(', '),\n        historyAfterGroup: editingGroup.historyAfterGroup ?? '',\n        // Which sub-key of a stored history entry is the amount / currency /\n        // unit. Same \"container=value\" pair encoding as the headings above.\n        historyAmountFields: Object.entries(editingGroup.historyAmountFields ?? {})\n          .map(([k, v]) => `${k}=${v}`).join(', '),\n        historyCurrencyFields: Object.entries(editingGroup.historyCurrencyFields ?? {})\n          .map(([k, v]) => `${k}=${v}`).join(', '),\n        historyUnitFields: Object.entries(editingGroup.historyUnitFields ?? {})\n          .map(([k, v]) => `${k}=${v}`).join(', '),\n        minRows: editingGroup.minRows ?? '',\n        maxRows: editingGroup.maxRows ?? '',\n        initialRows: editingGroup.initialRows ?? '',\n        requireOne: editingGroup.requireOne ?? false,\n        // Absent means allowed — blocking is the exception, so an untouched\n        // group must not present itself as restrictive.\n        allowInProgress: editingGroup.allowInProgress !== false,\n        inProgressMessage: editingGroup.inProgressMessage ?? '',\n        // These two are stored as whole rule objects; the editor exposes them\n        // as simple on/off switches and preserves the object underneath, so a\n        // rule tuned by a seeder is never flattened by opening this screen.\n        orderByEnabled: Boolean(editingGroup.orderBy),\n        levelRuleEnabled: Boolean(editingGroup.levelRule),\n        orderBy: editingGroup.orderBy ?? null,\n        levelRule: editingGroup.levelRule ?? null,\n        regionRules: editingGroup.regionRules ?? null,\n        requireValidatedField: editingGroup.requireValidatedField ?? '',\n        linkGroup: editingGroup.linkGroup ?? '',\n        mergeInto: editingGroup.mergeInto ?? '',\n        mergePosition: editingGroup.mergePosition ?? 'bottom',\n        showIfField: editingGroup.showIf?.field ?? '',\n        showIfOperator: editingGroup.showIf?.operator ?? 'notEmpty',\n        showIfValue: editingGroup.showIf?.value ?? '',\n        disabledIfField: editingGroup.disabledIf?.field ?? '',\n        disabledIfOperator: editingGroup.disabledIf?.operator ?? 'notEmpty',\n        disabledIfValue: editingGroup.disabledIf?.value ?? '',\n        submitDisabledMessage: editingGroup.submitDisabledMessage ?? '',\n        infoEnabled: editingGroup.infoEnabled ?? false,\n        infoText: editingGroup.infoText ?? '',\n        toggleEnabled: editingGroup.toggleEnabled ?? false,\n        toggleLabel: editingGroup.toggleLabel ?? '',\n        toggleField: editingGroup.toggleField ?? '',\n        afterSubmitMode: editingGroup.afterSubmit?.mode ?? undefined,\n        afterSubmitTarget: editingGroup.afterSubmit?.target ?? '',\n        formActions: (editingGroup.formActions ?? []).map((a) => ({\n          label: a.label ?? '',\n          tone: a.tone === 'primary' ? 'primary' : 'default',\n          afterSubmitMode: a.afterSubmit?.mode ?? 'stay',\n          afterSubmitTarget: a.afterSubmit?.target ?? '',\n          enabledWhenField: a.enabledWhen?.field ?? '',\n          enabledWhenOperator: a.enabledWhen?.operator ?? 'notEmpty',\n          enabledWhenValue: a.enabledWhen?.value ?? '',\n        })),\n        submitMsgAddSuccess: editingGroup.submitMessages?.addSuccess ?? '',\n        submitMsgEditSuccess: editingGroup.submitMessages?.editSuccess ?? '',\n        submitMsgAddError: editingGroup.submitMessages?.addError ?? '',\n        submitMsgEditError: editingGroup.submitMessages?.editError ?? '',\n        submitMsgSuppress: editingGroup.submitMessages?.suppress ?? false,\n        order:  editingGroup.order ?? 0,\n        // Load fields in their saved display order so the drag-and-drop editor\n        // and the rendered form always agree (both key off `order`).\n        fields: [...(editingGroup.fields ?? [])]\n          .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n          .map(initFieldValues),\n      });\n    } else {\n      form.resetFields();\n      form.setFieldsValue({ module: mod, addRow: false, hideGroup: false, hideGroupInForm: false, moduleName: '', linkMode: 'reverse', linkField: '', linkTypeField: '', parentRefField: '', hierarchyLevel: undefined, hierarchyParent: undefined, hierarchyLinkField: '', allowCollapse: false, defaultCollapsed: false, appendHistory: false, historyField: '', historyTimestampField: '', historyLabels: '', historyLabelFrom: '', historyAfterGroup: '', historyAmountFields: '', historyCurrencyFields: '', historyUnitFields: '', minRows: '', requireOne: false, allowInProgress: true, inProgressMessage: '', orderByEnabled: false, levelRuleEnabled: false, orderBy: null, levelRule: null, regionRules: null, mergeInto: '', mergePosition: 'bottom', showIfField: '', showIfOperator: 'notEmpty', showIfValue: '', disabledIfField: '', disabledIfOperator: 'notEmpty', disabledIfValue: '', submitDisabledMessage: '', formActions: [], infoEnabled: false, toggleEnabled: false, afterSubmitMode: undefined, afterSubmitTarget: '', order: 0, fields: [] });\n    }\n    ensureModuleFields(mod);\n  }, [open, editingGroup, defaultModule, form]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  function handleModuleChange(mod) { setFormModule(mod); ensureModuleFields(mod); }\n\n  function closeEditor() {\n    setExpandedFieldKeys(new Set());\n    setEditorTab('settings');\n    setFieldsVisited(false);\n    onClose();\n  }\n\n  function selectEditorTab(tab) {\n    setEditorTab(tab);\n    if (tab === 'fields') setFieldsVisited(true);\n  }\n\n  function toggleField(key, forceOpen = false) {\n    setExpandedFieldKeys((current) => {\n      const next = new Set(current);\n      if (forceOpen) next.add(key);\n      else if (next.has(key)) next.delete(key);\n      else next.add(key);\n      return next;\n    });\n  }\n\n  function usedFieldKeys(mod) {\n    const groups = allGroupsByModule[mod] ?? [];\n    const used = new Set();\n    groups.forEach((g) => {\n      if (editingGroup && g.id === editingGroup.id) return;\n      (g.fields ?? []).forEach((fld) => { if (fld.field) used.add(fld.field); });\n    });\n    return used;\n  }\n\n  function handleFieldKeySelect(fieldPath, rowName) {\n    const apiFields = moduleFields[formModule] ?? [];\n    const match = apiFields.find((f) => f.value === fieldPath);\n    if (!match) return;\n    const current = form.getFieldValue(['fields', rowName]) ?? {};\n    form.setFieldValue(['fields', rowName], { ...current, field: match.value, label: match.label, type: match.type ?? 'text' });\n  }\n\n  function fieldOptions(mod) {\n    const taken = usedFieldKeys(mod);\n    return (moduleFields[mod] ?? []).map((f) => ({\n      value: f.value,\n      disabled: taken.has(f.value),\n      label: (\n        <span style={{ opacity: taken.has(f.value) ? 0.4 : 1 }}>\n          {f.label}\n          <span className=\"fg-field-key-hint\">{f.value}</span>\n          {taken.has(f.value) && <span className=\"fg-field-taken-hint\">(in another group)</span>}\n        </span>\n      ),\n      searchLabel: `${f.label} ${f.value}`.toLowerCase(),\n    }));\n  }\n\n  async function handleSave() {\n    try {\n      const validated = await form.validateFields();\n      // Collapsed field editors are deliberately unmounted for speed. Read the\n      // preserved form store so their untouched settings remain in the payload.\n      const values = {\n        ...form.getFieldsValue(true),\n        ...validated,\n        fields: form.getFieldValue('fields') ?? [],\n      };\n      // Uniqueness config is refused rather than saved malformed — see\n      // collectUniqueRuleErrors for why the per-control rules are not enough.\n      const uniqueProblems = collectUniqueRuleErrors(values.fields);\n      if (uniqueProblems.length) {\n        message.error(`Uniqueness rule cannot be saved — ${uniqueProblems[0]}`);\n        return;\n      }\n      // Hierarchy validation — only when this group is a Target Collection AND\n      // at least one hierarchy field is set. A half-filled hierarchy (level with\n      // no parent, or vice versa) is ambiguous, so require the pair together.\n      if (values.moduleName) {\n        const groupLabel = values.name || values.label || 'this group';\n        const hParent = String(values.hierarchyParent ?? '').trim();\n        const hLinkField = String(values.hierarchyLinkField ?? '').trim();\n        // A Level on its own is valid — it just orders this write earlier and\n        // needs no parent — so only the parent/link pair triggers these checks.\n        const hierarchyTouched = Boolean(hParent || hLinkField);\n        if (hierarchyTouched) {\n          if (values.linkMode === 'forward') {\n            message.error(`Group \"${groupLabel}\": Hierarchy cannot be combined with a forward link (parentRefField) — choose one linkage mode.`);\n            return;\n          }\n          if (!hParent || !hLinkField) {\n            message.error(`Group \"${groupLabel}\": set both \"Parent collection\" and \"Store parent id in field\" to use Hierarchy.`);\n            return;\n          }\n          if (hParent === values.moduleName) {\n            message.error(`Group \"${groupLabel}\": Hierarchy parent cannot be this group's own Target Collection.`);\n            return;\n          }\n          // Cycle check: walk parent links across this module's OTHER groups,\n          // starting from the draft being saved. If the walk ever revisits a\n          // moduleName already seen, the chain loops back on itself.\n          const siblingGroups = (allGroupsByModule[values.module] ?? []).filter((g) => !editingGroup || g.id !== editingGroup.id);\n          const parentByModuleName = new Map();\n          siblingGroups.forEach((g) => { if (g.moduleName) parentByModuleName.set(g.moduleName, g.hierarchyParent ?? null); });\n          parentByModuleName.set(values.moduleName, hParent); // seed with the draft's own chosen parent\n          let cursor = hParent;\n          const seen = new Set([values.moduleName]);\n          let cycle = false;\n          while (cursor && cursor !== values.module) {\n            if (seen.has(cursor)) { cycle = true; break; }\n            seen.add(cursor);\n            cursor = parentByModuleName.get(cursor) ?? null;\n          }\n          if (cycle) {\n            message.error(`Group \"${groupLabel}\": this Hierarchy parent chain loops back on itself — pick a different Parent collection.`);\n            return;\n          }\n        }\n      }\n      setSaving(true);\n      const payload = {\n        module: values.module, name: values.name, label: values.label,\n        addRow: values.addRow ?? false, order: Number(values.order ?? 0),\n        fields: buildFieldPayload(values.fields ?? []),\n      };\n      if (values.hideGroup) payload.hideGroup = true;\n      if (values.hideGroupInForm) payload.hideGroupInForm = true;\n      if (values.moduleName) {\n        payload.moduleName = values.moduleName;\n        // Linkage between this Target Collection group and the main record —\n        // ids are stored as ObjectId either way. The two modes are mutually\n        // exclusive; persist only the keys for the chosen mode so the backend's\n        // mode inference (parentRefField set → forward) stays unambiguous.\n        if (values.linkMode === 'forward') {\n          const ref = String(values.parentRefField ?? '').trim();\n          if (ref) payload.parentRefField = ref;\n        } else {\n          const lf = String(values.linkField ?? '').trim();\n          const ltf = String(values.linkTypeField ?? '').trim();\n          if (lf) payload.linkField = lf;\n          if (ltf) payload.linkTypeField = ltf;\n        }\n        // Dependency config only means something for a Target Collection group.\n        const refs = (values.writeRefs ?? []).filter((r) => r?.fromModule && r?.targetField);\n        if (refs.length) payload.writeRefs = refs.map((r) => ({ fromModule: r.fromModule.trim(), targetField: r.targetField.trim() }));\n        const deps = (values.dependsOn ?? []).map((d) => String(d).trim()).filter(Boolean);\n        if (deps.length) payload.dependsOn = deps;\n        if (values.optionalWrite) payload.optionalWrite = true;\n        // Collection hierarchy — chains this Target Collection under another\n        // collection from the same form (main record or another group's\n        // Target Collection) instead of always attaching to the main record.\n        // The parent/link PAIR is emitted only when fully specified (validated\n        // above); never write a blank one. Level is independent of it — on its\n        // own it is a pure ordering hint (\"write this target first\"), which is\n        // useful without any parent link, so it must not be gated on the pair.\n        const hParentOut = String(values.hierarchyParent ?? '').trim();\n        const hLinkFieldOut = String(values.hierarchyLinkField ?? '').trim();\n        if (hParentOut && hLinkFieldOut) {\n          payload.hierarchyParent = hParentOut;\n          payload.hierarchyLinkField = hLinkFieldOut;\n        }\n        const hLevelOut = Number(values.hierarchyLevel);\n        if (Number.isFinite(hLevelOut) && hLevelOut > 0) payload.hierarchyLevel = hLevelOut;\n      }\n      // Append-history is independent of Target Collection — a plain group on\n      // the module's OWN record whose value gets appended (with a timestamp)\n      // instead of overwritten. historyField is required for it to do anything.\n      // Comma-separated input → one history container per prefix (a group whose\n      // fields span several prefixes keeps an independent timestamped array for\n      // each, e.g. \"candidateBudget, proposedRate, referralRate\").\n      const historyContainers = String(values.historyField ?? '')\n        .split(',').map((v) => v.trim()).filter(Boolean)\n        .filter((v, i, a) => a.indexOf(v) === i);\n      // Collapse is opt-in; `defaultCollapsed` only ships alongside it, so a\n      // group that no longer allows collapsing cannot keep a stale \"start\n      // closed\" flag that nothing would ever be able to open.\n      if (values.allowCollapse) {\n        payload.allowCollapse = true;\n        if (values.defaultCollapsed) payload.defaultCollapsed = true;\n      }\n      if (values.appendHistory && historyContainers.length) {\n        payload.appendHistory = true;\n        payload.historyField = historyContainers[0];\n        if (historyContainers.length > 1) payload.historyFields = historyContainers.slice(1);\n        if (String(values.historyTimestampField ?? '').trim()) {\n          payload.historyTimestampField = values.historyTimestampField.trim();\n        }\n        // \"container=value, container=value\" → { container: value }. Pairs\n        // naming a container this group does not declare are dropped: they\n        // could never take effect, and keeping them makes the config claim a\n        // heading it does not actually set.\n        const pairMap = (raw) => {\n          const out = {};\n          String(raw ?? '').split(',').forEach((entry) => {\n            const at = entry.indexOf('=');\n            if (at < 1) return;\n            const container = entry.slice(0, at).trim();\n            const value = entry.slice(at + 1).trim();\n            if (container && value && historyContainers.includes(container)) out[container] = value;\n          });\n          return out;\n        };\n        const historyLabels = pairMap(values.historyLabels);\n        if (Object.keys(historyLabels).length) payload.historyLabels = historyLabels;\n        const historyLabelFrom = pairMap(values.historyLabelFrom);\n        if (Object.keys(historyLabelFrom).length) payload.historyLabelFrom = historyLabelFrom;\n        // Which sub-key of a stored entry the detail card reads as the amount,\n        // the currency and the unit. OPTIONAL: blank lets the detail view infer\n        // all three from the \"<container>.\" fields this group already\n        // configures, which is right whenever the sub-field the admin wants\n        // shown is one they configured. Set it when the stored entry carries\n        // several amount-like sub-keys (a Start AND an End) and the one written\n        // first is not the one to show.\n        const historyAmountFields = pairMap(values.historyAmountFields);\n        if (Object.keys(historyAmountFields).length) payload.historyAmountFields = historyAmountFields;\n        const historyCurrencyFields = pairMap(values.historyCurrencyFields);\n        if (Object.keys(historyCurrencyFields).length) {\n          payload.historyCurrencyFields = historyCurrencyFields;\n        }\n        const historyUnitFields = pairMap(values.historyUnitFields);\n        if (Object.keys(historyUnitFields).length) payload.historyUnitFields = historyUnitFields;\n        if (String(values.historyAfterGroup ?? '').trim()) {\n          payload.historyAfterGroup = values.historyAfterGroup.trim();\n        }\n      }\n      if (values.addRow && values.minRows !== undefined && values.minRows !== '') {\n        payload.minRows = Number(values.minRows);\n      }\n      if (values.addRow && values.initialRows !== undefined && values.initialRows !== '') {\n        payload.initialRows = Number(values.initialRows);\n      }\n      if (values.addRow && values.maxRows !== undefined && values.maxRows !== '') {\n        payload.maxRows = Number(values.maxRows);\n      }\n      if (values.addRow && String(values.requireValidatedField ?? '').trim()) {\n        payload.requireValidatedField = values.requireValidatedField.trim();\n      }\n      if (values.addRow && values.requireOne) payload.requireOne = true;\n\n      // ── Row rules ────────────────────────────────────────────────────────\n      // \"Allowed\" is the default, so only the restrictive setting is stored.\n      if (values.allowInProgress === false) {\n        payload.allowInProgress = false;\n        const msg = String(values.inProgressMessage ?? '').trim();\n        if (msg) payload.inProgressMessage = msg;\n      }\n      // The switches turn a rule ON or OFF; they must NOT rewrite it. A rule\n      // seeded with tuned settings (which date field to sort on, the wording of\n      // each prompt, the required levels) would otherwise be flattened to a\n      // default the moment someone opened this screen and pressed Save.\n      if (values.orderByEnabled) {\n        payload.orderBy = values.orderBy ?? DEFAULT_ORDER_BY;\n      }\n      if (values.levelRuleEnabled) {\n        payload.levelRule = values.levelRule ?? DEFAULT_LEVEL_RULE;\n      }\n      // Region profiles are authored by a seeder (they are a per-market matrix,\n      // not a single switch). Carried through untouched so saving from this\n      // screen never drops them.\n      if (values.regionRules) payload.regionRules = values.regionRules;\n      if (values.addRow && values.linkGroup) payload.linkGroup = values.linkGroup.trim();\n      // Render-only merge: this group's fields show inside another group's card\n      // (AddFormV1/EditFormV1 renderGroupBody) — payload/history untouched.\n      if (String(values.mergeInto ?? '').trim()) {\n        payload.mergeInto = values.mergeInto.trim();\n        // Position is meaningless without a host, so it is only persisted with\n        // one — and 'bottom' is the renderer's default, so it is left unset.\n        if (values.mergePosition === 'top') payload.mergePosition = 'top';\n      }\n      // Group-level showIf — gate the whole group on another field's value.\n      if (String(values.showIfField ?? '').trim()) {\n        const operator = values.showIfOperator || 'notEmpty';\n        payload.showIf = { field: values.showIfField.trim(), operator };\n        if (['eq', 'neq', 'in', 'notIn'].includes(operator) && String(values.showIfValue ?? '').trim()) {\n          payload.showIf.value = values.showIfValue.trim();\n        }\n      }\n      // Disabled-submit tooltip message (\"why is Create/Update disabled\").\n      if (String(values.submitDisabledMessage ?? '').trim()) {\n        payload.submitDisabledMessage = values.submitDisabledMessage.trim();\n      }\n      // Group-level disabledIf — make the whole card read-only when another\n      // field's value satisfies the condition (same shape as showIf).\n      if (String(values.disabledIfField ?? '').trim()) {\n        const operator = values.disabledIfOperator || 'notEmpty';\n        payload.disabledIf = { field: values.disabledIfField.trim(), operator };\n        if (['eq', 'neq', 'in', 'notIn'].includes(operator) && String(values.disabledIfValue ?? '').trim()) {\n          payload.disabledIf.value = values.disabledIfValue.trim();\n        }\n      }\n      if (values.infoEnabled && values.infoText) {\n        payload.infoEnabled = true;\n        payload.infoText = values.infoText;\n      }\n      if (values.toggleEnabled && values.toggleField) {\n        payload.toggleEnabled = true;\n        payload.toggleLabel = values.toggleLabel || 'Toggle';\n        payload.toggleField = values.toggleField;\n      }\n      if (values.afterSubmitMode) {\n        payload.afterSubmit = { mode: values.afterSubmitMode };\n        if (values.afterSubmitMode === 'route' || values.afterSubmitMode === 'detail') {\n          payload.afterSubmit.target = (values.afterSubmitTarget || '').trim();\n        }\n      }\n      // Additional submit buttons (e.g. \"Create and Source Candidate\"): each has\n      // its own label, tone, after-submit landing and optional enable-when gate.\n      const actions = (values.formActions ?? []).filter((a) => String(a?.label ?? '').trim());\n      if (actions.length) {\n        payload.formActions = actions.map((a) => {\n          const out = { label: a.label.trim(), tone: a.tone === 'primary' ? 'primary' : 'default' };\n          const mode = a.afterSubmitMode || 'stay';\n          out.afterSubmit = { mode };\n          if (mode === 'route' || mode === 'detail') out.afterSubmit.target = String(a.afterSubmitTarget ?? '').trim();\n          if (String(a.enabledWhenField ?? '').trim()) {\n            const operator = a.enabledWhenOperator || 'notEmpty';\n            out.enabledWhen = { field: a.enabledWhenField.trim(), operator };\n            if (['eq', 'neq', 'in', 'notIn'].includes(operator) && String(a.enabledWhenValue ?? '').trim()) {\n              out.enabledWhen.value = a.enabledWhenValue.trim();\n            }\n          }\n          return out;\n        });\n      }\n      // Submit toast overrides. Only persisted when something differs from the\n      // built-in defaults, so untouched groups stay clean (nil in Mongo) and the\n      // frontend keeps using its defaults everywhere else.\n      const submitMessages = {};\n      if ((values.submitMsgAddSuccess || '').trim()) submitMessages.addSuccess = values.submitMsgAddSuccess.trim();\n      if ((values.submitMsgEditSuccess || '').trim()) submitMessages.editSuccess = values.submitMsgEditSuccess.trim();\n      if ((values.submitMsgAddError || '').trim()) submitMessages.addError = values.submitMsgAddError.trim();\n      if ((values.submitMsgEditError || '').trim()) submitMessages.editError = values.submitMsgEditError.trim();\n      if (values.submitMsgSuppress) submitMessages.suppress = true;\n      if (Object.keys(submitMessages).length) payload.submitMessages = submitMessages;\n      // Preserve group config keys this editor doesn't manage (payloadKey,\n      // sharedRowLabels, linkField/linkTypeField, showIf, …) — before this,\n      // editing ANY group here silently dropped them (e.g. workExperience's\n      // payloadKey), breaking the rendered form. Managed keys are excluded so\n      // clearing them in the UI still clears them.\n      if (editingGroup) {\n        for (const [k, v] of Object.entries(editingGroup)) {\n          if (v === undefined || v === null || v === '') continue;\n          if (k in payload || GROUP_EDITOR_MANAGED_KEYS.has(k)) continue;\n          payload[k] = v;\n        }\n      }\n      if (onSaveGroup) {\n        await onSaveGroup(payload, editingGroup);\n        message.success(editingGroup ? 'Group updated' : 'Group created');\n      } else if (editingGroup) {\n        await updateAdminFormGroup(editingGroup.id, payload);\n        message.success('Group updated');\n      } else {\n        await createAdminFormGroup(payload);\n        message.success('Group created');\n      }\n      setExpandedFieldKeys(new Set());\n      setEditorTab('settings');\n      setFieldsVisited(false);\n      onSaved();\n    } catch (err) {\n      if (err?.errorFields) return;\n      message.error(err.message || 'Could not save group');\n    } finally { setSaving(false); }\n  }\n\n  const options = useMemo(\n    () => fieldOptions(formModule || defaultModule),\n    // Group/field inputs are intentionally the cache boundary for option building.\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [allGroupsByModule, defaultModule, editingGroup, formModule, moduleFields],\n  );\n\n  return (\n    <Modal\n      open={open}\n      onCancel={closeEditor}\n      width={1080}\n      centered\n      destroyOnClose\n      maskClosable={false}\n      className=\"fg-editor-modal fg-group-editor-modal\"\n      title={\n        <span className=\"fg-drawer-title\">\n          {editingGroup ? <EditOutlined /> : <PlusOutlined />}\n          {editingGroup ? ' Edit Form Group' : ' New Form Group'}\n        </span>\n      }\n      footer={\n        <div className=\"fg-drawer-footer\">\n          <Button onClick={closeEditor}>Cancel</Button>\n          <Button type=\"primary\" loading={saving} onClick={handleSave}\n            icon={editingGroup ? <EditOutlined /> : <PlusOutlined />}>\n            {editingGroup ? 'Update Group' : 'Create Group'}\n          </Button>\n        </div>\n      }\n    >\n      <Form form={form} layout=\"vertical\" className=\"fg-form fg-editor-form fg-group-editor-form\">\n        <div className=\"fg-group-editor-tabs\" role=\"tablist\" aria-label=\"Form group editor sections\">\n          <button\n            type=\"button\"\n            role=\"tab\"\n            aria-selected={editorTab === 'settings'}\n            className={editorTab === 'settings' ? 'is-active' : ''}\n            onClick={() => selectEditorTab('settings')}\n          >\n            <span className=\"fg-editor-tab-number\">1</span>\n            <span><strong>Group settings</strong><small>Name, behaviour and display options</small></span>\n          </button>\n          <button\n            type=\"button\"\n            role=\"tab\"\n            aria-selected={editorTab === 'fields'}\n            className={editorTab === 'fields' ? 'is-active' : ''}\n            onClick={() => selectEditorTab('fields')}\n          >\n            <span className=\"fg-editor-tab-number\">2</span>\n            <span><strong>Fields</strong><small>{editingGroup?.fields?.length ?? 0} configured fields</small></span>\n          </button>\n        </div>\n\n        <div className={`fg-group-editor-panel${editorTab === 'settings' ? ' is-active' : ''}`}>\n        <div className=\"fg-form-section fg-group-settings-card\">\n          <div className=\"fg-form-section-label\">Group Info</div>\n          <Form.Item name=\"module\" label=\"Module\" rules={[{ required: true, message: 'Select a module' }]}>\n            <Select options={moduleOptions} placeholder=\"Select module\" onChange={handleModuleChange} />\n          </Form.Item>\n          <Form.Item name=\"label\" label=\"Group Label\" rules={[{ required: true, message: 'Label is required' }]}>\n            <Input placeholder=\"e.g. Work Experience\" />\n          </Form.Item>\n          <Form.Item name=\"name\" label=\"Group Name (key)\"\n            rules={[\n              { required: true, message: 'Name is required' },\n              { pattern: /^[a-z0-9_]+$/, message: 'Lowercase letters, numbers, underscores only' },\n            ]}>\n            <Input placeholder=\"e.g. work_experience\" className=\"fg-mono-input\" />\n          </Form.Item>\n          <Form.Item name=\"moduleName\" label=\"Target Collection (optional)\"\n            tooltip=\"Route THIS group's fields to a different collection instead of the default module record. Groups sharing the same target merge into one linked record. Leave blank for default behaviour.\">\n            <AutoComplete\n              options={moduleOptions.map((m) => ({ value: m.value, label: m.label }))}\n              placeholder=\"Default (this module's own record)\"\n              allowClear\n              filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n              className=\"fg-mono-input\"\n            />\n          </Form.Item>\n          {/* Linkage between a Target Collection group and the main record.\n              Shown only when a Target Collection is chosen. Ids are stored as\n              ObjectId in either direction; the two modes are mutually exclusive. */}\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => getFieldValue('moduleName') ? (\n              <div className=\"fg-options-block\" style={{ marginBottom: 12 }}>\n                <span className=\"fg-options-label\">\n                  Linkage\n                  <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                    how this collection links to the main record (ids stored as ObjectId)\n                  </span>\n                </span>\n                <Form.Item name=\"linkMode\" style={{ marginBottom: 8 }}>\n                  <Radio.Group optionType=\"button\" buttonStyle=\"solid\" size=\"small\">\n                    <Radio.Button value=\"reverse\">Target stores this record’s id (child→parent)</Radio.Button>\n                    <Radio.Button value=\"forward\">This record stores the target’s id (lookup)</Radio.Button>\n                  </Radio.Group>\n                </Form.Item>\n                <Form.Item shouldUpdate style={{ marginBottom: 0 }}>\n                  {({ getFieldValue: gv }) => gv('linkMode') === 'forward' ? (\n                    <Form.Item name=\"parentRefField\" label=\"Reference field on THIS record\"\n                      tooltip=\"A field on the main record that holds the target document's _id (as ObjectId), e.g. employerRef. On edit it selects which target document to load and update.\"\n                      style={{ marginBottom: 0 }}>\n                      <Input placeholder=\"e.g. employerRef\" className=\"fg-mono-input\" style={{ width: 260 }} />\n                    </Form.Item>\n                  ) : (\n                    <div className=\"fg-inline-row\" style={{ alignItems: 'flex-end' }}>\n                      <Form.Item name=\"linkField\" label=\"Link field on target (optional)\"\n                        tooltip=\"Field on the TARGET document that stores this record's _id (as ObjectId), e.g. jobRef. Leave blank to use the default parentId / parentModule linkage.\"\n                        style={{ marginBottom: 0 }}>\n                        <Input placeholder=\"e.g. jobRef\" className=\"fg-mono-input\" style={{ width: 220 }} />\n                      </Form.Item>\n                      <Form.Item name=\"linkTypeField\" label=\"Parent-type field (optional)\"\n                        tooltip=\"Field on the target document recording WHICH module the parent is (e.g. parentType), so one collection can serve several parent modules.\"\n                        style={{ marginBottom: 0 }}>\n                        <Input placeholder=\"e.g. parentType\" className=\"fg-mono-input\" style={{ width: 220 }} />\n                      </Form.Item>\n                    </div>\n                  )}\n                </Form.Item>\n              </div>\n            ) : null}\n          </Form.Item>\n          {/* Collection hierarchy — chains this Target Collection under another\n              collection from the SAME form (the main record, or another\n              group's Target Collection) instead of always attaching straight\n              to the main record, e.g.\n              users -> trainers.userId -> trainer_availability.trainerId.\n              Independent of the Linkage block above; mutually exclusive with\n              the forward-lookup mode (validated on save, not here). */}\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => getFieldValue('moduleName') ? (\n              <div className=\"fg-options-block\" style={{ marginBottom: 12 }}>\n                <span className=\"fg-options-label\">\n                  Hierarchy\n                  <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                    chain this collection under another collection of the same form\n                  </span>\n                </span>\n                <div className=\"fg-inline-row\" style={{ alignItems: 'flex-end' }}>\n                  <Form.Item name=\"hierarchyLevel\" label=\"Level\"\n                    tooltip=\"Explicit ordering when several collections chain together — level 1 is written first.\"\n                    style={{ marginBottom: 0 }}>\n                    <InputNumber min={1} max={99} style={{ width: 120 }} />\n                  </Form.Item>\n                  <Form.Item name=\"hierarchyParent\" label=\"Parent collection\"\n                    tooltip=\"What this collection is chained under: the main record, or another group's Target Collection.\"\n                    style={{ marginBottom: 0, minWidth: 260 }}>\n                    <Select\n                      allowClear\n                      showSearch\n                      placeholder=\"No hierarchy (default)\"\n                      optionFilterProp=\"label\"\n                      options={(() => {\n                        const mainModule = getFieldValue('module') || formModule || defaultModule;\n                        const ownTarget = getFieldValue('moduleName');\n                        const siblingGroups = allGroupsByModule[mainModule] ?? [];\n                        const seen = new Set();\n                        const opts = [];\n                        if (mainModule) {\n                          opts.push({ value: mainModule, label: `Main record (${mainModule})` });\n                          seen.add(mainModule);\n                        }\n                        siblingGroups.forEach((g) => {\n                          const tgt = g.moduleName;\n                          if (!tgt || tgt === ownTarget || seen.has(tgt)) return;\n                          seen.add(tgt);\n                          opts.push({ value: tgt, label: tgt });\n                        });\n                        return opts;\n                      })()}\n                    />\n                  </Form.Item>\n                  <Form.Item name=\"hierarchyLinkField\" label=\"Store parent id in field\"\n                    tooltip=\"Field on THIS collection holding the parent's _id (stored as ObjectId).\"\n                    style={{ marginBottom: 0 }}>\n                    <Input placeholder=\"e.g. trainerId\" className=\"fg-mono-input\" style={{ width: 200 }} />\n                  </Form.Item>\n                </div>\n                <Form.Item shouldUpdate noStyle>\n                  {({ getFieldValue: gv }) => {\n                    const mainModule = gv('module') || formModule || defaultModule;\n                    const ownTarget = gv('moduleName');\n                    const siblingGroups = allGroupsByModule[mainModule] ?? [];\n                    const chain = buildHierarchyChainPreview(\n                      mainModule, ownTarget, gv('hierarchyParent'), gv('hierarchyLinkField'), siblingGroups,\n                    );\n                    return chain ? (\n                      <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 6 }}>\n                        {chain}\n                      </Text>\n                    ) : null;\n                  }}\n                </Form.Item>\n              </div>\n            ) : null}\n          </Form.Item>\n          {/* Dependency config for a Target Collection group: which other writes\n              of the same submit this one depends on, and where their created\n              document ids are injected. Backend validates the graph (missing /\n              circular refs reject the submit before anything is written) and\n              rolls back ALL writes when a required one fails. */}\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => getFieldValue('moduleName') ? (\n              <div className=\"fg-options-block\" style={{ marginBottom: 12 }}>\n                <span className=\"fg-options-label\">\n                  Linked-write dependencies\n                  <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                    inject ids created by other writes of this same form submit\n                  </span>\n                </span>\n                <Form.List name=\"writeRefs\">\n                  {(refItems, { add: addRef, remove: removeRef }) => (\n                    <div>\n                      {refItems.map(({ key: rKey, name: rName, ...rRest }) => (\n                        <div key={rKey} className=\"fg-inline-row\" style={{ alignItems: 'flex-end', marginBottom: 6 }}>\n                          <Form.Item {...rRest} name={[rName, 'fromModule']} label=\"Id from (module)\"\n                            rules={[{ required: true, message: 'Module' }]} style={{ marginBottom: 0 }}>\n                            <AutoComplete\n                              options={moduleOptions.map((m) => ({ value: m.value }))}\n                              placeholder=\"e.g. users (or this module)\"\n                              style={{ width: 220 }} className=\"fg-mono-input\"\n                              filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n                            />\n                          </Form.Item>\n                          <Form.Item {...rRest} name={[rName, 'targetField']} label=\"Store into field\"\n                            rules={[{ required: true, message: 'Field' }]} style={{ marginBottom: 0 }}>\n                            <Input placeholder=\"e.g. userId or links.userId\" style={{ width: 220 }} className=\"fg-mono-input\" />\n                          </Form.Item>\n                          <Tooltip title=\"Remove dependency\">\n                            <button type=\"button\" className=\"fg-field-remove-btn\" onClick={() => removeRef(rName)} aria-label=\"Remove dependency\">\n                              <MinusCircleOutlined />\n                            </button>\n                          </Tooltip>\n                        </div>\n                      ))}\n                      <Button type=\"dashed\" size=\"small\" icon={<PlusOutlined />} onClick={() => addRef({ fromModule: '', targetField: '' })}>\n                        Add Dependency\n                      </Button>\n                    </div>\n                  )}\n                </Form.List>\n                <div className=\"fg-inline-row\" style={{ marginTop: 10 }}>\n                  <Form.Item name=\"dependsOn\" label=\"Runs after (ordering only)\"\n                    tooltip=\"Other Target Collections this write must wait for, without injecting an id.\"\n                    style={{ marginBottom: 0, flex: 1 }}>\n                    <Select mode=\"tags\" placeholder=\"e.g. users\" options={moduleOptions.map((m) => ({ value: m.value, label: m.value }))} />\n                  </Form.Item>\n                  <Form.Item name=\"optionalWrite\" label=\"Optional write\" valuePropName=\"checked\"\n                    tooltip=\"On: a failure of this write is logged but the submit still succeeds (best-effort). Off (default): a failure rolls back EVERY write of this submit.\"\n                    style={{ marginBottom: 0 }}>\n                    <Switch checkedChildren=\"Best-effort\" unCheckedChildren=\"Required\" />\n                  </Form.Item>\n                </div>\n              </div>\n            ) : null}\n          </Form.Item>\n\n          {/* Collapsible section. Opt-in: without it the card has no chevron and\n              cannot be collapsed, which is how every form behaved before this\n              was configurable. \"Start closed\" is offered only once collapsing\n              is on — a section that opens closed but cannot be opened is one\n              nobody can fill in. */}\n          <Form.Item shouldUpdate style={{ marginBottom: 12 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => {\n              const collapseOn = getFieldValue('allowCollapse');\n              return (\n                <div className=\"fg-options-block\">\n                  <span className=\"fg-options-label\">\n                    Collapsible section\n                    <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                      let users fold this section away — useful on long forms\n                    </span>\n                  </span>\n                  <div className=\"fg-options-controls\">\n                    <Form.Item name=\"allowCollapse\" valuePropName=\"checked\" style={{ marginBottom: 0 }}\n                      tooltip=\"On: the section header shows a chevron that opens and closes it, on both the Add and Edit forms. Off (default): no chevron, the section is always open.\">\n                      <Switch checkedChildren=\"Collapsible\" unCheckedChildren=\"Always open\" />\n                    </Form.Item>\n                    {collapseOn && (\n                      <Form.Item name=\"defaultCollapsed\" label=\"Start closed\" valuePropName=\"checked\"\n                        style={{ marginBottom: 0 }}\n                        tooltip=\"On: the section is already folded away when the form opens, and the user opens it if they need it. Use it for the parts most records leave alone, so the form opens on the fields that are filled in every time.\">\n                        <Switch size=\"small\" checkedChildren=\"Closed\" unCheckedChildren=\"Open\" />\n                      </Form.Item>\n                    )}\n                  </div>\n                </div>\n              );\n            }}\n          </Form.Item>\n\n          {/* Append-history: independent of Target Collection — this group's\n              own resolved value (on the module's own record) gets APPENDED\n              with a timestamp instead of overwritten. Detail view / edit\n              prefill still show only the LATEST entry, unaffected. */}\n          <Form.Item shouldUpdate style={{ marginBottom: 12 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => {\n              const appendHistoryOn = getFieldValue('appendHistory');\n              return (\n                <div className=\"fg-options-block\">\n                  <span className=\"fg-options-label\">\n                    Append as history\n                    <span className=\"fg-field-key-hint\" style={{ marginLeft: 6 }}>\n                      keep every past save instead of overwriting (e.g. rate negotiation history)\n                    </span>\n                  </span>\n                  <div className=\"fg-options-controls\">\n                    <Form.Item name=\"appendHistory\" valuePropName=\"checked\" style={{ marginBottom: 0 }}>\n                      <Switch checkedChildren=\"Append\" unCheckedChildren=\"Off\" />\n                    </Form.Item>\n                    {appendHistoryOn && (\n                      <>\n                        <Form.Item name=\"historyField\" label=\"Array field\"\n                          rules={[{ required: true, message: 'Required' }]}\n                          tooltip=\"The record key(s) holding the append-only array(s) — usually the prefix(es) this group's own fields already write through. Comma-separate to keep an independent history per prefix, e.g. candidateBudget, proposedRate, referralRate.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"e.g. proposedRate, candidateBudget\" style={{ width: 240 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyTimestampField\" label=\"Timestamp key\"\n                          tooltip=\"Key stamped onto each saved entry. Blank defaults to 'timestamp'.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"timestamp\" style={{ width: 140 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyLabels\" label=\"Detail headings\"\n                          tooltip=\"Heading shown for each history block in the detail view, as container=Label pairs, comma-separated. Blank derives it from the first field under that container — which also picks up that field's Conditional Label, so the heading can change per record.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"candidateBudget=Candidate Rate, proposedRate=Proposed Rate\" style={{ width: 320 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyLabelFrom\" label=\"Heading from field\"\n                          tooltip=\"Take each block's heading from a specific field's label, as container=fieldKey pairs. Use this when the heading must follow a Conditional Label on a field other than the first one.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"candidateBudget=candidateBudget.candidateBudgetStart\" style={{ width: 320 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        {/* Which sub-key of a stored entry is the money. The\n                            detail card already infers all three from the\n                            \"<container>.\" fields configured below — these three\n                            are the escape hatch for an entry that carries more\n                            than one amount-like sub-key (a Start AND an End),\n                            where the one stored first is not the one to show.\n                            Blank = infer. */}\n                        <Form.Item name=\"historyAmountFields\" label=\"Amount key\"\n                          tooltip=\"Which sub-key of a stored entry holds the amount, as container=subKey pairs, comma-separated. Blank uses the first field this group configures under that container that is not a currency/symbol/unit/type key — correct for almost every group.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"candidateBudget=candidateBudgetStart\" style={{ width: 320 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyCurrencyFields\" label=\"Currency key\"\n                          tooltip=\"Which sub-key holds the currency (code or symbol), as container=subKey pairs. Blank prefers a configured symbol field that actually carries a symbol, otherwise the configured currency field.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"candidateBudget=candidateBudgetCurrency\" style={{ width: 320 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyUnitFields\" label=\"Unit key\"\n                          tooltip=\"Which sub-key holds the rate unit (Hourly / Daily / …), as container=subKey pairs. Blank uses the configured unit field under that container.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"candidateBudget=candidateBudgetUnit\" style={{ width: 320 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                        <Form.Item name=\"historyAfterGroup\" label=\"Show after group\"\n                          tooltip=\"Group key the history card is rendered after in the detail view. Blank places it after the employer group, or last when there is none.\"\n                          style={{ marginBottom: 0 }}>\n                          <Input size=\"small\" placeholder=\"employer_details\" style={{ width: 200 }} className=\"fg-mono-input\" />\n                        </Form.Item>\n                      </>\n                    )}\n                  </div>\n                  {appendHistoryOn && (\n                    <p className=\"fg-source-hint\" style={{ marginTop: 6 }}>\n                      Every save adds a new entry to the end of the array — the detail view and edit form\n                      always show the latest one, exactly like a normal field.\n                    </p>\n                  )}\n                </div>\n              );\n            }}\n          </Form.Item>\n\n          <div className=\"fg-inline-row\">\n            <Form.Item name=\"order\" label=\"Display Order\">\n              <Input type=\"number\" min={0} style={{ width: 100 }} />\n            </Form.Item>\n            <Form.Item name=\"addRow\" label=\"Allow Add Row\" valuePropName=\"checked\">\n              <Switch checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n            </Form.Item>\n            <Form.Item name=\"hideGroup\" label=\"Hide Group\" valuePropName=\"checked\"\n              tooltip=\"Hide this group entirely from Add/Edit forms — not rendered, not validated, not submitted.\">\n              <Switch checkedChildren=\"Hidden\" unCheckedChildren=\"Visible\" />\n            </Form.Item>\n            <Form.Item name=\"hideGroupInForm\" label=\"Hide in Form only\" valuePropName=\"checked\"\n              tooltip=\"Hide this group from the Add/Edit forms but KEEP it on the detail view. For groups whose values are filled by the system and should be read, never typed — e.g. a submission's Job Information. (Hide Group above hides it in both places.)\">\n              <Switch checkedChildren=\"Form hidden\" unCheckedChildren=\"Shown\" />\n            </Form.Item>\n            <Form.Item label=\"Show group when\"\n              tooltip=\"Gate the whole group on another field's live value — the group only appears once the condition matches (e.g. the Employer group opens after Contract Type is chosen). Leave the field blank to always show.\">\n              <Space.Compact block>\n                <Form.Item name=\"showIfField\" noStyle>\n                  <Input placeholder=\"Field key e.g. contractType\" style={{ width: '45%' }} />\n                </Form.Item>\n                <Form.Item name=\"showIfOperator\" noStyle>\n                  <Select style={{ width: '30%' }} options={[\n                    { value: 'notEmpty', label: 'is set' },\n                    { value: 'isEmpty', label: 'is empty' },\n                    { value: 'eq', label: 'equals' },\n                    { value: 'neq', label: 'not equals' },\n                    { value: 'in', label: 'in list' },\n                    { value: 'notIn', label: 'not in list' },\n                  ]} />\n                </Form.Item>\n                <Form.Item noStyle shouldUpdate={(prev, cur) => prev.showIfOperator !== cur.showIfOperator}>\n                  {({ getFieldValue }) => (['eq', 'neq', 'in', 'notIn'].includes(getFieldValue('showIfOperator'))\n                    ? <Form.Item name=\"showIfValue\" noStyle><Input placeholder=\"Value(s), comma for list\" style={{ width: '25%' }} /></Form.Item>\n                    : null)}\n                </Form.Item>\n              </Space.Compact>\n            </Form.Item>\n            <Form.Item name=\"disabled\" label=\"Disable Group\" valuePropName=\"checked\"\n              tooltip=\"Make the whole group card read-only — it still renders and submits, but no field can be edited.\">\n              <Switch checkedChildren=\"Read-only\" unCheckedChildren=\"Editable\" />\n            </Form.Item>\n            <Form.Item label=\"Disable group when\"\n              tooltip=\"Make the whole group read-only while another field's live value satisfies this condition (same shape as 'Show group when'). Leave the field blank for no conditional disable.\">\n              <Space.Compact block>\n                <Form.Item name=\"disabledIfField\" noStyle>\n                  <Input placeholder=\"Field key e.g. contractType\" style={{ width: '45%' }} />\n                </Form.Item>\n                <Form.Item name=\"disabledIfOperator\" noStyle>\n                  <Select style={{ width: '30%' }} options={[\n                    { value: 'notEmpty', label: 'is set' },\n                    { value: 'isEmpty', label: 'is empty' },\n                    { value: 'eq', label: 'equals' },\n                    { value: 'neq', label: 'not equals' },\n                    { value: 'in', label: 'in list' },\n                    { value: 'notIn', label: 'not in list' },\n                  ]} />\n                </Form.Item>\n                <Form.Item noStyle shouldUpdate={(prev, cur) => prev.disabledIfOperator !== cur.disabledIfOperator}>\n                  {({ getFieldValue }) => (['eq', 'neq', 'in', 'notIn'].includes(getFieldValue('disabledIfOperator'))\n                    ? <Form.Item name=\"disabledIfValue\" noStyle><Input placeholder=\"Value(s), comma for list\" style={{ width: '25%' }} /></Form.Item>\n                    : null)}\n                </Form.Item>\n              </Space.Compact>\n            </Form.Item>\n            <Form.Item name=\"submitDisabledMessage\" label=\"Disabled submit tooltip\"\n              tooltip=\"Shown on hover over the form's Create/Update button WHILE it is disabled, so the user knows why they can't submit. Leave blank for the built-in default.\">\n              <Input placeholder=\"e.g. Complete all mandatory fields\" allowClear />\n            </Form.Item>\n            <Form.Item name=\"minRows\" label=\"Min Rows\"\n              tooltip=\"Minimum rows users must keep. Delete is disabled at this count.\">\n              <Input type=\"number\" min={0} style={{ width: 90 }} />\n            </Form.Item>\n            <Form.Item name=\"maxRows\" label=\"Max Rows\"\n              tooltip=\"Maximum rows users can add. The Add button hides once this count is reached. Blank/0 = unlimited.\">\n              <Input type=\"number\" min={0} style={{ width: 90 }} />\n            </Form.Item>\n            <Form.Item name=\"initialRows\" label=\"Initial Rows\"\n              tooltip=\"How many empty rows to show on load (0 = show only the + button).\">\n              <Input type=\"number\" min={0} style={{ width: 90 }} />\n            </Form.Item>\n            <Form.Item name=\"requireOne\" label=\"Row Required\" valuePropName=\"checked\"\n              tooltip=\"When users add a row, at least one field in that row must be filled.\">\n              <Switch checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n            </Form.Item>\n            <Form.Item name=\"requireValidatedField\" label=\"Require Validated Field\"\n              tooltip=\"A boolean field key on every row (e.g. isValid, set by a field's Verify action). The form's Submit button stays disabled until every row has it set to true. Blank = no gate.\">\n              <Input placeholder=\"e.g. isValid\" style={{ width: 130 }} className=\"fg-mono-input\" />\n            </Form.Item>\n            <Form.Item name=\"allowInProgress\" label=\"Allow &quot;still ongoing&quot; rows\"\n              valuePropName=\"checked\" initialValue\n              tooltip=\"Turn OFF where a person may only submit something they have FINISHED — for example a market where a company will not accept a course that is still being studied. When off, ticking the ongoing box on a row stops the form being submitted and shows the message below.\">\n              <Switch checkedChildren=\"Allowed\" unCheckedChildren=\"Must be finished\" />\n            </Form.Item>\n            <Form.Item name=\"inProgressMessage\" label=\"Message when not allowed\"\n              tooltip=\"Shown when someone ticks the ongoing box in a market that does not accept it. Say what they should do, not just that it is wrong.\"\n              style={{ flex: '1 1 320px' }}>\n              <Input placeholder=\"A completed qualification is required — an in-progress course cannot be submitted.\" />\n            </Form.Item>\n            <Form.Item name=\"orderByEnabled\" label=\"Keep rows newest-first\"\n              valuePropName=\"checked\"\n              tooltip=\"Keeps this section's rows in date order with the most recent at the top. If someone fills in a row whose dates make it the newest, they are asked whether to move it up — nothing is ever reordered behind their back.\">\n              <Switch checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n            </Form.Item>\n            <Form.Item name=\"levelRuleEnabled\" label=\"Require lower levels too\"\n              valuePropName=\"checked\"\n              tooltip=\"For qualification lists. When on, entering only a higher qualification (a Master's) asks for the lower one (a Bachelor's) as well. Turn OFF for markets where a higher qualification alone is acceptable. The levels themselves are edited in Masters → Degree Level.\">\n              <Switch checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n            </Form.Item>\n            <Form.Item name=\"linkGroup\" label=\"Link Group\"\n              tooltip=\"Groups sharing the same value here stay row-synced — adding or removing a row in one adds/removes the matching row in every linked group, while each keeps its own card and its own submitted data. Leave blank for an independent group. Only applies when Allow Add Row is on.\">\n              <Input placeholder=\"e.g. workHistory\" style={{ width: 160 }} className=\"fg-mono-input\" />\n            </Form.Item>\n            <Form.Item name=\"mergeInto\" label=\"Show inside another section\"\n              tooltip=\"Display these fields inside a different section's card instead of giving them a card of their own — type that section's name. This only changes where they APPEAR: what gets saved, and any rules on this group, stay exactly as they are. Leave blank to keep its own card.\">\n              <Input placeholder=\"e.g. submission_current_employer\" style={{ width: 220 }} className=\"fg-mono-input\" />\n            </Form.Item>\n            <Form.Item name=\"mergePosition\" label=\"Merge Position\" initialValue=\"bottom\"\n              tooltip=\"Whether these fields appear above or below the other card's own fields. Choose Above when this group holds the answer the other fields depend on — for example Contract Type, which decides what the Employer fields show. Below it, people are asked to fill in a section before they reach the box that unlocks it.\">\n              <Select style={{ width: 140 }} options={[\n                { label: 'Below host fields', value: 'bottom' },\n                { label: 'Above host fields', value: 'top' },\n              ]} />\n            </Form.Item>\n            <Form.Item name=\"infoEnabled\" label=\"Group Info\" valuePropName=\"checked\" initialValue={false}>\n              <Switch checkedChildren=\"Info\" unCheckedChildren=\"Info\" />\n            </Form.Item>\n            <Form.Item name=\"toggleEnabled\" label=\"Group Switch\" valuePropName=\"checked\" initialValue={false}>\n              <Switch checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n            </Form.Item>\n          </div>\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => getFieldValue('infoEnabled') ? (\n              <Form.Item\n                name=\"infoText\"\n                label=\"Group Info Message\"\n                rules={[{ required: true, message: 'Enter group info message' }]}\n              >\n                <Input.TextArea rows={2} placeholder=\"Message shown when users hover the group info icon\" />\n              </Form.Item>\n            ) : null}\n          </Form.Item>\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => getFieldValue('toggleEnabled') ? (\n              <div className=\"fg-inline-row\">\n                <Form.Item\n                  name=\"toggleLabel\"\n                  label=\"Switch Label\"\n                  rules={[{ required: true, message: 'Enter switch label' }]}\n                  style={{ flex: 1 }}\n                >\n                  <Input placeholder=\"e.g. Fresher\" />\n                </Form.Item>\n                <Form.Item\n                  name=\"toggleField\"\n                  label=\"Payload Field\"\n                  rules={[\n                    { required: true, message: 'Enter payload field' },\n                    { pattern: /^[A-Za-z_][\\w.]*$/, message: 'Use a valid key, dot path allowed' },\n                  ]}\n                  style={{ flex: 1 }}\n                >\n                  <Input placeholder=\"e.g. isFresher\" className=\"fg-mono-input\" />\n                </Form.Item>\n              </div>\n            ) : null}\n          </Form.Item>\n          <div className=\"fg-inline-row\">\n            <Form.Item name=\"afterSubmitMode\" label=\"After Submit\"\n              tooltip=\"What happens once this module's Add/Edit form submits successfully. Leave blank to keep the current default navigation.\">\n              <Select\n                allowClear\n                placeholder=\"Default (current behavior)\"\n                style={{ width: 220 }}\n                options={[\n                  { value: 'stay', label: 'Stay on Current Page' },\n                  { value: 'back', label: 'Go Back' },\n                  { value: 'route', label: 'Navigate to a Route' },\n                  { value: 'detail', label: 'Navigate to Record Detail' },\n                ]}\n              />\n            </Form.Item>\n          </div>\n          <Form.Item shouldUpdate style={{ marginBottom: 0 }} className=\"fg-group-conditional\">\n            {({ getFieldValue }) => {\n              const mode = getFieldValue('afterSubmitMode');\n              if (mode !== 'route' && mode !== 'detail') return null;\n              return (\n                <Form.Item\n                  name=\"afterSubmitTarget\"\n                  label=\"Navigation Target\"\n                  tooltip=\"An in-app path. Use :id for the created/updated record's id, or :fieldName for any submitted field value.\"\n                  rules={[\n                    { required: true, message: 'Enter a navigation target' },\n                    { pattern: /^\\//, message: 'Must be an in-app path starting with /' },\n                  ]}\n                >\n                  <Input placeholder=\"/trainers/:id\" className=\"fg-mono-input\" />\n                </Form.Item>\n              );\n            }}\n          </Form.Item>\n\n          {/* Additional submit buttons (e.g. \"Create and Source Candidate\"). */}\n          <Form.Item label=\"Additional submit buttons\"\n            tooltip=\"Extra buttons beside Create — each creates the record then navigates per its own After-Submit, optionally enabled only once a field is filled.\">\n            <Form.List name=\"formActions\">\n              {(rows, { add, remove }) => (\n                <div className=\"fg-form-actions-list\">\n                  {rows.map(({ key, name }) => (\n                    <div key={key} className=\"fg-form-action-row\" style={{ border: '1px solid #eee', borderRadius: 8, padding: 10, marginBottom: 8 }}>\n                      <Space wrap align=\"start\">\n                        <Form.Item name={[name, 'label']} label=\"Button Label\" rules={[{ required: true, message: 'Label' }]} style={{ marginBottom: 8 }}>\n                          <Input placeholder=\"e.g. Create and Source Candidate\" style={{ width: 240 }} />\n                        </Form.Item>\n                        <Form.Item name={[name, 'tone']} label=\"Type\" style={{ marginBottom: 8 }}>\n                          <Select style={{ width: 130 }} options={[\n                            { value: 'primary', label: 'Primary' },\n                            { value: 'default', label: 'Secondary' },\n                          ]} />\n                        </Form.Item>\n                        <Form.Item name={[name, 'afterSubmitMode']} label=\"After Submit\" style={{ marginBottom: 8 }}>\n                          <Select style={{ width: 180 }} options={[\n                            { value: 'stay', label: 'Stay on page' },\n                            { value: 'back', label: 'Go back' },\n                            { value: 'route', label: 'Navigate to a route' },\n                            { value: 'detail', label: 'Record detail' },\n                          ]} />\n                        </Form.Item>\n                        <Form.Item noStyle shouldUpdate>\n                          {({ getFieldValue }) => (['route', 'detail'].includes(getFieldValue(['formActions', name, 'afterSubmitMode']))\n                            ? (\n                              <Form.Item name={[name, 'afterSubmitTarget']} label=\"Target\" style={{ marginBottom: 8 }}\n                                rules={[{ pattern: /^\\//, message: 'Must start with /' }]}>\n                                <Input placeholder=\"/jobs/:id/source\" className=\"fg-mono-input\" style={{ width: 200 }} />\n                              </Form.Item>\n                            ) : null)}\n                        </Form.Item>\n                        <Button type=\"text\" danger icon={<DeleteOutlined />} onClick={() => remove(name)} style={{ marginTop: 28 }} />\n                      </Space>\n                      <Space wrap align=\"start\">\n                        <Form.Item name={[name, 'enabledWhenField']} label=\"Enable when field\" style={{ marginBottom: 0 }}\n                          tooltip=\"Keep the button disabled until this record field satisfies the condition (e.g. Assign To is set). Blank = always enabled.\">\n                          <Input placeholder=\"e.g. assignedTo\" style={{ width: 200 }} />\n                        </Form.Item>\n                        <Form.Item name={[name, 'enabledWhenOperator']} label=\"Condition\" style={{ marginBottom: 0 }}>\n                          <Select style={{ width: 130 }} options={[\n                            { value: 'notEmpty', label: 'is set' },\n                            { value: 'isEmpty', label: 'is empty' },\n                            { value: 'eq', label: 'equals' },\n                            { value: 'neq', label: 'not equals' },\n                            { value: 'in', label: 'in list' },\n                            { value: 'notIn', label: 'not in list' },\n                          ]} />\n                        </Form.Item>\n                        <Form.Item noStyle shouldUpdate>\n                          {({ getFieldValue }) => (['eq', 'neq', 'in', 'notIn'].includes(getFieldValue(['formActions', name, 'enabledWhenOperator']))\n                            ? (\n                              <Form.Item name={[name, 'enabledWhenValue']} label=\"Value\" style={{ marginBottom: 0 }}>\n                                <Input placeholder=\"Value(s)\" style={{ width: 160 }} />\n                              </Form.Item>\n                            ) : null)}\n                        </Form.Item>\n                      </Space>\n                    </div>\n                  ))}\n                  <Button type=\"dashed\" icon={<PlusOutlined />} onClick={() => add({ tone: 'primary', afterSubmitMode: 'stay', enabledWhenOperator: 'notEmpty' })}>\n                    Add submit button\n                  </Button>\n                </div>\n              )}\n            </Form.List>\n          </Form.Item>\n\n          <div className=\"fg-inline-row\">\n            <Form.Item name=\"submitMsgAddSuccess\" label=\"Add Success Message\"\n              tooltip={'Toast shown after a successful Add. ${module} is replaced with the module name. Blank = default \"<Module> has added successfully\".'}>\n              <Input placeholder=\"${module} has added successfully\" style={{ width: 280 }} />\n            </Form.Item>\n            <Form.Item name=\"submitMsgEditSuccess\" label=\"Edit Success Message\"\n              tooltip={'Toast shown after a successful Edit. ${module} is replaced with the module name. Blank = default \"<Module> has Updated successfully\".'}>\n              <Input placeholder=\"${module} has Updated successfully\" style={{ width: 280 }} />\n            </Form.Item>\n          </div>\n          <div className=\"fg-inline-row\">\n            <Form.Item name=\"submitMsgAddError\" label=\"Add Error Message\"\n              tooltip=\"Toast shown when Add fails. Blank = show the server's error.\">\n              <Input placeholder=\"Server error (default)\" style={{ width: 280 }} />\n            </Form.Item>\n            <Form.Item name=\"submitMsgEditError\" label=\"Edit Error Message\"\n              tooltip=\"Toast shown when Edit fails. Blank = show the server's error.\">\n              <Input placeholder=\"Server error (default)\" style={{ width: 280 }} />\n            </Form.Item>\n            <Form.Item name=\"submitMsgSuppress\" label=\"Hide Success Toast\" valuePropName=\"checked\"\n              tooltip=\"Prevent the success message for this module's Add/Edit (errors always show).\">\n              <Switch checkedChildren=\"Hidden\" unCheckedChildren=\"Shown\" />\n            </Form.Item>\n          </div>\n        </div>\n        <div className=\"fg-editor-next-row\">\n          <Text type=\"secondary\">Next, review the fields included in this group.</Text>\n          <Button type=\"primary\" onClick={() => selectEditorTab('fields')}>Continue to Fields</Button>\n        </div>\n        </div>\n\n        {fieldsVisited && (\n        <div className={`fg-group-editor-panel${editorTab === 'fields' ? ' is-active' : ''}`}>\n        <div className=\"fg-fields-header\">\n          <span className=\"fg-fields-title\">Fields</span>\n          <span className=\"fg-fields-hint\">Open only the field you want to change</span>\n          {fieldsLoading && <Spin size=\"small\" />}\n          {!fieldsLoading && options.length > 0 && (\n            <span className=\"fg-fields-hint\">{options.length} fields available</span>\n          )}\n        </div>\n        <Form.List name=\"fields\">\n          {(fieldItems, { add, remove, move }) => renderFieldRows({\n            form, fieldItems, add, remove, move,\n            absBase: [],\n            moduleFieldOptions: options,\n            fieldsLoading, dragIndexRef, dragOverIndex, setDragOverIndex,\n            onFieldKeySelect: (val, rowName) => handleFieldKeySelect(val, rowName),\n            expandedFieldKeys,\n            onToggleField: toggleField,\n            defaultFieldSet,\n            uniqueTarget: {\n              primaryModule: form.getFieldValue('module') || defaultModule || '',\n              // A Target Collection group's fields are written to THAT module\n              // through moduleWrites, so uniqueness must be checked there.\n              getTargetModule: () => form.getFieldValue('moduleName') || '',\n              collectionForModule,\n            },\n          })}\n        </Form.List>\n        </div>\n        )}\n      </Form>\n    </Modal>\n  );\n}\n\n// ── Groups Table ──────────────────────────────────────────────────────────────\nfunction ModuleGroupsTable({ groups, onEdit, onDelete, onCopy, onPaste, canPaste, onReorder }) {\n  const dragFrom = useRef(null);\n  const sorted = [...groups].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n  const reorderable = typeof onReorder === 'function' && sorted.length > 1;\n\n  const handleMove = (from, to) => {\n    const next = [...sorted];\n    const [moved] = next.splice(from, 1);\n    next.splice(to, 0, moved);\n    onReorder(next);\n  };\n\n  // Native-drag table row (same HTML5-drag approach as the field editor).\n  // Defined here as a closure so it reads dragFrom/handleMove directly instead\n  // of mutating a value passed through props.\n  const DraggableGroupRow = useMemo(() => {\n    function Row({ 'data-row-index': rowIndex, ...rest }) {\n      if (rowIndex === undefined) return <tr {...rest} />;\n      return (\n        <tr\n          {...rest}\n          draggable\n          onDragStart={() => { dragFrom.current = rowIndex; }}\n          onDragOver={(e) => { e.preventDefault(); }}\n          onDrop={(e) => {\n            e.preventDefault();\n            const from = dragFrom.current;\n            dragFrom.current = null;\n            if (from !== null && from !== rowIndex) handleMove(from, rowIndex);\n          }}\n          style={{ ...(rest.style || {}), cursor: 'grab' }}\n        />\n      );\n    }\n    return Row;\n    // handleMove closes over `sorted`/`onReorder`; recompute when the row set changes.\n  }, [sorted, onReorder]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const columns = [\n    ...(reorderable ? [{\n      title: '', key: 'drag', width: 34, align: 'center',\n      render: () => <HolderOutlined className=\"fg-drag-handle\" style={{ cursor: 'grab', color: 'var(--color-text-secondary)' }} />,\n    }] : []),\n    {\n      title: 'Label', dataIndex: 'label', key: 'label',\n      render: (label, record) => (\n        <Space size={6}>\n          <Text strong style={{ color: 'var(--color-text-heading)' }}>{label}</Text>\n          {record.hideGroup && <Tag color=\"default\">Hidden</Tag>}\n          {!record.hideGroup && record.hideGroupInForm && <Tag color=\"default\">Detail only</Tag>}\n          {record.moduleName && <Tag color=\"purple\">→ {record.moduleName}</Tag>}\n          {record.hierarchyParent && <Tag color=\"gold\">L{record.hierarchyLevel ?? '?'} ← {record.hierarchyParent}</Tag>}\n        </Space>\n      ),\n    },\n    { title: 'Key', dataIndex: 'name', key: 'name', render: (name) => <code className=\"fg-table-code\">{name}</code> },\n    {\n      title: 'Add Row', dataIndex: 'addRow', key: 'addRow', align: 'center', width: 90,\n      render: (val) => val\n        ? <Tag color=\"blue\" style={{ margin: 0 }}>Yes</Tag>\n        : <Tag color=\"default\" style={{ margin: 0 }}>No</Tag>,\n    },\n    {\n      title: 'Order', dataIndex: 'order', key: 'order', align: 'center', width: 72,\n      render: (v) => <span className=\"fg-order-cell\">{v ?? 0}</span>,\n    },\n    {\n      title: 'Fields', dataIndex: 'fields', key: 'fields', align: 'center', width: 76,\n      render: (fields) => <Badge count={fields?.length ?? 0} showZero color=\"var(--color-brand)\" />,\n    },\n    {\n      title: '', key: 'actions', align: 'right', width: 132,\n      render: (_, record) => (\n        <Space size={4}>\n          <Tooltip title=\"Copy settings\">\n            <Button type=\"text\" size=\"small\" icon={<CopyOutlined />} onClick={() => onCopy(record)} className=\"fg-action-btn\" />\n          </Tooltip>\n          <Tooltip title=\"Paste copied settings into this group\">\n            <Button type=\"text\" size=\"small\" icon={<SnippetsOutlined />} disabled={!canPaste} onClick={() => onPaste(record)} className=\"fg-action-btn\" />\n          </Tooltip>\n          <Tooltip title=\"Edit group\">\n            <Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => onEdit(record)} className=\"fg-action-btn\" />\n          </Tooltip>\n          <Popconfirm\n            title=\"Delete this group?\"\n            description=\"All field mappings inside will be removed.\"\n            onConfirm={() => onDelete(record.id)}\n            okText=\"Delete\" okButtonProps={{ danger: true }}\n          >\n            <Tooltip title=\"Delete group\">\n              <Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} className=\"fg-action-btn\" />\n            </Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <Table\n      rowKey={(r) => r.id ?? r.name}\n      dataSource={sorted}\n      columns={columns}\n      pagination={false}\n      className=\"fg-table\"\n      components={reorderable ? { body: { row: DraggableGroupRow } } : undefined}\n      onRow={reorderable\n        ? (_, index) => ({ 'data-row-index': index, dragCtx: { from: dragFrom, onMove: handleMove } })\n        : undefined}\n      locale={{\n        emptyText: (\n          <Empty description=\"No groups configured for this module yet.\"\n            image={Empty.PRESENTED_IMAGE_SIMPLE} style={{ padding: '24px 0' }} />\n        ),\n      }}\n      expandable={{\n        expandedRowRender: (record) =>\n          (record.fields ?? []).length === 0 ? (\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>No fields in this group.</Text>\n          ) : (\n            <div className=\"fg-expanded-fields\">\n              {(record.fields ?? []).map((f) => {\n                const dsColorMap = { master: 'geekblue', module: 'cyan', lookup: 'volcano', static: 'default' };\n                const dsLabelMap = {\n                  master: `master: ${f.masterName || '?'}`,\n                  module: 'module',\n                  lookup: `lookup: ${f.lookupCollection || '?'} → ${f.displayField || '?'}`,\n                  static: `static (${(f.options ?? []).length})`,\n                };\n                return (\n                  <div key={f.field} className=\"fg-field-row\">\n                    <div className=\"fg-field-row-info\">\n                      <span className=\"fg-field-row-label\">{f.label}</span>\n                      <span className=\"fg-field-row-key\">{f.field}</span>\n                      <span className=\"fg-field-row-type\">({f.type})</span>\n                      {['select', 'radio', 'checkbox'].includes(f.type) && f.dataSource && (\n                        <Tag color={dsColorMap[f.dataSource] ?? 'default'} style={{ fontSize: 10, marginLeft: 6 }}>\n                          {dsLabelMap[f.dataSource] ?? f.dataSource}\n                        </Tag>\n                      )}\n                    </div>\n                    <div className=\"fg-field-row-flags\">\n                      {f.show === 1 && <Tag color=\"blue\" style={{ marginRight: 4 }}>Show</Tag>}\n                      {f.showOnAdd === false && <Tag color=\"orange\" style={{ marginRight: 4 }}>Edit only</Tag>}\n                      {f.req  === 1 && <Tag color=\"red\"  style={{ marginRight: 4 }}>Required</Tag>}\n                      {f.edit === 1 && <Tag color=\"green\" style={{ marginRight: 4 }}>Editable</Tag>}\n                      {f.formatter && <Tag color=\"purple\" style={{ marginRight: 4 }}>fmt: {f.formatter}</Tag>}\n                    </div>\n                    {(f.validations ?? []).length > 0 && (\n                      <div className=\"fg-field-row-validations\">\n                        <CheckCircleOutlined style={{ color: 'var(--color-brand)', fontSize: 11, marginRight: 4 }} />\n                        {(f.validations ?? []).map((v, vi) => {\n                          // A field-targeting rule (maxFromField) has no `value` — its\n                          // argument is `field`. Showing one or the other keeps the\n                          // summary chip honest instead of rendering a bare rule name.\n                          // A unique rule's `value` is a config OBJECT, which would\n                          // interpolate as \"[object Object]\" — show the stored key it\n                          // guards instead, which is the useful part at a glance.\n                          const isUniqueRuleTag = v.type === UNIQUE_VALIDATION_TYPE;\n                          const rawArg = isUniqueRuleTag\n                            ? String(v.value?.collectionField ?? f.payloadKey ?? f.field ?? '')\n                            : v.value;\n                          const arg = (rawArg !== undefined && rawArg !== '') ? rawArg : (v.field ?? '');\n                          const argLabel = isUniqueRuleTag\n                            ? 'Stored field'\n                            : (v.field && !(v.value !== undefined && v.value !== '') ? 'Field' : 'Value');\n                          return (\n                            <Tooltip key={vi}\n                              title={`${arg !== '' ? `${argLabel}: ${arg} — ` : ''}${v.message}`}>\n                              <Tag color={VALIDATION_TAG_COLOR[v.type] ?? 'default'}\n                                style={{ cursor: 'default', fontFamily: 'monospace', fontSize: 10 }}>\n                                {v.type}{arg !== '' ? `(${arg})` : ''}\n                              </Tag>\n                            </Tooltip>\n                          );\n                        })}\n                      </div>\n                    )}\n                  </div>\n                );\n              })}\n            </div>\n          ),\n        rowExpandable: () => true,\n      }}\n    />\n  );\n}\n\n// ── Custom Form Drawer ────────────────────────────────────────────────────────\n// Full drawer: form identity (module/action/label) + groups with fields.\n// Each group's field list uses renderFieldRows with absBase=['groups', gName].\nfunction CustomFormDrawer({ open, editingForm, moduleOptions, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const [selectedModule, setSelectedModule] = useState('');\n  const [moduleFields, setModuleFields] = useState({});\n  const [fieldsLoading, setFieldsLoading] = useState(false);\n  const [dragOverIndex, setDragOverIndex] = useState(null);\n  const loadedRef = useRef({});\n  const dragIndexRef = useRef(null);\n  const collectionForModule = useModuleCollections();\n\n  async function ensureModuleFields(mod) {\n    if (!mod || loadedRef.current[mod]) return;\n    setFieldsLoading(true);\n    try {\n      const fields = await getModuleFields(mod);\n      setModuleFields((prev) => ({ ...prev, [mod]: fields }));\n      loadedRef.current[mod] = true;\n    } catch { /* fall back to free-text */ } finally {\n      setFieldsLoading(false);\n    }\n  }\n\n  useEffect(() => {\n    if (!open) { loadedRef.current = {}; setModuleFields({}); return; }\n    if (editingForm) {\n      const mod = editingForm.module;\n      setSelectedModule(mod);\n      form.setFieldsValue({\n        module: mod,\n        formType: editingForm.formType || \"popup\",\n        action: editingForm.action,\n        label:  editingForm.label,\n        booleanSearchEnabled: editingForm.booleanSearchEnabled ?? false,\n        booleanSearchEndpoint: editingForm.booleanSearchEndpoint ?? '',\n        booleanDefaultSourceType: editingForm.booleanDefaultSourceType ?? '',\n        searchEndpoint: editingForm.searchEndpoint ?? '',\n        actionButtonEnabled: editingForm.actionButtonEnabled ?? false,\n        actionButtonLabel: editingForm.actionButtonLabel ?? '',\n        actionButtonUrl: editingForm.actionButtonUrl ?? '',\n        actionButtonTarget: editingForm.actionButtonTarget ?? '_self',\n        groups: (editingForm.groups ?? []).map((g) => ({\n          ...g,\n          hideGroup: g.hideGroup ?? false,\n          hideGroupInForm: g.hideGroupInForm ?? false,\n          moduleName: g.moduleName ?? '',\n          infoEnabled: g.infoEnabled ?? false,\n          infoText: g.infoText ?? '',\n          minRows: g.minRows ?? '',\n          initialRows: g.initialRows ?? '',\n          requireOne: g.requireOne ?? false,\n          linkGroup: g.linkGroup ?? '',\n          toggleEnabled: g.toggleEnabled ?? false,\n          toggleLabel: g.toggleLabel ?? '',\n          toggleField: g.toggleField ?? '',\n          fields: (g.fields ?? []).map(initFieldValues),\n        })),\n      });\n      ensureModuleFields(mod);\n    } else {\n      form.resetFields();\n      form.setFieldsValue({ groups: [], formType: \"popup\" });\n      setSelectedModule('');\n    }\n  }, [open, editingForm, form]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  function handleModuleChange(mod) { setSelectedModule(mod); ensureModuleFields(mod); }\n\n  function fieldOptions() {\n    return (moduleFields[selectedModule] ?? []).map((f) => ({\n      value: f.value,\n      label: (\n        <span>{f.label}<span className=\"fg-field-key-hint\">{f.value}</span></span>\n      ),\n      searchLabel: `${f.label} ${f.value}`.toLowerCase(),\n    }));\n  }\n\n  async function handleSave() {\n    try {\n      const values = await form.validateFields();\n      // Same save-time backstop as the group editor: a malformed uniqueness rule\n      // is refused, never quietly written.\n      const uniqueProblems = (values.groups ?? [])\n        .flatMap((g) => collectUniqueRuleErrors(g?.fields));\n      if (uniqueProblems.length) {\n        message.error(`Uniqueness rule cannot be saved — ${uniqueProblems[0]}`);\n        return;\n      }\n      setSaving(true);\n      const payload = {\n        module: values.module,\n        formType: values.formType,\n        action: values.action.trim(),\n        label:  values.label,\n        // Boolean search is opt-in per search form. Omitted entirely when off,\n        // so every form that never enables it keeps its existing document shape\n        // and its existing runtime behaviour.\n        ...(values.formType === 'search' && values.booleanSearchEnabled ? {\n          booleanSearchEnabled: true,\n          booleanSearchEndpoint: String(values.booleanSearchEndpoint ?? '').trim(),\n          ...(values.booleanDefaultSourceType\n            ? { booleanDefaultSourceType: values.booleanDefaultSourceType } : {}),\n        } : {}),\n        // Written unconditionally, unlike the boolean keys above: handleSave\n        // sends { ...editingForm, ...payload }, so an omitted key would let the\n        // previously saved value come straight back — and CLEARING the field\n        // would never persist, which is what makes the switch reversible.\n        searchEndpoint: values.formType === 'search'\n          ? String(values.searchEndpoint ?? '').trim()\n          : '',\n        actionButtonEnabled: !!values.actionButtonEnabled,\n        actionButtonLabel: String(values.actionButtonLabel ?? '').trim(),\n        actionButtonUrl: String(values.actionButtonUrl ?? '').trim(),\n        actionButtonTarget: values.actionButtonTarget || '_self',\n        groups: (values.groups ?? []).map((g) => ({\n          label:  g.label,\n          name:   g.name,\n          addRow: g.addRow ?? false,\n          ...(g.hideGroup ? { hideGroup: true } : {}),\n          ...(g.hideGroupInForm ? { hideGroupInForm: true } : {}),\n          ...(g.moduleName ? { moduleName: g.moduleName } : {}),\n          // Preserve dependency config (edited in the main group editor) so a\n          // custom-form re-save never strips it.\n          ...(g.moduleName && (g.writeRefs ?? []).length ? { writeRefs: g.writeRefs } : {}),\n          ...(g.moduleName && (g.dependsOn ?? []).length ? { dependsOn: g.dependsOn } : {}),\n          ...(g.moduleName && g.optionalWrite ? { optionalWrite: true } : {}),\n          // Preserve the Target Collection linkage (child→parent linkField or\n          // forward-lookup parentRefField) so a custom-form re-save never strips it.\n          ...(g.moduleName && g.linkField ? { linkField: g.linkField } : {}),\n          ...(g.moduleName && g.linkTypeField ? { linkTypeField: g.linkTypeField } : {}),\n          ...(g.moduleName && g.parentRefField ? { parentRefField: g.parentRefField } : {}),\n          // Preserve collection hierarchy config the same way — chains this\n          // Target Collection under another collection of the same form.\n          ...(g.moduleName && g.hierarchyParent && g.hierarchyLinkField ? {\n            hierarchyParent: g.hierarchyParent,\n            hierarchyLinkField: g.hierarchyLinkField,\n          } : {}),\n          // Level is preserved independently — it is a valid ordering hint on\n          // its own, so it must survive a re-save even with no parent link.\n          ...(g.moduleName && Number.isFinite(Number(g.hierarchyLevel)) && Number(g.hierarchyLevel) > 0\n            ? { hierarchyLevel: Number(g.hierarchyLevel) } : {}),\n          // Preserve append-history config the same way — independent of\n          // Target Collection, so it's guarded by its own field, not moduleName.\n          ...(g.appendHistory && g.historyField ? {\n            appendHistory: true,\n            historyField: g.historyField,\n            ...(g.historyTimestampField ? { historyTimestampField: g.historyTimestampField } : {}),\n          } : {}),\n          ...(g.addRow && g.minRows !== undefined && g.minRows !== '' ? { minRows: Number(g.minRows) } : {}),\n          ...(g.addRow && g.initialRows !== undefined && g.initialRows !== '' ? { initialRows: Number(g.initialRows) } : {}),\n          ...(g.addRow && g.requireOne ? { requireOne: true } : {}),\n          ...(g.addRow && g.linkGroup ? { linkGroup: g.linkGroup.trim() } : {}),\n          order:  Number(g.order ?? 0),\n          fields: buildFieldPayload(g.fields ?? []),\n          ...(g.infoEnabled && g.infoText ? { infoEnabled: true, infoText: g.infoText } : {}),\n        })),\n      };\n      if (editingForm) {\n        await updateCustomForm(editingForm.id, { ...editingForm, ...payload });\n        message.success('Custom form updated');\n      } else {\n        await createCustomForm(payload);\n        message.success('Custom form created');\n      }\n      onSaved();\n    } catch (err) {\n      if (err?.errorFields) return;\n      message.error(err.message || 'Could not save custom form');\n    } finally { setSaving(false); }\n  }\n\n  const fldOptions = fieldOptions();\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      width={1120}\n      centered\n      destroyOnClose\n      maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={\n        <span className=\"fg-drawer-title\">\n          {editingForm ? <EditOutlined /> : <PlusOutlined />}\n          {editingForm ? ' Edit Custom Form' : ' New Custom Form'}\n        </span>\n      }\n      footer={\n        <div className=\"fg-drawer-footer\">\n          <Button onClick={onClose}>Cancel</Button>\n          <Button type=\"primary\" loading={saving} onClick={handleSave}\n            icon={editingForm ? <EditOutlined /> : <PlusOutlined />}>\n            {editingForm ? 'Update' : 'Create'}\n          </Button>\n        </div>\n      }\n    >\n      <Form form={form} layout=\"vertical\" className=\"fg-form fg-editor-form\">\n        {/* Identity */}\n        <div className=\"fg-form-section fg-editor-sticky-section\">\n          <div className=\"fg-form-section-label\">Form Identity</div>\n          <Form.Item name=\"module\" label=\"Module\" rules={[{ required: true, message: 'Select a module' }]}>\n            <Select options={moduleOptions} placeholder=\"Select module\" onChange={handleModuleChange} />\n          </Form.Item>\n          <Form.Item name=\"formType\" label=\"Form Type\" rules={[{ required: true, message: 'Form Type is required' }]}\n            initialValue=\"popup\">\n            <Select placeholder=\"Select form type\"\n              options={[\n                { label: 'Search', value: 'search' },\n                { label: 'Popup', value: 'popup' },\n              ]}\n            />\n          </Form.Item>\n          <Form.Item\n            name=\"action\"\n            label=\"Action Key\"\n            extra=\"Unique identifier used as ?action= in the URL (e.g. quickAdd, popup)\"\n            rules={[\n              { required: true, message: 'Action is required' },\n              { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Letters, numbers, hyphens, underscores only' },\n            ]}\n          >\n            <Input placeholder=\"e.g. quickAdd\" className=\"fg-mono-input\" disabled={!!editingForm} />\n          </Form.Item>\n          <Form.Item name=\"label\" label=\"Display Label\" rules={[{ required: true, message: 'Label is required' }]}>\n            <Input placeholder=\"e.g. Quick Add Job\" />\n          </Form.Item>\n\n          {/* Boolean search — only meaningful on a search form */}\n          <Form.Item noStyle shouldUpdate>\n            {({ getFieldValue }) => {\n              if (getFieldValue('formType') !== 'search') return null;\n              const enabled = getFieldValue('booleanSearchEnabled');\n              return (\n                <>\n                  {/* Deliberately separate from Boolean Endpoint below. That one\n                      means \"where boolean mode POSTs\"; this means \"EVERY search\n                      on this form goes here, and the results table reads its\n                      columns/actions/tabs from that response\". Reusing the\n                      boolean key would silently reroute traditional search on\n                      any form that merely enabled the toggle. */}\n                  <Form.Item name=\"searchEndpoint\" label=\"Search Endpoint\"\n                    extra=\"Routes every search on this form — traditional and boolean — through one endpoint. Leave blank to use the common module list API.\">\n                    <Input placeholder=\"/candidates/boolean-search\" className=\"fg-mono-input\" allowClear />\n                  </Form.Item>\n                  <Form.Item name=\"booleanSearchEnabled\" label=\"Enable Boolean Search\"\n                    valuePropName=\"checked\" initialValue={false}\n                    extra=\"Adds a Boolean toggle to this search form. Off means the form behaves exactly as it does today.\">\n                    <Switch size=\"small\" checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n                  </Form.Item>\n                  {enabled && (\n                    <>\n                      <Form.Item name=\"booleanSearchEndpoint\" label=\"Boolean Endpoint\"\n                        rules={[{ required: true, message: 'Required while Boolean Search is enabled' }]}\n                        extra=\"Backend path used in Boolean mode, e.g. /candidates/boolean-search\">\n                        <Input placeholder=\"/candidates/boolean-search\" className=\"fg-mono-input\" />\n                      </Form.Item>\n                      <Form.Item name=\"booleanDefaultSourceType\" label=\"Default Source Type\"\n                        extra=\"Sent as sourceType when the form has no source field. Leave blank for 'internal'.\">\n                        <Input placeholder=\"internal,dice\" className=\"fg-mono-input\" />\n                      </Form.Item>\n                    </>\n                  )}\n                </>\n              );\n            }}\n          </Form.Item>\n\n          {/* Link button — one extra action rendered next to the form's own\n              Reset/Search buttons. Not gated to search forms: a link out to a\n              related screen makes sense on any form. */}\n          <Form.Item noStyle shouldUpdate>\n            {({ getFieldValue }) => (\n              <>\n                <Form.Item name=\"actionButtonEnabled\" label=\"Show Link Button\"\n                  valuePropName=\"checked\" initialValue={false}\n                  extra=\"Adds one button beside Reset/Search that navigates to another screen. Off means no button renders at all.\">\n                  <Switch size=\"small\" checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n                </Form.Item>\n                {getFieldValue('actionButtonEnabled') && (\n                  <>\n                    <Form.Item name=\"actionButtonLabel\" label=\"Button Label\"\n                      rules={[{ required: true, message: 'Required while the link button is on' }]}\n                      extra=\"Text shown on the button, e.g. Job Description\">\n                      <Input placeholder=\"Job Description\" />\n                    </Form.Item>\n                    <Form.Item name=\"actionButtonUrl\" label=\"Destination\"\n                      rules={[\n                        { required: true, message: 'Required while the link button is on' },\n                        {\n                          // Same rule safeNavTarget enforces at runtime, applied\n                          // here so a bad URL is caught at save time instead of\n                          // silently disabling the button on the live screen.\n                          validator: (_rule, value) => {\n                            const raw = String(value ?? '').trim();\n                            if (!raw) return Promise.resolve();\n                            if (!raw.startsWith('/') || raw.startsWith('//')) {\n                              return Promise.reject(new Error('Must be an in-app path starting with a single /'));\n                            }\n                            if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) {\n                              return Promise.reject(new Error('External and scheme: URLs are not allowed'));\n                            }\n                            return Promise.resolve();\n                          },\n                        },\n                      ]}\n                      extra=\"In-app path. :tokens resolve against the record the search runs for, e.g. /jobs/detailview?id=:jobId&tab=details\">\n                      <Input placeholder=\"/jobs/detailview?id=:jobId&tab=details\" className=\"fg-mono-input\" />\n                    </Form.Item>\n                    <Form.Item name=\"actionButtonTarget\" label=\"Open In\"\n                      initialValue=\"_self\">\n                      <Select size=\"small\" style={{ width: 180 }} options={[\n                        { label: 'Same tab', value: '_self' },\n                        { label: 'New tab', value: '_blank' },\n                      ]} />\n                    </Form.Item>\n                  </>\n                )}\n              </>\n            )}\n          </Form.Item>\n        </div>\n\n        {/* Groups */}\n        <div className=\"fg-fields-header\">\n          <span className=\"fg-fields-title\">Groups</span>\n          <span className=\"fg-fields-hint\">Each group holds a set of form fields</span>\n          {fieldsLoading && <Spin size=\"small\" />}\n        </div>\n\n        <Form.List name=\"groups\">\n          {(groupItems, { add: addGroup, remove: removeGroup }) => (\n            <>\n              {groupItems.map(({ key: gKey, name: gName }) => (\n                <div key={gKey} className=\"fg-form-section\" style={{ marginBottom: 16 }}>\n                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>\n                    <span className=\"fg-form-section-label\" style={{ marginBottom: 0 }}>Group {gName + 1}</span>\n                    <Tooltip title=\"Remove group\">\n                      <button type=\"button\" className=\"fg-field-remove-btn\"\n                        onClick={() => removeGroup(gName)} aria-label=\"Remove group\">\n                        <MinusCircleOutlined />\n                      </button>\n                    </Tooltip>\n                  </div>\n\n                  <div className=\"fg-inline-row\" style={{ flexWrap: 'wrap', marginBottom: 8 }}>\n                    <Form.Item name={[gName, 'label']} label=\"Group Label\"\n                      rules={[{ required: true, message: 'Required' }]}\n                      style={{ flex: 2, marginBottom: 8 }}>\n                      <Input placeholder=\"e.g. Basic Info\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'name']} label=\"Group Key\"\n                      rules={[\n                        { required: true, message: 'Required' },\n                        { pattern: /^[a-z0-9_]+$/, message: 'Lowercase, numbers, underscores' },\n                      ]}\n                      style={{ flex: 2, marginBottom: 8 }}>\n                      <Input placeholder=\"e.g. basicInfo\" className=\"fg-mono-input\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'addRow']} label=\"Add Row\" valuePropName=\"checked\"\n                      initialValue={false} style={{ marginBottom: 8 }}>\n                      <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'hideGroup']} label=\"Hide Group\" valuePropName=\"checked\"\n                      initialValue={false} style={{ marginBottom: 8 }}\n                      tooltip=\"Hide this group entirely from Add/Edit forms — not rendered, not validated, not submitted.\">\n                      <Switch size=\"small\" checkedChildren=\"Hidden\" unCheckedChildren=\"Visible\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'moduleName']} label=\"Target Collection\"\n                      style={{ marginBottom: 8, flex: 2 }}\n                      tooltip=\"Route THIS group's fields to a different collection instead of the default module record. Leave blank for default behaviour.\">\n                      <AutoComplete\n                        size=\"small\"\n                        options={moduleOptions.map((m) => ({ value: m.value, label: m.label }))}\n                        placeholder=\"Default\"\n                        allowClear\n                        filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n                        className=\"fg-mono-input\"\n                      />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'minRows']} label=\"Min Rows\"\n                      style={{ marginBottom: 8 }}\n                      tooltip=\"Minimum rows users must keep. Delete is disabled at this count.\">\n                      <Input type=\"number\" min={0} style={{ width: 80 }} />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'initialRows']} label=\"Initial Rows\"\n                      style={{ marginBottom: 8 }}\n                      tooltip=\"How many empty rows to show on load (0 = show only the + button).\">\n                      <Input type=\"number\" min={0} style={{ width: 80 }} />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'requireOne']} label=\"Row Required\" valuePropName=\"checked\"\n                      initialValue={false} style={{ marginBottom: 8 }}\n                      tooltip=\"When users add a row, at least one field in that row must be filled.\">\n                      <Switch size=\"small\" checkedChildren=\"Yes\" unCheckedChildren=\"No\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'linkGroup']} label=\"Link Group\"\n                      style={{ marginBottom: 8 }}\n                      tooltip=\"Groups sharing the same value here stay row-synced — adding or removing a row in one adds/removes the matching row in every linked group, while each keeps its own card and its own submitted data. Leave blank for an independent group.\">\n                      <Input size=\"small\" placeholder=\"e.g. workHistory\" style={{ width: 130 }} className=\"fg-mono-input\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'infoEnabled']} label=\"Group Info\" valuePropName=\"checked\"\n                      initialValue={false} style={{ marginBottom: 8 }}>\n                      <Switch size=\"small\" checkedChildren=\"Info\" unCheckedChildren=\"Info\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'toggleEnabled']} label=\"Group Switch\" valuePropName=\"checked\"\n                      initialValue={false} style={{ marginBottom: 8 }}>\n                      <Switch size=\"small\" checkedChildren=\"On\" unCheckedChildren=\"Off\" />\n                    </Form.Item>\n                    <Form.Item name={[gName, 'order']} label=\"Order\" initialValue={0}\n                      style={{ marginBottom: 8 }}>\n                      <Input type=\"number\" min={0} style={{ width: 70 }} />\n                    </Form.Item>\n                  </div>\n                  <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                    {({ getFieldValue }) => getFieldValue(['groups', gName, 'infoEnabled']) ? (\n                      <Form.Item\n                        name={[gName, 'infoText']}\n                        label=\"Group Info Message\"\n                        rules={[{ required: true, message: 'Enter group info message' }]}\n                      >\n                        <Input.TextArea rows={2} placeholder=\"Message shown when users hover the group info icon\" />\n                      </Form.Item>\n                    ) : null}\n                  </Form.Item>\n                  <Form.Item shouldUpdate style={{ marginBottom: 8 }}>\n                    {({ getFieldValue }) => getFieldValue(['groups', gName, 'toggleEnabled']) ? (\n                      <div className=\"fg-inline-row\">\n                        <Form.Item\n                          name={[gName, 'toggleLabel']}\n                          label=\"Switch Label\"\n                          rules={[{ required: true, message: 'Enter switch label' }]}\n                          style={{ flex: 1, marginBottom: 0 }}\n                        >\n                          <Input placeholder=\"e.g. Fresher\" />\n                        </Form.Item>\n                        <Form.Item\n                          name={[gName, 'toggleField']}\n                          label=\"Payload Field\"\n                          rules={[\n                            { required: true, message: 'Enter payload field' },\n                            { pattern: /^[A-Za-z_][\\w.]*$/, message: 'Use a valid key, dot path allowed' },\n                          ]}\n                          style={{ flex: 1, marginBottom: 0 }}\n                        >\n                          <Input placeholder=\"e.g. isFresher\" className=\"fg-mono-input\" />\n                        </Form.Item>\n                      </div>\n                    ) : null}\n                  </Form.Item>\n\n                  <div className=\"fg-fields-header\" style={{ marginTop: 4, marginBottom: 8 }}>\n                    <span className=\"fg-fields-title\" style={{ fontSize: 12 }}>Fields</span>\n                  </div>\n\n                  <Form.List name={[gName, 'fields']}>\n                    {(fieldItems, { add, remove, move }) => renderFieldRows({\n                      form, fieldItems, add, remove, move,\n                      absBase: ['groups', gName],\n                      moduleFieldOptions: fldOptions,\n                      fieldsLoading, dragIndexRef, dragOverIndex, setDragOverIndex,\n                      onFieldKeySelect: (val, rowName) => {\n                        const apiFields = moduleFields[selectedModule] ?? [];\n                        const match = apiFields.find((f) => f.value === val);\n                        if (!match) return;\n                        const current = form.getFieldValue(['groups', gName, 'fields', rowName]) ?? {};\n                        form.setFieldValue(['groups', gName, 'fields', rowName], {\n                          ...current, field: match.value, label: match.label, type: match.type ?? 'text',\n                        });\n                      },\n                      uniqueTarget: {\n                        primaryModule: selectedModule || '',\n                        getTargetModule: () => form.getFieldValue(['groups', gName, 'moduleName']) || '',\n                        collectionForModule,\n                      },\n                    })}\n                  </Form.List>\n                </div>\n              ))}\n\n              <Button\n                type=\"dashed\" icon={<PlusOutlined />} block style={{ marginBottom: 16 }}\n                onClick={() => addGroup({ label: '', name: '', addRow: false, order: groupItems.length, fields: [] })}\n              >\n                Add Group\n              </Button>\n            </>\n          )}\n        </Form.List>\n      </Form>\n    </Modal>\n  );\n}\n\n// ── Custom Forms Section ──────────────────────────────────────────────────────\nfunction CustomFormsSection({ moduleOptions }) {\n  const [customForms, setCustomForms] = useState([]);\n  const [loading, setLoading]         = useState(false);\n  const [drawerOpen, setDrawerOpen]   = useState(false);\n  const [editingForm, setEditingForm] = useState(null);\n\n  function loadForms() {\n    setLoading(true);\n    getCustomForms()\n      .then((data) => setCustomForms(data))\n      .catch((err) => message.error(err.message || 'Could not load custom forms'))\n      .finally(() => setLoading(false));\n  }\n\n  useEffect(() => { loadForms(); }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n  async function handleDelete(record) {\n    try {\n      await deleteCustomForm(record.id);\n      message.success('Custom form deleted');\n      loadForms();\n    } catch (err) {\n      message.error(err.message || 'Could not delete custom form');\n    }\n  }\n\n  const columns = [\n    {\n      title: 'Module', dataIndex: 'module', key: 'module',\n      render: (mod) => <Tag color=\"blue\">{mod}</Tag>,\n    },\n    {\n      title: 'Action Key', dataIndex: 'action', key: 'action',\n      render: (a) => <code className=\"fg-table-code\">{a}</code>,\n    },\n    {\n      title: 'Label', dataIndex: 'label', key: 'label',\n      render: (lbl) => <Text strong style={{ color: 'var(--color-text-heading)' }}>{lbl}</Text>,\n    },\n    {\n      title: 'Groups', dataIndex: 'groups', key: 'groups', align: 'center', width: 76,\n      render: (groups) => <Badge count={groups?.length ?? 0} showZero color=\"var(--color-brand)\" />,\n    },\n    {\n      title: '', key: 'actions', align: 'right', width: 100,\n      render: (_, record) => (\n        <Space size={4}>\n          <Tooltip title=\"Edit form\">\n            <Button type=\"text\" size=\"small\" icon={<EditOutlined />}\n              onClick={() => { setEditingForm(record); setDrawerOpen(true); }}\n              className=\"fg-action-btn\" />\n          </Tooltip>\n          <Popconfirm\n            title=\"Delete this custom form?\"\n            description=\"All configured groups will be lost.\"\n            onConfirm={() => handleDelete(record)}\n            okText=\"Delete\" okButtonProps={{ danger: true }}\n          >\n            <Tooltip title=\"Delete form\">\n              <Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} className=\"fg-action-btn\" />\n            </Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <div>\n      <div className=\"fg-tab-toolbar\" style={{ marginBottom: 12 }}>\n        <Button type=\"primary\" size=\"small\" icon={<PlusOutlined />}\n          onClick={() => { setEditingForm(null); setDrawerOpen(true); }}>\n          New Custom Form\n        </Button>\n      </div>\n\n      <Spin spinning={loading}>\n        <Table\n          rowKey={(r) => r.id ?? r.action}\n          dataSource={customForms}\n          columns={columns}\n          pagination={false}\n          className=\"fg-table\"\n          locale={{\n            emptyText: (\n              <Empty description=\"No custom forms yet. Click 'New Custom Form' to create one.\"\n                image={Empty.PRESENTED_IMAGE_SIMPLE} style={{ padding: '24px 0' }} />\n            ),\n          }}\n        />\n      </Spin>\n\n      <CustomFormDrawer\n        open={drawerOpen}\n        editingForm={editingForm}\n        moduleOptions={moduleOptions}\n        onClose={() => { setDrawerOpen(false); setEditingForm(null); }}\n        onSaved={() => { setDrawerOpen(false); setEditingForm(null); loadForms(); }}\n      />\n    </div>\n  );\n}\n\n// ── Main Section ──────────────────────────────────────────────────────────────\nexport default function FormGroupsSection() {\n  const [apiModules, setApiModules]         = useState([]);\n  const [modulesLoading, setModulesLoading] = useState(true);\n  const [moduleState, setModuleState]       = useState({});\n  const [activeModule, setActiveModule]     = useState('all');\n  const [drawerOpen, setDrawerOpen]         = useState(false);\n  const [editingGroup, setEditingGroup]     = useState(null);\n  const [gate, setGate]                     = useState(null); // { action, title, confirmLabel, danger, description }\n  const [topTab, setTopTab]                 = useState('module');\n  const [clients, setClients]               = useState([]);\n  const [scope, setScope]                   = useState({ clientId: '', region: '' });\n  const [previewOpen, setPreviewOpen]       = useState(false);\n  const [copiedGroup, setCopiedGroup]       = useState(null);\n\n  const tabs          = buildModuleTabs(apiModules);\n  const moduleOptions = apiModules.map((m) => ({ value: m.key, label: m.label }));\n\n  useEffect(() => {\n    getAvailableModules()\n      .then((raw) => {\n        const mods = normalizeModuleOptions(raw).map(({ value, label }) => ({ key: value, label }));\n        setApiModules(mods);\n        const built = buildModuleTabs(mods);\n        setModuleState(initModuleState(built));\n        loadModuleInto('all', built);\n      })\n      .catch(() => setApiModules([]))\n      .finally(() => setModulesLoading(false));\n  }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n  useEffect(() => {\n    getAdminClients({ limit: 200 })\n      .then(setClients)\n      .catch(() => setClients([]));\n  }, []);\n\n  function patchModule(key, patch) {\n    setModuleState((prev) => ({ ...prev, [key]: { ...prev[key], ...patch } }));\n  }\n\n  // ── Client scope ────────────────────────────────────────────────────────────\n  // The client picker scopes EVERY module, not just Jobs. The backend has always\n  // supported it for any module — read (clientId+region → clientId → region →\n  // module default) and write (an edit against a client with no config of its own\n  // forks the module default into a new client-scoped document). Only this screen\n  // hardcoded `=== 'jobs'`, so selecting a client while editing Submissions (or\n  // any other module) silently read AND wrote the module DEFAULT — the client's\n  // variant was never created, which is why a field hidden for one client kept\n  // rendering everywhere else.\n  //\n  // The merged \"All\" tab stays unscoped: it lists every module's groups at once,\n  // and scoping it would quietly hide every module the client has no document\n  // for. What you SEE on a tab is what a save writes to.\n  const scopeApplies = (key) => key !== 'all' && Boolean(scope.clientId || scope.region);\n  const scopeFor = (key) => (scopeApplies(key) ? scope : {});\n  // Identifies WHICH scope a tab's cached groups were loaded under.\n  const scopeKey = (key) => (scopeApplies(key) ? `${scope.clientId}|${scope.region}` : '');\n\n  function loadModuleInto(key, tabList) {\n    const currentTabs = tabList ?? tabs;\n    if (!currentTabs.find((t) => t.key === key)) return;\n    const loadedScope = scopeKey(key);\n    patchModule(key, { loading: true, error: '' });\n    getAdminFormGroups(key === 'all' ? '' : key, scopeFor(key))\n      .then((data) => patchModule(key, { groups: data, loading: false, loaded: true, scopeKey: loadedScope }))\n      .catch((err) => patchModule(key, { error: err.message || 'Could not load groups', loading: false }));\n  }\n\n  function loadModule(key) { loadModuleInto(key, null); }\n  function handleTabChange(key) {\n    setActiveModule(key);\n    // A tab loaded under a DIFFERENT scope must be refetched, or switching tabs\n    // with a client selected would show the previously cached default config.\n    if (!moduleState[key]?.loaded || moduleState[key]?.scopeKey !== scopeKey(key)) loadModule(key);\n  }\n  function openCreate() { setEditingGroup(null); setDrawerOpen(true); }\n  function openEdit(group) { setEditingGroup(group); setDrawerOpen(true); }\n  function closeDrawer() { setDrawerOpen(false); setEditingGroup(null); }\n\n  async function handleSaved() {\n    closeDrawer();\n    loadModule(activeModule);\n    if (activeModule !== 'all') loadModule('all');\n  }\n\n  async function handleDelete(id) {\n    try {\n      await deleteAdminFormGroup(id, activeScopeForSave());\n      message.success('Group deleted');\n      loadModule(activeModule);\n      if (activeModule !== 'all') loadModule('all');\n    } catch (err) {\n      message.error(err.message || 'Could not delete group');\n    }\n  }\n\n  // Persist a drag-and-drop group reorder: renumber each group's `order` from\n  // its new position and PUT only the ones that actually moved, so the rendered\n  // form (which sorts groups by `order`) matches the admin's arrangement.\n  async function handleReorderGroups(reordered) {\n    const changed = reordered\n      .map((g, index) => ({ g, index }))\n      .filter(({ g, index }) => Number(g.order ?? 0) !== index && g.id);\n    if (!changed.length) return;\n    try {\n      await Promise.all(changed.map(({ g, index }) =>\n        updateAdminFormGroup(g.id, { ...g, order: index }, activeScopeForSave(g.module || activeModule))));\n      message.success('Group order updated');\n      loadModule(activeModule);\n      if (activeModule !== 'all') loadModule('all');\n    } catch (err) {\n      message.error(err.message || 'Could not reorder groups');\n      loadModule(activeModule); // reload to discard the optimistic order\n    }\n  }\n\n  function openGate(action) { setGate(CONFIG_GATE_META[action]); }\n\n  function handleScopeChange(next) {\n    const merged = { ...scope, ...next };\n    setScope(merged);\n    // Reload whatever module is on screen under the NEW scope. Every other tab\n    // is marked stale so it refetches when opened (handleTabChange), instead of\n    // showing groups cached under the previous client.\n    setModuleState((prev) => {\n      const out = {};\n      for (const [key, state] of Object.entries(prev)) {\n        out[key] = key === activeModule ? state : { ...state, loaded: false };\n      }\n      return out;\n    });\n    if (activeModule === 'all') return;\n    const requestScope = (merged.clientId || merged.region) ? merged : {};\n    patchModule(activeModule, { loading: true, error: '' });\n    getAdminFormGroups(activeModule, requestScope)\n      .then((data) => patchModule(activeModule, {\n        groups: data,\n        loading: false,\n        loaded: true,\n        scopeKey: (merged.clientId || merged.region) ? `${merged.clientId}|${merged.region}` : '',\n      }))\n      .catch((err) => patchModule(activeModule, { error: err.message || 'Could not load scoped groups', loading: false }));\n  }\n\n  // Saves go to the scope the CURRENT tab is displaying, so an edit always lands\n  // in the config the admin is looking at. On the merged \"All\" tab (always shown\n  // unscoped) saves keep writing the module default, exactly as before.\n  function activeScopeForSave() {\n    return scopeFor(activeModule);\n  }\n\n  function copyGroupSettings(group) {\n    setCopiedGroup(JSON.parse(JSON.stringify(group)));\n    message.success(`Copied settings from ${group.label || group.name}`);\n  }\n\n  async function pasteGroupSettings(target) {\n    if (!copiedGroup) return;\n    try {\n      const payload = {\n        ...target,\n        addRow: copiedGroup.addRow ?? target.addRow,\n        payloadKey: copiedGroup.payloadKey ?? target.payloadKey,\n        fields: JSON.parse(JSON.stringify(copiedGroup.fields ?? [])),\n      };\n      await updateAdminFormGroup(target.id, payload, activeScopeForSave(target.module || activeModule));\n      message.success(`Pasted settings into ${target.label || target.name}`);\n      loadModule(activeModule);\n      if (activeModule !== 'all') loadModule('all');\n    } catch (err) {\n      message.error(err.message || 'Could not paste settings');\n    }\n  }\n\n  // Called after the OTP modal verifies + performs the action — reload so the\n  // table reflects the new (reset / restored / unchanged) config.\n  function handleGateVerified() {\n    setGate(null);\n    setModuleState(initModuleState(tabs));\n    loadModule(activeModule);\n    if (activeModule !== 'all') loadModule('all');\n  }\n\n  const tabItems = tabs.map(({ key, label, color }) => {\n    const state  = moduleState[key] ?? { groups: [], loading: false, loaded: false, error: '' };\n    const sorted = [...state.groups].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n    return {\n      key,\n      label: (\n        <span className=\"fg-tab-label\">\n          <span className=\"fg-tab-dot\" style={{ background: color }} />\n          {label}\n          <Badge count={state.groups.length} showZero color={color} size=\"small\" />\n        </span>\n      ),\n      children: (\n        <div className=\"fg-tab-content\">\n          {state.error && <Alert type=\"error\" showIcon message={state.error} style={{ marginBottom: 12 }} />}\n          <div className=\"fg-tab-toolbar\">\n            <Button type=\"primary\" size=\"small\" icon={<PlusOutlined />}\n              disabled={key === 'all'}\n              onClick={() => { setActiveModule(key); openCreate(); }}>\n              Add Group\n            </Button>\n          </div>\n          <Spin spinning={state.loading}>\n            <ModuleGroupsTable\n              groups={sorted}\n              onEdit={openEdit}\n              onDelete={handleDelete}\n              onCopy={copyGroupSettings}\n              onPaste={pasteGroupSettings}\n              canPaste={!!copiedGroup}\n              onReorder={key === 'all' ? undefined : handleReorderGroups}\n            />\n          </Spin>\n        </div>\n      ),\n    };\n  });\n\n  // The module the Preview drawer renders (never the merged \"All\" tab).\n  const previewModule = activeModule === 'all' ? (moduleOptions[0]?.value ?? 'jobs') : activeModule;\n  const previewLabel = tabs.find((t) => t.key === previewModule)?.label ?? previewModule;\n\n  const topTabItems = [\n    {\n      key: 'module',\n      label: 'Module Form',\n      children: (\n        <>\n          <AppCard>\n            <div className=\"fg-scope-toolbar\">\n              <div>\n                <div>\n                  <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                    Select a client to edit that client&apos;s field list for the module tab you are on — any module,\n                    not just Jobs. Leave blank for the default module config. Until the client has a config of its own\n                    you are shown the default; the first save copies it into a client-scoped config. A record rendered\n                    against a client — a Job, or a Submission through its job — uses that client&apos;s list here and\n                    falls back to the default when the client has none. The <b>All</b> tab always shows the defaults.\n                  </Text>\n                </div>\n                {scopeApplies(activeModule) && (\n                  <div style={{ marginTop: 6 }}>\n                    <Tag color=\"processing\">\n                      {`Editing ${clients.find((c) => (c._id ?? c.id) === scope.clientId)?.clientName ?? 'client'} config for ${activeModule}`}\n                    </Tag>\n                  </div>\n                )}\n              </div>\n              <Space wrap size={8}>\n                <Select\n                  size=\"small\"\n                  allowClear\n                  showSearch\n                  placeholder=\"Client\"\n                  style={{ width: 240 }}\n                  value={scope.clientId || undefined}\n                  optionFilterProp=\"label\"\n                  options={clients.map((c) => ({\n                    value: c._id ?? c.id,\n                    label: c.clientName ?? c.name ?? c.clientRefrenceId ?? c._id,\n                  })).filter((c) => c.value)}\n                  onChange={(clientId) => handleScopeChange({ clientId: clientId ?? '' })}\n                />\n                <Button size=\"small\" icon={<ReloadOutlined />} onClick={() => loadModule(activeModule)}>\n                  Reload\n                </Button>\n                {/* Preview renders the ACTIVE module's Add form under the selected\n                    client scope — the fastest way to confirm a client-scoped\n                    field list before saving. Disabled only on the merged tab,\n                    which is not a single module. */}\n                <Button size=\"small\" icon={<EyeOutlined />} disabled={activeModule === 'all'} onClick={() => setPreviewOpen(true)}>\n                  Preview\n                </Button>\n              </Space>\n            </div>\n          </AppCard>\n\n          <AppCard>\n            <Spin spinning={modulesLoading}>\n              <Tabs\n                activeKey={activeModule}\n                onChange={handleTabChange}\n                items={tabItems}\n                size=\"middle\"\n                className=\"fg-tabs\"\n              />\n            </Spin>\n          </AppCard>\n\n          <GroupDrawer\n            open={drawerOpen}\n            editingGroup={editingGroup}\n            defaultModule={activeModule === 'all' ? (moduleOptions[0]?.value ?? '') : activeModule}\n            moduleOptions={moduleOptions}\n            allGroupsByModule={Object.fromEntries(\n              Object.entries(moduleState)\n                .filter(([k]) => k !== 'all')\n                .map(([k, v]) => [k, v.groups ?? []])\n            )}\n            onClose={closeDrawer}\n            onSaved={handleSaved}\n            onSaveGroup={(payload, group) => group\n              ? updateAdminFormGroup(group.id, payload, activeScopeForSave(payload.module))\n              : createAdminFormGroup(payload, activeScopeForSave(payload.module))}\n          />\n\n          <Drawer\n            open={previewOpen}\n            onClose={() => setPreviewOpen(false)}\n            width=\"92vw\"\n            title={<span className=\"fg-drawer-title\"><EyeOutlined /> {previewLabel} Add Form Preview</span>}\n            classNames={{ body: 'fg-preview-body' }}\n            destroyOnClose\n          >\n            <AddFormV1\n              key={`${previewModule}-${scope.clientId}-${scope.region}`}\n              moduleName={previewModule}\n              clientId={scope.clientId}\n              region={scope.region}\n              cancelPath={`/${previewModule}`}\n              onSubmit={async () => message.info('Preview only. No record was created.')}\n              breadcrumbItems={[\n                { label: 'Admin' },\n                { label: 'Form Groups' },\n                { label: `${previewLabel} Preview` },\n              ]}\n            />\n          </Drawer>\n        </>\n      ),\n    },\n    {\n      key: 'custom',\n      label: 'Custom Form',\n      children: (\n        <AppCard>\n          <CustomFormsSection moduleOptions={moduleOptions} />\n        </AppCard>\n      ),\n    },\n    {\n      key: 'defaultFields',\n      label: 'Default Fields',\n      children: <DefaultFieldsPanel moduleOptions={moduleOptions} />,\n    },\n  ];\n\n  return (\n    <div className=\"fg-section\">\n      <AppCard\n        icon={<AppstoreAddOutlined />}\n        title=\"Form Groups\"\n        extra={\n          topTab === 'module' ? (\n            <Space size={8} wrap>\n              <Dropdown trigger={['click']} menu={{ items: [\n                { key: 'save', label: 'Save current as default', icon: <SaveOutlined />, onClick: () => openGate('save') },\n                { key: 'restore', label: 'Restore saved default', icon: <CloudDownloadOutlined />, onClick: () => openGate('restore') },\n                { type: 'divider' },\n                { key: 'reset', label: 'Reset all form groups', icon: <ReloadOutlined />, danger: true, onClick: () => openGate('reset') },\n              ] }}>\n                <Button size=\"small\" icon={<MoreOutlined />}>Workspace defaults</Button>\n              </Dropdown>\n              <Button type=\"primary\" size=\"small\" icon={<AppstoreAddOutlined />} onClick={openCreate}>\n                New Group\n              </Button>\n            </Space>\n          ) : null\n        }\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          <strong>Module Form</strong> — configure the default add/edit form for each module.{' '}\n          <strong>Custom Form</strong> — create standalone named forms (module + action) for\n          context-specific flows such as quick-add or popup forms.\n        </Text>\n      </AppCard>\n\n      <AppCard styles={{ body: { padding: '0 0' } }}>\n        <Tabs\n          activeKey={topTab}\n          onChange={setTopTab}\n          items={topTabItems}\n          size=\"middle\"\n          className=\"fg-top-tabs\"\n          tabBarStyle={{ padding: '0 16px', margin: 0 }}\n          destroyInactiveTabPane={false}\n        />\n      </AppCard>\n\n      <OtpGateModal\n        open={!!gate}\n        scope=\"formGroups\"\n        action={gate?.action}\n        title={gate?.title}\n        description={gate?.description}\n        confirmLabel={gate?.confirmLabel}\n        danger={gate?.danger}\n        onCancel={() => setGate(null)}\n        onVerified={handleGateVerified}\n      />\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n  Alert,\n  AutoComplete,\n  Badge,\n  Button,\n  Dropdown,\n  Drawer,\n  Empty,\n  Input,\n  Modal,\n  Select,\n  Space,\n  Spin,\n  Switch,\n  Table,\n  Tabs,\n  Tag,\n  Tooltip,\n  Typography,\n  message,\n} from 'antd';\nimport {\n  BgColorsOutlined,\n  CloudDownloadOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  EyeOutlined,\n  MergeCellsOutlined,\n  PlusOutlined,\n  ReloadOutlined,\n  SaveOutlined,\n  SettingOutlined,\n  MoreOutlined,\n  SearchOutlined,\n} from '@ant-design/icons';\nimport {\n  getAdminClients,\n  getAvailableModules,\n  getAdminFormGroups,\n  updateAdminFormGroup,\n  getDetailConfig,\n  saveDetailConfig,\n  getModuleDetailPreview,\n  getAvailableCollections,\n  getCollectionFields,\n  getDetailDefaults,\n  saveDetailDefaults,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\n// Read-only import on purpose — this screen only ever ASKS whether a field\n// carries a uniqueness rule. Authoring lives in Form Groups.\nimport { hasUniqueValidation, uniqueValidationOf } from './uniqueValidationConfig';\nimport {\n  getDefaults,\n  applyDefaults,\n  loadDetailDefaults,\n  BUILT_IN_DEFAULTS,\n} from '../../../services/detailDefaults';\nimport AppCard from '../../../components/cards/AppCard';\nimport OtpGateModal from '../../../components/admin/OtpGateModal';\nimport FieldValue from '../../../components/detail/fieldRenderEngine';\nimport { BUILT_IN_EMPTY_TEXTS } from '../../../components/detail/emptyText';\nimport { listTimeZones, tzLabel, tzShortLabel, formatAppDateTime } from '../../../services/timezone';\n\n// A fixed instant for the live format preview, so the sample never changes\n// while an admin is typing and cannot be mistaken for real data.\nconst SAMPLE_INSTANT = '2026-08-06T13:33:00.000Z';\nimport { recordValues, detailFieldLabel } from '../../../components/detail/detailVisibility';\nimport { CONDITION_OPERATORS, operatorNeedsValue } from '../../../components/form/conditionOperators';\nimport { RENDER_TYPES, DOCUMENT_MODES, TEXT_TRANSFORMS } from '../../../components/detail/renderConfig';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\n// Detail editor metadata changes rarely during an admin session. Reusing these\n// requests makes repeated field edits open immediately instead of refetching.\nlet collectionsRequest;\nconst collectionFieldsRequests = new Map();\n\nfunction loadCollectionsCached() {\n  if (!collectionsRequest) {\n    collectionsRequest = getAvailableCollections().catch((error) => {\n      collectionsRequest = undefined;\n      throw error;\n    });\n  }\n  return collectionsRequest;\n}\n\nfunction loadCollectionFieldsCached(collection) {\n  if (!collectionFieldsRequests.has(collection)) {\n    collectionFieldsRequests.set(collection, getCollectionFields(collection).catch((error) => {\n      collectionFieldsRequests.delete(collection);\n      throw error;\n    }));\n  }\n  return collectionFieldsRequests.get(collection);\n}\n\n// OTP-gated config actions for the detail-view config, mirroring Form Groups.\nconst CONFIG_GATE_META = {\n  reset:   { action: 'reset',   title: 'Reset all detail config',  confirmLabel: 'Reset All',       danger: true,\n    description: 'Clears every detail-view override for all modules in this workspace, so the detail view falls back to the plain form-group fields.' },\n  save:    { action: 'save',    title: 'Save current as default',  confirmLabel: 'Save Default',    danger: false,\n    description: 'Snapshots the current detail config for all modules as the saved default you can restore to later.' },\n  restore: { action: 'restore', title: 'Restore saved default',    confirmLabel: 'Restore Default', danger: true,\n    description: 'Replaces the current detail config for all modules with the last saved default.' },\n};\n\n\n// capitalize is a tri-state (*bool on the backend): unset → default behaviour,\n// true → force title-case, false → leave the raw value alone.\nconst CAP_OPTIONS = [\n  { label: 'Default',        value: 'default' },\n  { label: 'Title Case On',  value: 'on' },\n  { label: 'Off (raw text)', value: 'off' },\n];\nconst capToValue = (c) => (c === true ? 'on' : c === false ? 'off' : 'default');\nconst valueToCap = (v) => (v === 'on' ? true : v === 'off' ? false : undefined);\n\n// hideGroup lives on the SAME formGroupConfig group document the Form Groups\n// admin screen edits — there is no separate detail-side flag, so toggling it\n// here and toggling it in Form Groups always stay in sync automatically.\nconst truthy = (value) => value === true || value === 1 || value === '1';\n\n// Flatten the module's form-groups into a de-duplicated field universe that the\n// detail config overrides sit on top of.\nfunction flattenFields(groups) {\n  const seen = new Set();\n  const out = [];\n  for (const g of groups ?? []) {\n    for (const f of g.fields ?? []) {\n      if (!f.field || seen.has(f.field)) continue;\n      seen.add(f.field);\n      out.push({\n        key: f.field,\n        label: f.label ?? f.field,\n        type: f.type ?? 'text',\n        group: g.label ?? g.name,\n        // Carried through READ-ONLY. Detail Groups is display configuration; it\n        // never authors, edits or executes validation. Keeping `validations` on\n        // the flattened field is what lets this screen SHOW that a field is\n        // configured unique in Form Groups (and what stops a future flatten\n        // consumer from writing a field back without it). `key` above stays the\n        // raw form field key, so a label customised here can never change the\n        // key uniqueness is validated against.\n        validations: Array.isArray(f.validations) ? f.validations : [],\n        lookupDefaults: f.lookupCollection ? {\n          lookupCollection: f.lookupCollection,\n          displayField: f.displayField ?? '',\n          displayField2: f.displayField2 ?? '',\n          valueField: f.valueField || '_id',\n        } : {},\n      });\n    }\n  }\n  return out;\n}\n\n// Strip an override down to only the keys that actually change something, so the\n// saved config stays minimal (and a field with no overrides is dropped).\nfunction cleanFieldCfg(field, c) {\n  if (!c) return null;\n  const out = { field };\n  if (c.label) out.label = c.label;\n  if (c.prefix) out.prefix = c.prefix;\n  if (c.suffix) out.suffix = c.suffix;\n  if (c.color) out.color = c.color;\n  if (c.capitalize === true || c.capitalize === false) out.capitalize = c.capitalize;\n  if (c.hidden === true || c.hidden === false) out.hidden = c.hidden;\n  // Detail-only hide — kept separate from `hidden` (which the save flow mirrors\n  // onto the form field's `show`); this one never touches the form.\n  if (c.hideInDetail === true) out.hideInDetail = true;\n  // Hide-when-empty. `hideWhenEmpty` and `hideWhenEmptyInDetail` are ALIASES —\n  // components/detail/detailEmptiness.js ORs them — so the editor exposes one\n  // switch rather than two controls that fight over the same behaviour. The\n  // switch writes the canonical `hideWhenEmpty`; a config seeded with the\n  // longer alias is preserved verbatim while the switch stays on, so a\n  // wire-* seeder's document is never silently rewritten by an unrelated save.\n  if (c.hideWhenEmpty === true || c.hideWhenEmptyInDetail === true) {\n    out.hideWhenEmpty = true;\n    if (c.hideWhenEmptyInDetail === true) out.hideWhenEmptyInDetail = true;\n  }\n  // Zero-counts-as-empty for THIS field only (detailEmptiness.hidesWhenZero).\n  // Its own switch rather than a mode on the one above: it is self-sufficient\n  // (0 AND blank both hide), so an admin who wants \"only show the range end\n  // when there IS one\" flips one thing, and a field that opts in can never be\n  // half-configured by a hideWhenEmpty that was left off. Persisted only when\n  // ON, like every other key here.\n  if (c.hideWhenZero === true) out.hideWhenZero = true;\n  // Drop this field's sub-label inside a combined block (DetailViewV1.partLabel).\n  // Persisted only when ON, like every other key here.\n  if (c.hidePartLabel === true) out.hidePartLabel = true;\n  // Detail-only opt-out of the field's Conditional Label. Only persisted when\n  // switched ON, so a field that simply follows the rule stays absent from the\n  // saved config (same minimal-config rule as every other key here).\n  if (c.ignoreLabelWhenInDetail === true) out.ignoreLabelWhenInDetail = true;\n  // Detail-authored conditional labels. Half-typed rows are dropped rather than\n  // saved: a rule with no watch field or no label can never match anything, and\n  // keeping it would make the config lie about what is configured.\n  const labelWhen = (c.labelWhen ?? [])\n    .filter((rule) => String(rule?.field ?? '').trim() && String(rule?.label ?? '').trim())\n    .map((rule) => {\n      const cleaned = {\n        field: String(rule.field).trim(),\n        operator: rule.operator || 'eq',\n        label: String(rule.label).trim(),\n      };\n      // Unary operators (truthy/falsy/notEmpty) carry no value — drop any left\n      // behind by switching the operator, so it can't resurface later.\n      if (operatorNeedsValue(cleaned.operator) && rule.value != null && rule.value !== '') {\n        cleaned.value = String(rule.value);\n      }\n      return cleaned;\n    });\n  if (labelWhen.length) out.labelWhen = labelWhen;\n  // Render type is the single source of truth — migrate the legacy\n  // documentPreview / displayAs flags into it on save.\n  const rt = c.renderType\n    || (c.documentPreview ? 'document' : c.displayAs === 'tag' ? 'tag' : c.displayAs === 'text' ? 'text' : '');\n  if (rt && rt !== 'auto') out.renderType = rt;\n  const ro = {};\n  for (const [k, v] of Object.entries(c.renderOptions ?? {})) {\n    if (v !== undefined && v !== '' && v !== false) ro[k] = v;\n  }\n  if (Object.keys(ro).length) out.renderOptions = ro;\n  if (c.lookupCollection) {\n    out.lookupCollection = c.lookupCollection;\n    out.displayField = c.displayField || '';\n    if (c.displayField2) out.displayField2 = c.displayField2;\n    out.valueField = c.valueField || '_id';\n  }\n  return Object.keys(out).length > 1 ? out : null;\n}\n\nfunction cleanMerges(merges) {\n  return (merges ?? [])\n    .filter((m) => m.key && (m.fields ?? []).length)\n    .map((m) => {\n      const out = { key: m.key, label: m.label || m.key, fields: m.fields };\n      if (m.template) out.template = m.template;\n      if (m.valueMaps && Object.keys(m.valueMaps).length) out.valueMaps = m.valueMaps;\n      if (m.separator) out.separator = m.separator;\n      if (m.prefix) out.prefix = m.prefix;\n      if (m.suffix) out.suffix = m.suffix;\n      if (m.color) out.color = m.color;\n      if (m.capitalize === true || m.capitalize === false) out.capitalize = m.capitalize;\n      if (m.group) out.group = m.group;\n      if (m.hideSources === false) out.hideSources = false;\n      return out;\n    });\n}\n\nfunction fieldShowToHidden(field) {\n  return Number(field?.show ?? 1) === 0;\n}\n\nfunction syncGroupsWithDetailVisibility(groups, fieldCfg) {\n  const changed = [];\n  const nextGroups = (groups ?? []).map((group) => {\n    let groupChanged = false;\n    const fields = (group.fields ?? []).map((field) => {\n      const cfg = fieldCfg[field.field];\n      if (!cfg || cfg.hidden === undefined) return field;\n\n      const nextShow = cfg.hidden ? 0 : 1;\n      if (Number(field.show ?? 1) === nextShow) return field;\n\n      groupChanged = true;\n      return { ...field, show: nextShow };\n    });\n\n    const nextGroup = groupChanged ? { ...group, fields } : group;\n    if (groupChanged) changed.push(nextGroup);\n    return nextGroup;\n  });\n\n  return { nextGroups, changed };\n}\n\n// ── Colour input (text + native swatch) ─────────────────────────────────────────\nfunction ColorInput({ value, onChange }) {\n  return (\n    <Space.Compact style={{ width: '100%' }}>\n      <Input\n        size=\"small\"\n        placeholder=\"#0053a5\"\n        value={value ?? ''}\n        onChange={(e) => onChange(e.target.value)}\n        className=\"fg-mono-input\"\n        prefix={<BgColorsOutlined style={{ color: value || '#bbb' }} />}\n      />\n      <input\n        type=\"color\"\n        value={/^#[0-9a-f]{6}$/i.test(value ?? '') ? value : '#0053a5'}\n        onChange={(e) => onChange(e.target.value)}\n        style={{ width: 32, border: '1px solid #d9d9d9', borderLeft: 0, cursor: 'pointer', padding: 0 }}\n        aria-label=\"Pick colour\"\n      />\n    </Space.Compact>\n  );\n}\n\n// ── Conditional Label editor ─────────────────────────────────────────────────\n// Authors the rules that decide what this field is CALLED for a given record —\n// e.g. a submission's rate reads \"Employer Rate\" when contractType is C2C and\n// \"Candidate Rate\" otherwise. Pick the field to watch, the value to match, and\n// the label to show; rules are evaluated top-down and the first match wins, so\n// more than two states is just more rows.\n//\n// Only the displayed label changes — never the field key, the stored value, or\n// anything the add/edit forms do.\nfunction ConditionalLabelEditor({\n  fieldMeta, rules, ignore, fieldOptions, onChangeRules, onChangeIgnore,\n}) {\n  const list = Array.isArray(rules) ? rules : [];\n  const inherited = fieldMeta?.labelWhen;\n  // With no rules of its own the field follows the form's Conditional Label —\n  // show that, so \"inherited\" never looks like \"nothing configured\".\n  const isInheriting = list.length === 0 && Boolean(inherited?.field && inherited?.label);\n\n  const update = (index, patch) => onChangeRules(\n    list.map((rule, i) => (i === index ? { ...rule, ...patch } : rule)),\n  );\n  const remove = (index) => onChangeRules(list.filter((_, i) => i !== index));\n  const add = () => onChangeRules([...list, { field: '', operator: 'eq', value: '', label: '' }]);\n  // Start from the inherited rule so overriding is an edit, not a retype.\n  const addFromInherited = () => onChangeRules([{\n    field: inherited.field,\n    operator: inherited.operator ?? 'eq',\n    value: inherited.value ?? '',\n    label: inherited.label,\n  }]);\n\n  return (\n    <div className=\"fg-form-section\" style={{ marginTop: 14, marginBottom: 0 }}>\n      <div className=\"fg-form-section-label\">Conditional Label</div>\n      <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n        Show a different label depending on another field&apos;s value on the record.\n        The first matching rule wins; if none match, the label above (\n        <b>{fieldMeta?.label}</b>) is used. Detail view only — the add/edit forms are\n        unaffected.\n      </Text>\n\n      {isInheriting && (\n        <Alert\n          type=\"info\"\n          showIcon\n          style={{ marginBottom: 10 }}\n          message={`Inheriting from Form Groups: \"${inherited.label}\" when ${inherited.field} ${inherited.operator ?? 'eq'} ${inherited.value ?? ''}`}\n          description={(\n            <Button size=\"small\" type=\"link\" style={{ padding: 0 }} onClick={addFromInherited}>\n              Override it here\n            </Button>\n          )}\n        />\n      )}\n\n      {list.map((rule, i) => {\n        const needsValue = operatorNeedsValue(rule.operator);\n        return (\n          <div key={i} className=\"fg-field-meta-row\" style={{ marginBottom: 8, alignItems: 'flex-end' }}>\n            <div style={{ flex: 1.4 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>When field</Text>\n              {/* mode=\"tags\" + maxCount=1: pick a known field, or type a key the\n                  flattened list does not carry (e.g. a recordMeta key). */}\n              <Select\n                size=\"small\"\n                showSearch\n                mode=\"tags\"\n                maxCount={1}\n                style={{ width: '100%' }}\n                placeholder=\"e.g. contractType\"\n                optionFilterProp=\"label\"\n                options={fieldOptions}\n                value={rule.field ? [rule.field] : []}\n                onChange={(v) => update(i, { field: String(v[v.length - 1] ?? '').trim() })}\n              />\n            </div>\n            <div style={{ flex: 1 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>Is</Text>\n              <Select\n                size=\"small\"\n                style={{ width: '100%' }}\n                options={CONDITION_OPERATORS}\n                value={rule.operator ?? 'eq'}\n                onChange={(v) => update(i, { operator: v })}\n              />\n            </div>\n            {needsValue && (\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Value</Text>\n                <Input\n                  size=\"small\"\n                  placeholder=\"C2C\"\n                  value={rule.value ?? ''}\n                  onChange={(e) => update(i, { value: e.target.value })}\n                  className=\"fg-mono-input\"\n                />\n              </div>\n            )}\n            <div style={{ flex: 1.2 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>Show label</Text>\n              <Input\n                size=\"small\"\n                placeholder=\"Employer Rate\"\n                value={rule.label ?? ''}\n                onChange={(e) => update(i, { label: e.target.value })}\n              />\n            </div>\n            <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} onClick={() => remove(i)} />\n          </div>\n        );\n      })}\n\n      <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} onClick={add}>\n        Add rule\n      </Button>\n\n      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n        <Switch size=\"small\" checked={!ignore} onChange={(v) => onChangeIgnore(!v)} />\n        <Text style={{ fontSize: 13 }}>Use conditional labels in the detail view</Text>\n      </div>\n      <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 4 }}>\n        Turn off to always show the static label here, ignoring both the rules above and\n        the one from Form Groups.\n      </Text>\n    </div>\n  );\n}\n\n// ── Field Override Drawer ────────────────────────────────────────────────────────\n// moduleFieldOptions = every field on the module, offered as the \"When field\"\n// choices for conditional labels. Distinct from the local `fieldOptions` below,\n// which lists the columns of a LOOKUP collection.\nfunction FieldOverrideDrawer({ open, fieldMeta, value, moduleFieldOptions, onClose, onSave }) {\n  // The parent keys this component per field, so it remounts on every open —\n  // a useState initializer seeds the draft (no prop→state effect needed).\n  const [draft, setDraft] = useState(() => ({ ...(value ?? {}) }));\n  const [collections, setCollections] = useState([]);\n  const [collFields, setCollFields] = useState([]);\n  const [activeSection, setActiveSection] = useState('display');\n\n  useEffect(() => {\n    if (!open || activeSection !== 'lookup') return undefined;\n    let cancelled = false;\n    loadCollectionsCached()\n      .then((c) => { if (!cancelled) setCollections(c.map((x) => (typeof x === 'string' ? x : x.name ?? x.value ?? '')).filter(Boolean)); })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, [activeSection, open]);\n\n  useEffect(() => {\n    if (!open || activeSection !== 'lookup' || !draft.lookupCollection) return undefined;\n    let cancelled = false;\n    loadCollectionFieldsCached(draft.lookupCollection)\n      .then((f) => { if (!cancelled) setCollFields(f.map((x) => (typeof x === 'string' ? x : x.value ?? x.field ?? x.label ?? '')).filter(Boolean)); })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, [activeSection, open, draft.lookupCollection]);\n\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n  // Clearing collFields in the handler (not an effect) keeps suggestions fresh.\n  const setCollection = (v) => { setCollFields([]); setDraft((d) => ({ ...d, lookupCollection: v })); };\n  const collOptions = collections.map((c) => ({ value: c }));\n  const fieldOptions = collFields.map((c) => ({ value: c }));\n\n  // Render type drives the detail view. Derive from legacy flags for old configs.\n  const renderOpts = draft.renderOptions ?? {};\n  const setOpt = (k, v) => set('renderOptions', { ...renderOpts, [k]: v || undefined });\n  const effectiveRenderType = draft.renderType\n    || (draft.documentPreview ? 'document' : draft.displayAs === 'tag' ? 'tag' : draft.displayAs === 'text' ? 'text' : 'auto');\n  const isTagLike = ['tag', 'tags', 'chip', 'badge'].includes(effectiveRenderType);\n  const isTransformable = ['text', 'tag', 'tags', 'chip', 'badge', 'link', 'email', 'phone'].includes(effectiveRenderType);\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      width={760}\n      centered\n      destroyOnClose\n      maskClosable={false}\n      className=\"fg-editor-modal detail-field-editor-modal\"\n      title={\n        <span className=\"fg-drawer-title\">\n          <EditOutlined /> {fieldMeta?.label}\n          <code className=\"fg-field-key-hint\" style={{ marginLeft: 8 }}>{fieldMeta?.key}</code>\n        </span>\n      }\n      footer={\n        <div className=\"fg-drawer-footer\">\n          <Button onClick={onClose}>Cancel</Button>\n          <Button type=\"primary\" icon={<SaveOutlined />} onClick={() => onSave(draft)}>Apply</Button>\n        </div>\n      }\n    >\n      <div className=\"detail-editor-nav\" role=\"tablist\" aria-label=\"Field settings\">\n        <Button type={activeSection === 'display' ? 'primary' : 'text'} onClick={() => setActiveSection('display')}>\n          Display\n        </Button>\n        <Button type={activeSection === 'lookup' ? 'primary' : 'text'} onClick={() => setActiveSection('lookup')}>\n          Reference lookup\n        </Button>\n      </div>\n\n      {activeSection === 'display' && <div className=\"fg-form-section detail-editor-panel\">\n        <div className=\"fg-form-section-label\">Display</div>\n\n        <div style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Label override</Text>\n          <Input size=\"small\" placeholder={fieldMeta?.label} value={draft.label ?? ''} onChange={(e) => set('label', e.target.value)} />\n        </div>\n\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Prefix</Text>\n            <Input size=\"small\" placeholder=\"e.g. $\" value={draft.prefix ?? ''} onChange={(e) => set('prefix', e.target.value)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Suffix</Text>\n            <Input size=\"small\" placeholder=\"e.g. yrs\" value={draft.suffix ?? ''} onChange={(e) => set('suffix', e.target.value)} />\n          </div>\n        </div>\n\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Colour</Text>\n            <ColorInput value={draft.color} onChange={(v) => set('color', v)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Capitalize</Text>\n            <Select\n              size=\"small\"\n              style={{ width: '100%' }}\n              options={CAP_OPTIONS}\n              value={capToValue(draft.capitalize)}\n              onChange={(v) => set('capitalize', valueToCap(v))}\n            />\n          </div>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={!!draft.hidden} onChange={(v) => set('hidden', v)} />\n          <Text style={{ fontSize: 13 }}>Hide this field everywhere (detail view and the add/edit form)</Text>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>\n          <Switch size=\"small\" checked={!!draft.hideInDetail} onChange={(v) => set('hideInDetail', v)} />\n          <Text style={{ fontSize: 13 }}>Hide in the detail view only (keep it in the add/edit form)</Text>\n        </div>\n\n        {/* One switch, both stored keys — see cleanFieldCfg for why. Turning it OFF\n            clears the alias too, otherwise the field would keep hiding itself with\n            no switch left showing that it does. */}\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>\n          <Switch\n            size=\"small\"\n            checked={!!draft.hideWhenEmpty || !!draft.hideWhenEmptyInDetail}\n            onChange={(v) => setDraft((d) => ({\n              ...d,\n              hideWhenEmpty: v,\n              hideWhenEmptyInDetail: v ? d.hideWhenEmptyInDetail : false,\n            }))}\n          />\n          <Text style={{ fontSize: 13 }}>\n            Hide when empty — drop this field (and a combined block left with nothing\n            to show) instead of printing a heading over a dash\n          </Text>\n        </div>\n\n        {/* Combined blocks name each part with what is left of its own label\n            after the block's shared words come off (\"Notice Period Unit\" under\n            \"Notice Period\" → \"Unit\"). That disambiguates a start/end range but\n            is noise on a qualifier whose value already says what it is, which\n            is how \"12 Days\" came out as \"12 · Unit Days\". */}\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>\n          <Switch\n            size=\"small\"\n            checked={!!draft.hidePartLabel}\n            onChange={(v) => set('hidePartLabel', v)}\n          />\n          <Text style={{ fontSize: 13 }}>\n            Hide this part&apos;s label inside a combined block — show just the\n            value (e.g. &ldquo;12 Days&rdquo;, not &ldquo;12 · Unit Days&rdquo;)\n          </Text>\n        </div>\n\n        {/* Zero counts as empty, for this field only. Deliberately NOT global:\n            a rate of 0, a count of 0 and a 0% are real values everywhere else,\n            so only the field an admin points at here treats 0 as nothing. */}\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>\n          <Switch\n            size=\"small\"\n            checked={!!draft.hideWhenZero}\n            onChange={(v) => set('hideWhenZero', v)}\n          />\n          <Text style={{ fontSize: 13 }}>\n            Treat 0 as empty — hide this field when its value is 0 or blank (e.g. the\n            end of a rate range that was never filled in, so &quot;92 - 0&quot; shows as\n            just &quot;92&quot;)\n          </Text>\n        </div>\n\n        <ConditionalLabelEditor\n          fieldMeta={fieldMeta}\n          rules={draft.labelWhen}\n          ignore={draft.ignoreLabelWhenInDetail}\n          fieldOptions={moduleFieldOptions}\n          onChangeRules={(v) => set('labelWhen', v)}\n          onChangeIgnore={(v) => set('ignoreLabelWhenInDetail', v)}\n        />\n\n        <div style={{ marginTop: 14 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Render Type</Text>\n          <Select\n            size=\"small\"\n            style={{ width: '100%' }}\n            value={effectiveRenderType}\n            onChange={(v) => set('renderType', v)}\n            options={RENDER_TYPES}\n          />\n          <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 4 }}>\n            How this field is displayed in the detail view — entirely config-driven.\n          </Text>\n        </div>\n\n        {/* Per-field empty text. Overrides the tenant-wide wording (Display\n            Defaults → Empty-value text by kind) for THIS field only, e.g.\n            \"No LinkedIn profile added\" rather than a generic \"Not provided\". */}\n        <div style={{ marginTop: 12 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Empty text</Text>\n          <Input\n            size=\"small\"\n            placeholder={BUILT_IN_EMPTY_TEXTS[effectiveRenderType] ?? BUILT_IN_EMPTY_TEXTS.default}\n            value={renderOpts.emptyText ?? ''}\n            onChange={(e) => setOpt('emptyText', e.target.value)}\n          />\n          <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 4 }}>\n            What to show when this particular field is empty — for example &quot;No LinkedIn\n            profile added&quot;. Leave blank to use the wording set for its type in Display\n            Defaults.\n          </Text>\n        </div>\n\n        {/* Render-type-specific options */}\n        {effectiveRenderType === 'document' && (\n          <div style={{ marginTop: 12 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Document mode</Text>\n            <Select\n              size=\"small\"\n              style={{ width: '100%' }}\n              value={renderOpts.documentMode || 'preview'}\n              onChange={(v) => setOpt('documentMode', v)}\n              options={DOCUMENT_MODES}\n            />\n          </div>\n        )}\n        {isTransformable && (\n          <div style={{ marginTop: 12 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Text transform</Text>\n            <Select\n              size=\"small\"\n              style={{ width: '100%' }}\n              value={renderOpts.textTransform || 'none'}\n              onChange={(v) => setOpt('textTransform', v === 'none' ? undefined : v)}\n              options={TEXT_TRANSFORMS}\n            />\n          </div>\n        )}\n        {isTagLike && (\n          <div style={{ marginTop: 12 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Tag colour</Text>\n            <Input size=\"small\" placeholder=\"geekblue / #0053a5\" value={renderOpts.tagColor ?? ''} onChange={(e) => setOpt('tagColor', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        )}\n        {effectiveRenderType === 'date' && (\n          <div style={{ marginTop: 12 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Date format (dayjs tokens)</Text>\n            <Input size=\"small\" placeholder=\"DD/MM/YYYY\" value={renderOpts.dateFormat ?? ''} onChange={(e) => setOpt('dateFormat', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        )}\n        {/* Phone — which key on the RECORD carries the dialling code. Without this\n            the renderer can only guess from sibling names (countryCode /\n            phoneCountryCode / …) and then falls back to the tenant default, which\n            is exactly how every candidate came out displayed as \"+1\". Dotted paths\n            are allowed, e.g. contact.countryCode. */}\n        {effectiveRenderType === 'phone' && (\n          <div style={{ marginTop: 12 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Country-code field on the record</Text>\n            <Input\n              size=\"small\"\n              placeholder=\"e.g. countryCode or contact.countryCode\"\n              value={renderOpts.countryCodeField ?? ''}\n              onChange={(e) => setOpt('countryCodeField', e.target.value)}\n              className=\"fg-mono-input\"\n            />\n            <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 4 }}>\n              Leave blank to auto-detect a sibling code key. Nothing is prefixed when the\n              record carries no code and no global fallback is set.\n            </Text>\n          </div>\n        )}\n        {(effectiveRenderType === 'currency' || effectiveRenderType === 'budget') && (\n          <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n            <div style={{ flex: 1 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>Currency symbol</Text>\n              <Input size=\"small\" placeholder=\"$ / ₹ / £\" value={renderOpts.currencySymbol ?? ''} onChange={(e) => setOpt('currencySymbol', e.target.value)} />\n            </div>\n            {effectiveRenderType === 'budget' && (\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Unit (e.g. Monthly)</Text>\n                <Input size=\"small\" placeholder=\"Monthly\" value={renderOpts.unit ?? ''} onChange={(e) => setOpt('unit', e.target.value)} />\n              </div>\n            )}\n          </div>\n        )}\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={!!renderOpts.showEmpty} onChange={(v) => setOpt('showEmpty', v)} />\n          <Text style={{ fontSize: 13 }}>Show empty values</Text>\n        </div>\n      </div>}\n\n      {activeSection === 'lookup' && <div className=\"fg-form-section detail-editor-panel\">\n        <div className=\"fg-form-section-label\">Reference Lookup (id → name)</div>\n        <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n          For fields that store a foreign-key id. The detail API resolves the name from the\n          target collection and returns <code>{'{ id, value }'}</code>.\n        </Text>\n\n        <div style={{ marginBottom: 10 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Collection</Text>\n          <AutoComplete\n            size=\"small\"\n            style={{ width: '100%' }}\n            options={collOptions}\n            placeholder=\"e.g. vendors\"\n            value={draft.lookupCollection ?? ''}\n            onChange={setCollection}\n            filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n            className=\"fg-mono-input\"\n          />\n        </div>\n\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Display Field</Text>\n            <AutoComplete\n              size=\"small\"\n              style={{ width: '100%' }}\n              options={fieldOptions}\n              placeholder=\"e.g. vendorCompanyName\"\n              value={draft.displayField ?? ''}\n              onChange={(v) => set('displayField', v)}\n              filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n              className=\"fg-mono-input\"\n            />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Display Field 2</Text>\n            <AutoComplete\n              size=\"small\"\n              style={{ width: '100%' }}\n              options={fieldOptions}\n              placeholder=\"e.g. lastName\"\n              value={draft.displayField2 ?? ''}\n              onChange={(v) => set('displayField2', v)}\n              filterOption={(input, opt) => (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())}\n              className=\"fg-mono-input\"\n            />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Value Field (FK)</Text>\n            <Input size=\"small\" placeholder=\"_id\" value={draft.valueField ?? ''} onChange={(e) => set('valueField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n      </div>}\n    </Modal>\n  );\n}\n\n// ── Merge Drawer ──────────────────────────────────────────────────────────────\n// flattenValueMaps turns the saved { field: { raw: display } } shape into flat\n// editor rows; buildValueMaps does the reverse.\nfunction flattenValueMaps(valueMaps) {\n  const rows = [];\n  Object.entries(valueMaps ?? {}).forEach(([field, mapping]) => {\n    Object.entries(mapping ?? {}).forEach(([from, to]) => rows.push({ field, from, to }));\n  });\n  return rows;\n}\n\nfunction buildValueMaps(rows) {\n  const out = {};\n  for (const r of rows ?? []) {\n    if (!r.field || !r.from) continue;\n    out[r.field] = { ...(out[r.field] ?? {}), [r.from]: r.to ?? '' };\n  }\n  return out;\n}\n\nfunction MergeDrawer({ open, merge, fieldOptions, groupOptions, onClose, onSave }) {\n  // Parent keys this per merge → remounts on open, so the initializer seeds it.\n  const [draft, setDraft] = useState(() => ({\n    key: '', label: '', fields: [], separator: ' - ', template: '',\n    prefix: '', suffix: '', color: '', capitalize: undefined,\n    group: '', hideSources: true,\n    ...(merge ?? {}),\n    mapRows: flattenValueMaps(merge?.valueMaps),\n  }));\n\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n  const updateRow = (i, patch) => setDraft((d) => {\n    const rows = [...(d.mapRows ?? [])];\n    rows[i] = { ...rows[i], ...patch };\n    return { ...d, mapRows: rows };\n  });\n  const removeRow = (i) => setDraft((d) => ({ ...d, mapRows: (d.mapRows ?? []).filter((_, idx) => idx !== i) }));\n  const addRow = () => setDraft((d) => ({\n    ...d, mapRows: [...(d.mapRows ?? []), { field: d.fields?.[0] ?? '', from: '', to: '' }],\n  }));\n\n  const handleSave = () => {\n    if (!draft.key?.trim()) return message.error('A merge key is required');\n    if (!/^[a-z0-9_]+$/.test(draft.key)) return message.error('Key: lowercase letters, numbers, underscores only');\n    if (!(draft.fields ?? []).length) return message.error('Pick at least one source field');\n    const { mapRows, ...rest } = draft;\n    onSave({ ...rest, valueMaps: buildValueMaps(mapRows) });\n  };\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      width={820}\n      centered\n      destroyOnClose\n      maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><MergeCellsOutlined /> {merge ? 'Edit Merged Field' : 'New Merged Field'}</span>}\n      footer={\n        <div className=\"fg-drawer-footer\">\n          <Button onClick={onClose}>Cancel</Button>\n          <Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button>\n        </div>\n      }\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-form-section-label\">Merged Field</div>\n\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Key</Text>\n            <Input size=\"small\" placeholder=\"experience_range\" value={draft.key ?? ''} onChange={(e) => set('key', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Label</Text>\n            <Input size=\"small\" placeholder=\"Experience\" value={draft.label ?? ''} onChange={(e) => set('label', e.target.value)} />\n          </div>\n        </div>\n\n        <div style={{ margin: '12px 0' }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Source fields (combined in order)</Text>\n          <Select\n            mode=\"multiple\"\n            size=\"small\"\n            style={{ width: '100%' }}\n            placeholder=\"Pick fields to combine\"\n            options={fieldOptions}\n            value={draft.fields ?? []}\n            onChange={(v) => set('fields', v)}\n            optionFilterProp=\"label\"\n          />\n        </div>\n\n        {/* Template — full control over layout & literals. Overrides Separator. */}\n        <div style={{ margin: '12px 0' }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>\n            Template <span style={{ color: '#94a3b8' }}>(optional — overrides separator)</span>\n          </Text>\n          <Input.TextArea\n            rows={2}\n            value={draft.template ?? ''}\n            onChange={(e) => set('template', e.target.value)}\n            placeholder=\"{clientBudgetStart} - {clientBudgetEnd} {clientBudgetCurrency}/{clientBudgetUnit}\"\n            className=\"fg-mono-input\"\n          />\n          <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 4 }}>\n            A field with no value takes its joining punctuation with it, so a rate\n            with no end shows <code>80 $/hour</code> rather than <code>80 - $/hour</code>.\n            That only applies to pure connectors (<code>-</code> <code>/</code>{' '}\n            <code>,</code> <code>|</code> <code>:</code> and spaces) — literal words\n            you type, like <code>Rate:</code>, are always kept.\n            Put spacing in the template itself, never inside a Value Map: a mapped\n            value like <code>&quot; hour&quot;</code> adds a gap the template cannot\n            see, which is how <code>$/hour</code> came out as <code>$ / hour</code>.\n          </Text>\n          {(draft.fields ?? []).length > 0 && (\n            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 6 }}>\n              {(draft.fields ?? []).map((f) => (\n                <Tag\n                  key={f}\n                  color=\"blue\"\n                  style={{ cursor: 'pointer', margin: 0 }}\n                  onClick={() => set('template', `${draft.template ?? ''}{${f}}`)}\n                >\n                  + {`{${f}}`}\n                </Tag>\n              ))}\n            </div>\n          )}\n          <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 4 }}>\n            Click a chip to insert a field. Everything else (spaces, “/”, “-”) is kept literally.\n            Result e.g. <code>60 - 80 $/Monthly</code>.\n          </Text>\n        </div>\n\n        {/* Per-field value maps — e.g. Monthly → mon. Unmapped values pass through. */}\n        <div style={{ margin: '12px 0' }}>\n          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Value mappings (raw → display)</Text>\n            <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} disabled={!(draft.fields ?? []).length} onClick={addRow}>\n              Add\n            </Button>\n          </div>\n          {(draft.mapRows ?? []).map((row, i) => (\n            <div key={i} style={{ display: 'flex', gap: 6, marginTop: 6, alignItems: 'center' }}>\n              <Select\n                size=\"small\"\n                style={{ flex: 1.4 }}\n                placeholder=\"field\"\n                value={row.field || undefined}\n                options={(draft.fields ?? []).map((f) => ({ value: f, label: f }))}\n                onChange={(v) => updateRow(i, { field: v })}\n              />\n              <Input size=\"small\" style={{ flex: 1 }} placeholder=\"Monthly\" value={row.from} onChange={(e) => updateRow(i, { from: e.target.value })} />\n              <span style={{ color: '#94a3b8' }}>→</span>\n              <Input size=\"small\" style={{ flex: 1 }} placeholder=\"mon\" value={row.to} onChange={(e) => updateRow(i, { to: e.target.value })} />\n              <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} onClick={() => removeRow(i)} />\n            </div>\n          ))}\n          {!(draft.mapRows ?? []).length && (\n            <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 4 }}>\n              e.g. Monthly → mon, Daily → day, Yearly → yr. Unmapped values stay as-is.\n            </Text>\n          )}\n        </div>\n\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Separator <span style={{ color: '#94a3b8' }}>(used when no template)</span></Text>\n            <Input size=\"small\" placeholder=\" - \" value={draft.separator ?? ''} onChange={(e) => set('separator', e.target.value)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Place in group</Text>\n            <Select\n              size=\"small\"\n              style={{ width: '100%' }}\n              allowClear\n              placeholder=\"(first source's group)\"\n              options={groupOptions}\n              value={draft.group || undefined}\n              onChange={(v) => set('group', v ?? '')}\n            />\n          </div>\n        </div>\n\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Prefix</Text>\n            <Input size=\"small\" value={draft.prefix ?? ''} onChange={(e) => set('prefix', e.target.value)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Suffix</Text>\n            <Input size=\"small\" placeholder=\"yrs\" value={draft.suffix ?? ''} onChange={(e) => set('suffix', e.target.value)} />\n          </div>\n        </div>\n\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Colour</Text>\n            <ColorInput value={draft.color} onChange={(v) => set('color', v)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Capitalize</Text>\n            <Select size=\"small\" style={{ width: '100%' }} options={CAP_OPTIONS} value={capToValue(draft.capitalize)} onChange={(v) => set('capitalize', valueToCap(v))} />\n          </div>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={draft.hideSources !== false} onChange={(v) => set('hideSources', v)} />\n          <Text style={{ fontSize: 13 }}>Hide the source fields after merging</Text>\n        </div>\n      </div>\n    </Modal>\n  );\n}\n\n// ── Preview Drawer ──────────────────────────────────────────────────────────────\nfunction PreviewDrawer({ open, module, onClose }) {\n  const [recordId, setRecordId] = useState('');\n  const [groups, setGroups] = useState([]);\n  // Flattened record values, so the preview can resolve Conditional Labels the\n  // same way the real detail view does.\n  const [previewValues, setPreviewValues] = useState({});\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState('');\n\n  const load = async () => {\n    if (!recordId.trim()) return message.warning('Enter a record _id to preview');\n    setLoading(true); setError('');\n    try {\n      // Load saved display defaults alongside the record so the preview renders\n      // with the configured S3 base / date format / labels.\n      const [data] = await Promise.all([\n        getModuleDetailPreview(module, recordId.trim()),\n        loadDetailDefaults(),\n      ]);\n      setGroups(data);\n      setPreviewValues(recordValues(data));\n      if (!data.length) setError('No groups returned — check the id and module.');\n    } catch (e) {\n      setError(e?.message || 'Failed to load preview');\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <Drawer\n      open={open}\n      onClose={onClose}\n      width={520}\n      title={<span className=\"fg-drawer-title\"><EyeOutlined /> Detail Preview — {module}</span>}\n      classNames={{ header: 'fg-drawer-header', body: 'fg-drawer-body' }}\n    >\n      <Space.Compact style={{ width: '100%', marginBottom: 14 }}>\n        <Input\n          placeholder=\"Paste a record _id (24-char ObjectId)\"\n          value={recordId}\n          onChange={(e) => setRecordId(e.target.value)}\n          onPressEnter={load}\n          className=\"fg-mono-input\"\n        />\n        <Button type=\"primary\" loading={loading} onClick={load}>Load</Button>\n      </Space.Compact>\n\n      {error && <Alert type=\"warning\" showIcon message={error} style={{ marginBottom: 12 }} />}\n\n      <Spin spinning={loading}>\n        {groups.map((g) => (\n          <div key={g.id ?? g.name} style={{ marginBottom: 18 }}>\n            <Text strong style={{ display: 'block', marginBottom: 8 }}>{g.label ?? g.name}</Text>\n            {(g.fields ?? []).filter((f) => f.show === undefined || f.show === 1).map((f) => (\n              <div key={f.field} style={{ display: 'flex', gap: 10, padding: '4px 0', borderBottom: '1px dashed #eee' }}>\n                {/* Resolve the Conditional Label against the previewed record,\n                    exactly as DetailViewV1 does, so the preview cannot show a\n                    different label than the real detail view. */}\n                <Text type=\"secondary\" style={{ fontSize: 12, width: 150, flexShrink: 0 }}>\n                  {detailFieldLabel(f, previewValues)}\n                </Text>\n                <FieldValue field={f} />\n              </div>\n            ))}\n          </div>\n        ))}\n        {!loading && !groups.length && !error && (\n          <Empty description=\"Load a record to preview its detail view.\" image={Empty.PRESENTED_IMAGE_SIMPLE} />\n        )}\n      </Spin>\n    </Drawer>\n  );\n}\n\n// The empty-text kinds surfaced in the Display Defaults drawer. Keys match the\n// render types resolved by components/detail/fieldRenderEngine, and the\n// placeholders are the built-in sentences from components/detail/emptyText.js,\n// so the admin sees exactly what they would get by leaving the box blank.\n// Region profiles offered in Display Defaults. These are KEYS into each form\n// group's `regionRules` map — adding a market is a config edit, not a code one,\n// so this list only has to name the ones an admin can pick today.\nconst REGION_OPTIONS = [\n  { label: 'Common (no region profile)', value: '' },\n  { label: 'United States (US)', value: 'US' },\n  { label: 'United Kingdom (UK)', value: 'UK' },\n  { label: 'India (IND)', value: 'IND' },\n];\n\nconst EMPTY_TEXT_KINDS = [\n  { key: 'default',  label: 'Any value',   placeholder: BUILT_IN_EMPTY_TEXTS.default },\n  { key: 'group',    label: 'Empty group', placeholder: 'No <group name> added' },\n  { key: 'document', label: 'Document',    placeholder: BUILT_IN_EMPTY_TEXTS.document },\n  { key: 'date',     label: 'Date',        placeholder: BUILT_IN_EMPTY_TEXTS.date },\n  { key: 'phone',    label: 'Phone',       placeholder: BUILT_IN_EMPTY_TEXTS.phone },\n  { key: 'email',    label: 'Email',       placeholder: BUILT_IN_EMPTY_TEXTS.email },\n  { key: 'link',     label: 'Link',        placeholder: BUILT_IN_EMPTY_TEXTS.link },\n  { key: 'skills',   label: 'Skills/tags', placeholder: BUILT_IN_EMPTY_TEXTS.skills },\n];\n\n// ── Display Defaults Drawer ─────────────────────────────────────────────────────\n// Tenant-wide settings that used to be hard-coded in fileUtils.js / FieldValue.jsx.\nfunction pickDefaults(d) {\n  const out = {};\n  ['s3BaseUrl', 'dateFormat', 'dateTimeFormat', 'phoneFormat', 'booleanTrueLabel', 'booleanFalseLabel', 'emptyPlaceholder', 'separator'].forEach((k) => {\n    if (d?.[k] !== undefined && d?.[k] !== '') out[k] = d[k];\n  });\n  // phoneCountryCode is the one default where EMPTY is a deliberate setting\n  // (\"prefix nothing unless the record says so\"), not \"unset — keep the\n  // built-in\", so it is picked up whenever the server sent it as a string.\n  if (typeof d?.phoneCountryCode === 'string') out.phoneCountryCode = d.phoneCountryCode;\n  if (Array.isArray(d?.documentNameOrder) && d.documentNameOrder.length) out.documentNameOrder = d.documentNameOrder;\n  if (d?.emptyTexts && typeof d.emptyTexts === 'object') out.emptyTexts = { ...d.emptyTexts };\n  // Like phoneCountryCode, EMPTY is a real setting here (\"use the viewer's own\n  // zone\"), so it is picked up whenever the server sent it as a string.\n  if (typeof d?.timeZone === 'string') out.timeZone = d.timeZone;\n  if (typeof d?.region === 'string') out.region = d.region;\n  // A saved `false` is a real setting (\"never print the zone\"), so it is picked\n  // up whenever it is present as a boolean, not only when truthy.\n  if (typeof d?.showTimeZoneLabel === 'boolean') out.showTimeZoneLabel = d.showTimeZoneLabel;\n  return out;\n}\n\nfunction DefaultsDrawer({ open, onClose }) {\n  const [draft, setDraft] = useState(() => ({ ...getDefaults() }));\n  const [saving, setSaving] = useState(false);\n\n  useEffect(() => {\n    if (!open) return undefined;\n    let cancelled = false;\n    getDetailDefaults()\n      .then((d) => { if (!cancelled) setDraft((prev) => ({ ...prev, ...pickDefaults(d) })); })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, [open]);\n\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  // Built once: enumerating and offsetting every IANA zone is not free, and the\n  // list only changes when the alias map does.\n  const timeZoneOptions = useMemo(\n    () => listTimeZones(draft).map(({ value, label }) => ({ value, label })),\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [draft.timeZoneAliases],\n  );\n\n  const handleSave = async () => {\n    setSaving(true);\n    try {\n      const payload = {\n        s3BaseUrl: (draft.s3BaseUrl ?? '').trim(),\n        dateFormat: (draft.dateFormat ?? '').trim(),\n        dateTimeFormat: (draft.dateTimeFormat ?? '').trim(),\n        showTimeZoneLabel: draft.showTimeZoneLabel !== false,\n        phoneFormat: (draft.phoneFormat ?? '').trim(),\n        // Always sent, including as '' — that is how an admin CLEARS a global\n        // dial code they previously set.\n        phoneCountryCode: (draft.phoneCountryCode ?? '').trim(),\n        booleanTrueLabel: draft.booleanTrueLabel ?? '',\n        booleanFalseLabel: draft.booleanFalseLabel ?? '',\n        emptyPlaceholder: draft.emptyPlaceholder ?? '',\n        emptyTexts: draft.emptyTexts ?? {},\n        // Always sent, including as '' — that is how an admin clears the tenant\n        // zone and returns everyone to their own browser clock.\n        timeZone: (draft.timeZone ?? '').trim(),\n        // Always sent, including as '' — that is how an admin clears the region\n        // and returns every group to its own defaults.\n        region: (draft.region ?? '').trim(),\n        separator: draft.separator ?? '',\n        documentNameOrder: Array.isArray(draft.documentNameOrder) ? draft.documentNameOrder : [],\n      };\n      await saveDetailDefaults(payload);\n      applyDefaults(payload); // live-update the singleton so detail views reflect immediately\n      message.success('Display defaults saved');\n      onClose();\n    } catch (e) {\n      message.error(e?.message || 'Could not save defaults');\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  const labelStyle = { fontSize: 12, display: 'block', marginBottom: 4 };\n\n  return (\n    <Drawer\n      open={open}\n      onClose={onClose}\n      width={460}\n      title={<span className=\"fg-drawer-title\"><SettingOutlined /> Display Defaults</span>}\n      classNames={{ header: 'fg-drawer-header', body: 'fg-drawer-body' }}\n      footer={\n        <div className=\"fg-drawer-footer\">\n          <Button onClick={() => setDraft({ ...BUILT_IN_DEFAULTS })}>Reset to built-in</Button>\n          <Button type=\"primary\" icon={<SaveOutlined />} loading={saving} onClick={handleSave}>Save Defaults</Button>\n        </div>\n      }\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-form-section-label\">Documents / Files</div>\n        <div style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>S3 Base URL</Text>\n          <Input size=\"small\" placeholder={BUILT_IN_DEFAULTS.s3BaseUrl} value={draft.s3BaseUrl ?? ''} onChange={(e) => set('s3BaseUrl', e.target.value)} className=\"fg-mono-input\" />\n        </div>\n        <div>\n          <Text type=\"secondary\" style={labelStyle}>Document name priority (first match wins)</Text>\n          <Select\n            mode=\"tags\"\n            size=\"small\"\n            style={{ width: '100%' }}\n            placeholder=\"name, documentName, uploadedFileName…\"\n            value={draft.documentNameOrder ?? []}\n            onChange={(v) => set('documentNameOrder', v)}\n          />\n        </div>\n      </div>\n\n      <div className=\"fg-form-section\">\n        <div className=\"fg-form-section-label\">Value Formatting</div>\n        <div style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>Date format (dayjs tokens)</Text>\n          <Input size=\"small\" placeholder=\"DD MMM YYYY\" value={draft.dateFormat ?? ''} onChange={(e) => set('dateFormat', e.target.value)} className=\"fg-mono-input\" />\n        </div>\n        <div style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>Phone format (digit groups, e.g. 3-3-4 → 999-878-3413)</Text>\n          <Input size=\"small\" placeholder=\"3-3-4\" value={draft.phoneFormat ?? ''} onChange={(e) => set('phoneFormat', e.target.value)} className=\"fg-mono-input\" />\n        </div>\n        <div style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>Fallback country code (leave blank — recommended)</Text>\n          <Input size=\"small\" placeholder=\"blank = no code\" value={draft.phoneCountryCode ?? ''} onChange={(e) => set('phoneCountryCode', e.target.value)} className=\"fg-mono-input\" />\n          <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 4 }}>\n            Used ONLY when a record carries no dial code of its own. It ships empty on\n            purpose: a number that never stated a country is shown without one, rather\n            than being stamped with a code someone assumed. Set it only if this tenant\n            really is single-country.\n          </Text>\n        </div>\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={labelStyle}>Boolean — true</Text>\n            <Input size=\"small\" placeholder=\"Yes\" value={draft.booleanTrueLabel ?? ''} onChange={(e) => set('booleanTrueLabel', e.target.value)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={labelStyle}>Boolean — false</Text>\n            <Input size=\"small\" placeholder=\"No\" value={draft.booleanFalseLabel ?? ''} onChange={(e) => set('booleanFalseLabel', e.target.value)} />\n          </div>\n        </div>\n        {/* The region profile. It carries no logic of its own: it selects which\n            `regionRules` block each form group applies, so switching it\n            re-renders every affected component with no code change. Used today\n            for whether a candidate may submit an in-progress qualification\n            (normal in the US/UK, not in India) and whether a lower degree is\n            mandatory alongside a higher one. */}\n        <div style={{ marginTop: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>Region</Text>\n          <Select\n            size=\"small\"\n            allowClear\n            style={{ width: '100%' }}\n            placeholder=\"Common — every group uses its own defaults\"\n            value={draft.region || undefined}\n            onChange={(v) => set('region', v ?? '')}\n            options={REGION_OPTIONS}\n            getPopupContainer={() => document.body}\n          />\n          <Text type=\"secondary\" style={{ ...labelStyle, marginTop: 4 }}>\n            Different markets expect different things. Choosing one here switches the rules\n            that have been set up for it — for example whether someone may be put forward\n            while still studying, which is normal in the US and UK but not in India. Leave\n            it on Common if the same rules suit everyone.\n          </Text>\n        </div>\n\n        {/* The application's clock. Every date-time is RENDERED in this zone and\n            every datetime/time INPUT is interpreted as being in it — so a team\n            spread across locations reads and enters the same wall-clock value.\n            Plain calendar dates (date of birth, expiry, education dates) are\n            deliberately NOT converted; see services/timezone.js. */}\n        <div style={{ marginTop: 12 }}>\n          <Text type=\"secondary\" style={labelStyle}>Application time zone</Text>\n          <Select\n            size=\"small\"\n            showSearch\n            allowClear\n            style={{ width: '100%' }}\n            placeholder=\"Use each viewer's own browser time zone\"\n            optionFilterProp=\"label\"\n            value={draft.timeZone || undefined}\n            onChange={(v) => set('timeZone', v ?? '')}\n            options={timeZoneOptions}\n            getPopupContainer={() => document.body}\n          />\n          <Text type=\"secondary\" style={{ ...labelStyle, marginTop: 4 }}>\n            {draft.timeZone\n              ? `Everyone now sees and enters times in ${tzLabel({ ...draft, timeZone: draft.timeZone })}, whichever country they are working from — so an interview slot means the same thing to all of them. Plain dates such as a date of birth are not affected.`\n              : 'Not set — everyone sees times in their own computer\\u2019s time zone, so the same interview can appear at two different times to two people.'}\n          </Text>\n        </div>\n\n        {/* Two formats, not one. A date of birth has no time and no zone —\n            printing \"07:03 PM IST\" after one claims a precision the value does\n            not have. A created/updated stamp is a moment, so it carries both. */}\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={labelStyle}>Date and time format</Text>\n            <Input size=\"small\" placeholder=\"MMM DD, YYYY | hh:mm A\"\n              value={draft.dateTimeFormat ?? ''}\n              onChange={(e) => set('dateTimeFormat', e.target.value)} />\n            <Text type=\"secondary\" style={{ ...labelStyle, marginTop: 4 }}>\n              Used wherever a moment is shown — when a record was created or last\n              changed, activity entries, interview slots. Example:\n              <b> {formatAppDateTime(SAMPLE_INSTANT, { ...draft, showTimeZoneLabel: draft.showTimeZoneLabel !== false }) || '—'}</b>\n            </Text>\n          </div>\n          <div style={{ flex: '0 0 200px' }}>\n            <Text type=\"secondary\" style={labelStyle}>Show the time zone</Text>\n            <div>\n              <Switch\n                size=\"small\"\n                checked={draft.showTimeZoneLabel !== false}\n                onChange={(v) => set('showTimeZoneLabel', v)}\n                checkedChildren=\"Shown\"\n                unCheckedChildren=\"Hidden\"\n              />\n            </div>\n            <Text type=\"secondary\" style={{ ...labelStyle, marginTop: 4 }}>\n              Adds a small &quot;{tzShortLabel(draft)}&quot; after every time, so nobody has to\n              guess whose clock it is. Only times get it — plain dates never do.\n            </Text>\n          </div>\n        </div>\n\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={labelStyle}>Empty placeholder</Text>\n            <Input size=\"small\" placeholder=\"-\" value={draft.emptyPlaceholder ?? ''} onChange={(e) => set('emptyPlaceholder', e.target.value)} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={labelStyle}>Object / array separator</Text>\n            <Input size=\"small\" placeholder=\" - \" value={draft.separator ?? ''} onChange={(e) => set('separator', e.target.value)} />\n          </div>\n        </div>\n\n        {/* Per-kind empty text. \"Empty placeholder\" above can only ever say ONE\n            thing, so every absence read as the same bare \"-\" — indistinguishable\n            from a rendering fault. These say what is actually missing. Each is\n            OPTIONAL: left blank, the built-in sentence for that kind is used. */}\n        <div style={{ marginTop: 18 }}>\n          <Text strong style={{ fontSize: 12 }}>Empty-value text by kind</Text>\n          <Text type=\"secondary\" style={{ ...labelStyle, marginTop: 2 }}>\n            What people see where there is nothing to show. A dash tells them nothing —\n            &quot;No experience added&quot; tells them the record is fine and that part is\n            simply empty. Leave a box blank to use the built-in wording; a single field or\n            section can still say something different.\n          </Text>\n          <div className=\"fg-field-meta-row\" style={{ marginTop: 8, flexWrap: 'wrap' }}>\n            {EMPTY_TEXT_KINDS.map(({ key, label, placeholder }) => (\n              <div key={key} style={{ flex: '1 1 190px' }}>\n                <Text type=\"secondary\" style={labelStyle}>{label}</Text>\n                <Input\n                  size=\"small\"\n                  placeholder={placeholder}\n                  value={draft.emptyTexts?.[key] ?? ''}\n                  onChange={(e) => set('emptyTexts', { ...(draft.emptyTexts ?? {}), [key]: e.target.value })}\n                />\n              </div>\n            ))}\n          </div>\n        </div>\n      </div>\n    </Drawer>\n  );\n}\n\n// ── Main Section ──────────────────────────────────────────────────────────────\nexport default function DetailGroupsSection() {\n  const [modules, setModules] = useState([]);\n  const [modulesLoading, setModulesLoading] = useState(true);\n  const [selected, setSelected] = useState('');\n\n  const [groups, setGroups] = useState([]); // raw form-groups (listed like FormGroups)\n  const [fields, setFields] = useState([]); // flattened — used for merge field options\n  const [groupNames, setGroupNames] = useState([]);\n  const [fieldCfg, setFieldCfg] = useState({}); // { [fieldKey]: override }\n  const [merges, setMerges] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState('');\n  const [saving, setSaving] = useState(false);\n\n  const [editField, setEditField] = useState(null); // field meta being edited\n  const [mergeDraft, setMergeDraft] = useState(null); // { index, merge } | { index:null }\n  const [previewOpen, setPreviewOpen] = useState(false);\n  const [defaultsOpen, setDefaultsOpen] = useState(false);\n  const [gate, setGate] = useState(null); // OTP-gated config action meta\n  const [refreshKey, setRefreshKey] = useState(0);\n  const [query, setQuery] = useState('');\n  // Client scope, mirroring the Form Groups admin: blank edits the module\n  // default, a client edits that client's own detail config.\n  const [clients, setClients] = useState([]);\n  const [clientId, setClientId] = useState('');\n  // Which scope the LOADED config actually came from. When a client is selected\n  // but has no config of its own the backend serves the default, and the admin\n  // needs to know that what they see is inherited, not client-specific.\n  const [loadedClientId, setLoadedClientId] = useState('');\n  const [groupHideSaving, setGroupHideSaving] = useState({}); // { [groupId]: true } while a hideGroup PUT is in flight\n\n  function openGate(action) { setGate(CONFIG_GATE_META[action]); }\n\n  // Both visibility flags live on the formGroupConfig group document itself\n  // (the same one Form Groups edits) — flipping either writes straight through\n  // via updateAdminFormGroup. `hideGroup` hides the group EVERYWHERE (forms +\n  // detail, shared with Form Groups); `hideGroupInDetail` hides it from the\n  // DETAIL VIEW only, leaving the add/edit forms untouched — the group-level\n  // counterpart of the per-field \"Hide in the detail view only\" override.\n  async function toggleGroupFlag(group, flag, value, messages) {\n    const previous = groups;\n    setGroups((cur) => cur.map((g) => (g.id === group.id ? { ...g, [flag]: value } : g)));\n    setGroupHideSaving((cur) => ({ ...cur, [`${group.id}:${flag}`]: true }));\n    try {\n      await updateAdminFormGroup(group.id, { ...group, [flag]: value });\n      message.success(value ? messages.on : messages.off);\n    } catch (e) {\n      setGroups(previous);\n      message.error(e?.message || 'Could not update group visibility');\n    } finally {\n      setGroupHideSaving((cur) => {\n        const next = { ...cur };\n        delete next[`${group.id}:${flag}`];\n        return next;\n      });\n    }\n  }\n\n  // Free-text counterpart of toggleGroupFlag, for the group's empty-state text.\n  // Kept separate because it saves on BLUR rather than on every keystroke —\n  // one PUT per character would hammer the API and race itself.\n  async function saveGroupText(group, key, value) {\n    const next = String(value ?? '').trim();\n    if (next === String(group?.[key] ?? '').trim()) return;\n    const previous = groups;\n    setGroups((cur) => cur.map((g) => (g.id === group.id ? { ...g, [key]: next } : g)));\n    try {\n      await updateAdminFormGroup(group.id, { ...group, [key]: next });\n      message.success('Empty text saved');\n    } catch (e) {\n      setGroups(previous);\n      message.error(e?.message || 'Could not save empty text');\n    }\n  }\n\n  const toggleGroupHidden = (group, hidden) => toggleGroupFlag(group, 'hideGroup', hidden, {\n    on: 'Group hidden from add/edit forms and the detail view',\n    off: 'Group is visible again',\n  });\n\n  const toggleGroupDetailHidden = (group, hidden) => toggleGroupFlag(group, 'hideGroupInDetail', hidden, {\n    on: 'Group hidden from the detail view only — add/edit forms keep it',\n    off: 'Group is visible in the detail view again',\n  });\n\n  // The detail view honours the same Show Condition the forms do, so a group\n  // that no longer applies to the record is hidden instead of showing a stale\n  // value. This switch opts a group out of that, keeping it always visible.\n  const toggleGroupIgnoreShowIf = (group, ignore) => toggleGroupFlag(group, 'ignoreShowIfInDetail', ignore, {\n    on: 'Group always shows in the detail view, even when its Show Condition fails',\n    off: 'Group follows its Show Condition in the detail view',\n  });\n\n  // After the OTP modal verifies + performs the action, re-fetch the selected\n  // module's config (bump refreshKey, which the loader effect depends on).\n  function handleGateVerified() {\n    setGate(null);\n    setRefreshKey((k) => k + 1);\n  }\n\n  useEffect(() => {\n    getAdminClients({ limit: 200 })\n      .then(setClients)\n      .catch(() => setClients([]));\n  }, []);\n\n  useEffect(() => {\n    getAvailableModules()\n      .then((raw) => {\n        const mods = normalizeModuleOptions(raw).map(({ value, label }) => ({ key: value, label }));\n        setModules(mods);\n        if (mods.length) setSelected(mods[0].key);\n      })\n      .catch(() => setModules([]))\n      .finally(() => setModulesLoading(false));\n  }, []);\n\n  useEffect(() => {\n    if (!selected) return;\n    let cancelled = false;\n    (async () => {\n      setLoading(true); setError('');\n      try {\n        const [groupData, cfg] = await Promise.all([\n          getAdminFormGroups(selected, { clientId }),\n          getDetailConfig(selected, { clientId }),\n        ]);\n        if (cancelled) return;\n        setLoadedClientId(cfg.clientId ?? '');\n        setGroups(groupData ?? []);\n        setFields(flattenFields(groupData));\n        setGroupNames((groupData ?? []).map((g) => ({ value: g.name, label: g.label ?? g.name })));\n        const map = {};\n        (cfg.fields ?? []).forEach((fc) => { map[fc.field] = fc; });\n        setFieldCfg(map);\n        setMerges(cfg.merges ?? []);\n      } catch (e) {\n        if (!cancelled) setError(e?.message || 'Failed to load configuration');\n      } finally {\n        if (!cancelled) setLoading(false);\n      }\n    })();\n    return () => { cancelled = true; };\n  }, [selected, refreshKey, clientId]);\n\n  const fieldOptions = useMemo(() => fields.map((f) => ({ value: f.key, label: `${f.label} (${f.key})` })), [fields]);\n\n  async function handleSave() {\n    setSaving(true);\n    try {\n      const fieldsPayload = Object.entries(fieldCfg).map(([k, c]) => cleanFieldCfg(k, c)).filter(Boolean);\n      const { nextGroups, changed } = syncGroupsWithDetailVisibility(groups, fieldCfg);\n      await saveDetailConfig({ module: selected, fields: fieldsPayload, merges: cleanMerges(merges), clientId });\n      if (changed.length) {\n        setGroups(nextGroups);\n        setFields(flattenFields(nextGroups));\n        setGroupNames(nextGroups.map((g) => ({ value: g.name, label: g.label ?? g.name })));\n      }\n      // Saving against a client CREATES that client's config on first write, so\n      // reflect the new scope instead of leaving the \"inherited\" hint up.\n      setLoadedClientId(clientId);\n      message.success(clientId\n        ? 'Detail view configuration saved for this client'\n        : 'Detail view configuration saved');\n    } catch (e) {\n      message.error(e?.message || 'Could not save configuration');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  function applyFieldOverride(draft) {\n    setFieldCfg((prev) => ({ ...prev, [editField.key]: { ...draft, field: editField.key } }));\n    setEditField(null);\n  }\n\n  function clearFieldOverride(key) {\n    setFieldCfg((prev) => {\n      const next = { ...prev };\n      delete next[key];\n      return next;\n    });\n  }\n\n  function applyMerge(draft) {\n    setMerges((prev) => {\n      const next = [...prev];\n      if (mergeDraft.index === null) next.push(draft);\n      else next[mergeDraft.index] = draft;\n      return next;\n    });\n    setMergeDraft(null);\n  }\n\n  // Quick inline hidden toggle\n  function toggleHidden(key, hidden) {\n    setFieldCfg((prev) => {\n      const cur = prev[key] ?? { field: key };\n      return { ...prev, [key]: { ...cur, hidden } };\n    });\n  }\n\n  const overrideTags = (cfg) => {\n    if (!cfg) return null;\n    const tags = [];\n    if (cfg.label) tags.push(<Tag key=\"l\" color=\"blue\">label</Tag>);\n    if (cfg.prefix || cfg.suffix) tags.push(<Tag key=\"ps\" color=\"geekblue\">±fix</Tag>);\n    if (cfg.color) tags.push(<Tag key=\"c\" color={cfg.color}>colour</Tag>);\n    if (cfg.capitalize === true) tags.push(<Tag key=\"cap\" color=\"purple\">Title</Tag>);\n    if (cfg.capitalize === false) tags.push(<Tag key=\"cap\" color=\"default\">raw</Tag>);\n    if (cfg.lookupCollection) tags.push(<Tag key=\"lk\" color=\"volcano\">lookup: {cfg.lookupCollection}</Tag>);\n    if (cfg.ignoreLabelWhenInDetail) tags.push(<Tag key=\"ilw\" color=\"default\">static label</Tag>);\n    const rt = cfg.renderType || (cfg.documentPreview ? 'document' : cfg.displayAs);\n    if (rt && rt !== 'auto') tags.push(<Tag key=\"rt\" color=\"cyan\">{rt}</Tag>);\n    return tags.length ? tags : <Text type=\"secondary\" style={{ fontSize: 12 }}>—</Text>;\n  };\n\n  // Groups listed exactly like FormGroupsSection (same getAdminFormGroups API),\n  // each row expandable to its fields — but the per-field action configures the\n  // DETAIL override instead of editing the group.\n  const groupColumns = [\n    {\n      title: 'Group',\n      dataIndex: 'label',\n      key: 'label',\n      render: (label, g) => <Text strong style={{ color: 'var(--color-text-heading)' }}>{label ?? g.name}</Text>,\n    },\n    { title: 'Key', dataIndex: 'name', key: 'name', render: (name) => <code className=\"fg-table-code\">{name}</code> },\n    { title: 'Order', dataIndex: 'order', key: 'order', width: 72, align: 'center', render: (v) => <span className=\"fg-order-cell\">{v ?? 0}</span> },\n    {\n      title: 'Fields', dataIndex: 'fields', key: 'fields', width: 76, align: 'center',\n      render: (f) => <Badge count={f?.length ?? 0} showZero color=\"var(--color-brand)\" />,\n    },\n    {\n      title: 'Customized', key: 'cust', width: 100, align: 'center',\n      render: (_, g) => {\n        const n = (g.fields ?? []).filter((f) => fieldCfg[f.field]).length;\n        return n ? <Tag color=\"blue\" style={{ margin: 0 }}>{n}</Tag> : <Text type=\"secondary\" style={{ fontSize: 12 }}>—</Text>;\n      },\n    },\n    {\n      title: 'Hide Group', key: 'hideGroup', width: 110, align: 'center',\n      render: (_, g) => (\n        <Tooltip title={truthy(g.hideGroup) ? 'Hidden from add/edit forms AND the detail view' : 'Visible in both — same flag as Form Groups'}>\n          <Switch\n            size=\"small\"\n            checkedChildren=\"Hide\"\n            unCheckedChildren=\"Show\"\n            checked={truthy(g.hideGroup)}\n            loading={Boolean(groupHideSaving[`${g.id}:hideGroup`])}\n            onChange={(v) => toggleGroupHidden(g, v)}\n          />\n        </Tooltip>\n      ),\n    },\n    {\n      title: 'Show Condition', key: 'ignoreShowIfInDetail', width: 130, align: 'center',\n      render: (_, g) => {\n        const cond = g.showIf?.field\n          ? `${g.showIf.field} ${g.showIf.operator ?? 'eq'} ${g.showIf.value ?? ''}`.trim()\n          : null;\n        if (!cond) return <Text type=\"secondary\" style={{ fontSize: 12 }}>—</Text>;\n        return (\n          <Tooltip title={truthy(g.ignoreShowIfInDetail)\n            ? `Always shown, ignoring \"${cond}\"`\n            : `Hidden in the detail view unless \"${cond}\"`}>\n            <Switch\n              size=\"small\"\n              checkedChildren=\"Always\"\n              unCheckedChildren=\"Follow\"\n              checked={truthy(g.ignoreShowIfInDetail)}\n              loading={Boolean(groupHideSaving[`${g.id}:ignoreShowIfInDetail`])}\n              onChange={(v) => toggleGroupIgnoreShowIf(g, v)}\n            />\n          </Tooltip>\n        );\n      },\n    },\n    {\n      // Only meaningful for a repeatable group: it is what shows INSTEAD of an\n      // empty card when the record has no rows. A non-addRow group renders its\n      // fields' own empty texts, so the column stays blank for those.\n      title: 'Empty Text', key: 'emptyText', width: 220,\n      render: (_, g) => (truthy(g.addRow) ? (\n        <Input\n          size=\"small\"\n          defaultValue={g.emptyText ?? ''}\n          placeholder={`No ${String(g.label ?? g.name ?? '').toLowerCase()} added`}\n          onBlur={(e) => saveGroupText(g, 'emptyText', e.target.value)}\n          onPressEnter={(e) => e.currentTarget.blur()}\n        />\n      ) : <Text type=\"secondary\" style={{ fontSize: 12 }}>—</Text>),\n    },\n    {\n      title: 'Hide in Detail', key: 'hideGroupInDetail', width: 120, align: 'center',\n      render: (_, g) => (\n        <Tooltip title={truthy(g.hideGroupInDetail)\n          ? 'Hidden from the DETAIL VIEW only — the add/edit forms still show this group'\n          : 'Shown in the detail view. Hide here to remove it from the detail view without touching the forms'}>\n          <Switch\n            size=\"small\"\n            checkedChildren=\"Hide\"\n            unCheckedChildren=\"Show\"\n            checked={truthy(g.hideGroupInDetail)}\n            loading={Boolean(groupHideSaving[`${g.id}:hideGroupInDetail`])}\n            onChange={(v) => toggleGroupDetailHidden(g, v)}\n          />\n        </Tooltip>\n      ),\n    },\n  ];\n\n  // Expanded rows: the fields inside a group, each with its detail-override\n  // controls (visibility toggle, customize, reset).\n  const renderGroupFields = (group) => {\n    const fieldsArr = group.fields ?? [];\n    if (!fieldsArr.length) {\n      return <Text type=\"secondary\" style={{ fontSize: 12 }}>No fields in this group.</Text>;\n    }\n    return (\n      <div className=\"fg-expanded-fields\">\n        {fieldsArr.map((f) => {\n          const cfg = fieldCfg[f.field];\n          const hidden = cfg?.hidden ?? fieldShowToHidden(f);\n          const meta = {\n            key: f.field,\n            label: f.label ?? f.field,\n            type: f.type ?? 'text',\n            group: group.label ?? group.name,\n            // Carried through so the drawer can show the Conditional Label rule\n            // and offer the detail-only opt-out.\n            labelWhen: f.labelWhen,\n            lookupDefaults: f.lookupCollection ? {\n              lookupCollection: f.lookupCollection,\n              displayField: f.displayField ?? '',\n              displayField2: f.displayField2 ?? '',\n              valueField: f.valueField || '_id',\n            } : {},\n          };\n          return (\n            <div key={f.field} className=\"fg-field-row\">\n              <div className=\"fg-field-row-info\">\n                <span className=\"fg-field-row-label\">{cfg?.label || f.label}</span>\n                <span className=\"fg-field-row-key\">{f.field}</span>\n                <span className=\"fg-field-row-type\">({f.type})</span>\n                {/* Read-only marker for a uniqueness rule authored in Form\n                    Groups. It is informational ONLY: Detail Groups never runs a\n                    uniqueness check, never edits the rule, and nothing saved\n                    here can override or remove it. */}\n                {hasUniqueValidation(f) && (\n                  <Tooltip title={(() => {\n                    const rule = uniqueValidationOf(f);\n                    const stored = rule?.value?.collectionField || f.payloadKey || f.field;\n                    return `Configured unique in Form Groups on \"${stored}\"`\n                      + `${rule?.message ? ` — \"${rule.message}\"` : ''}. Edit it there; this screen is display only.`;\n                  })()}>\n                    <Tag color=\"magenta\" style={{ marginLeft: 6 }}>Unique</Tag>\n                  </Tooltip>\n                )}\n                {/* Effective conditional labels: rules authored here win over\n                    the inherited Form Groups rule, matching detailLabelRules. */}\n                {(() => {\n                  const own = (cfg?.labelWhen ?? []).filter((r) => r?.field && r?.label);\n                  const rules = own.length\n                    ? own\n                    : (f.labelWhen?.field && f.labelWhen?.label ? [f.labelWhen] : []);\n                  if (!rules.length) return null;\n                  const ignored = cfg?.ignoreLabelWhenInDetail;\n                  const describe = (r) => `\"${r.label}\" when ${r.field} ${r.operator ?? 'eq'} ${r.value ?? ''}`.trim();\n                  return (\n                    <Tooltip title={ignored\n                      ? `Conditional labels ignored here — the detail view always shows \"${f.label}\"`\n                      : `${own.length ? 'Set in Detail Groups' : 'Inherited from Form Groups'} — ${rules.map(describe).join('; ')}`}>\n                      <Tag color={ignored ? 'default' : own.length ? 'purple' : 'blue'} style={{ marginLeft: 6 }}>\n                        ⇄ {rules[0].label}{rules.length > 1 ? ` +${rules.length - 1}` : ''}\n                      </Tag>\n                    </Tooltip>\n                  );\n                })()}\n              </div>\n              <div className=\"fg-field-row-flags\">{overrideTags(cfg)}</div>\n              <Space size={4} style={{ marginLeft: 'auto' }}>\n                <Tooltip title={hidden ? 'Hidden in form and detail view' : 'Visible'}>\n                  <Switch size=\"small\" checkedChildren=\"Hide\" unCheckedChildren=\"Show\" checked={hidden} onChange={(v) => toggleHidden(f.field, v)} />\n                </Tooltip>\n                <Tooltip title=\"Customize field\"><Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => setEditField(meta)} /></Tooltip>\n                {cfg && <Tooltip title=\"Reset to default\"><Button type=\"text\" size=\"small\" danger icon={<ReloadOutlined />} onClick={() => clearFieldOverride(f.field)} /></Tooltip>}\n              </Space>\n            </div>\n          );\n        })}\n      </div>\n    );\n  };\n\n  const sortedGroups = useMemo(() => {\n    const needle = query.trim().toLowerCase();\n    return [...groups]\n      .filter((group) => !needle || [\n        group.label,\n        group.name,\n        ...(group.fields ?? []).flatMap((field) => [field.label, field.field, field.type]),\n      ].some((value) => String(value ?? '').toLowerCase().includes(needle)))\n      .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n  }, [groups, query]);\n\n  const mergeColumns = [\n    { title: 'Label', dataIndex: 'label', key: 'label', render: (l, r) => <span><Text strong>{l || r.key}</Text><span className=\"fg-field-key-hint\">{r.key}</span></span> },\n    { title: 'Fields', dataIndex: 'fields', key: 'fields', render: (f) => <Space size={4} wrap>{(f ?? []).map((x) => <Tag key={x}>{x}</Tag>)}</Space> },\n    {\n      title: 'Format', key: 'sep', width: 220,\n      render: (_, r) => <code className=\"fg-table-code\">{r.template?.trim() ? r.template : `join: ${r.separator || ' - '}`}</code>,\n    },\n    {\n      title: '',\n      key: 'actions',\n      width: 90,\n      align: 'right',\n      render: (_, r, i) => (\n        <Space size={4}>\n          <Tooltip title=\"Edit\"><Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => setMergeDraft({ index: i, merge: r })} /></Tooltip>\n          <Tooltip title=\"Delete\"><Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} onClick={() => setMerges((prev) => prev.filter((_, idx) => idx !== i))} /></Tooltip>\n        </Space>\n      ),\n    },\n  ];\n\n  const moduleTabs = modules.map((m) => ({ key: m.key, label: m.label }));\n\n  return (\n    <div className=\"fg-section\">\n      <AppCard\n        icon={<BgColorsOutlined />}\n        title=\"Detail Groups\"\n        extra={\n          <Space size={8} wrap>\n            <Dropdown trigger={['click']} menu={{ items: [\n              { key: 'save', label: 'Save current as default', icon: <SaveOutlined />, onClick: () => openGate('save') },\n              { key: 'restore', label: 'Restore saved default', icon: <CloudDownloadOutlined />, onClick: () => openGate('restore') },\n              { type: 'divider' },\n              { key: 'reset', label: 'Reset all detail settings', icon: <ReloadOutlined />, danger: true, onClick: () => openGate('reset') },\n            ] }}>\n              <Button size=\"small\" icon={<MoreOutlined />}>Workspace defaults</Button>\n            </Dropdown>\n            <Button size=\"small\" icon={<SettingOutlined />} onClick={() => setDefaultsOpen(true)}>Display Defaults</Button>\n            <Button size=\"small\" icon={<EyeOutlined />} disabled={!selected} onClick={() => setPreviewOpen(true)}>Preview</Button>\n            <Button type=\"primary\" size=\"small\" icon={<SaveOutlined />} loading={saving} disabled={!selected} onClick={handleSave}>\n              Save Configuration\n            </Button>\n          </Space>\n        }\n      >\n        <div className=\"admin-accent-bar\" />\n        <div className=\"fg-scope-toolbar\" style={{ marginBottom: 12 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>\n            Select a client to edit a client-scoped detail view for this module. Leave blank for the\n            module default. A record belonging to a client automatically uses that client&apos;s\n            detail config, falling back to the default when the client has none.\n          </Text>\n          <Space wrap size={8}>\n            <Select\n              size=\"small\"\n              allowClear\n              showSearch\n              placeholder=\"Client (default)\"\n              style={{ width: 240 }}\n              value={clientId || undefined}\n              optionFilterProp=\"label\"\n              options={clients\n                .map((c) => ({\n                  value: c._id ?? c.id,\n                  label: c.clientName ?? c.name ?? c.clientRefrenceId ?? c._id,\n                }))\n                .filter((c) => c.value)}\n              onChange={(next) => setClientId(next ?? '')}\n            />\n            <Button size=\"small\" icon={<ReloadOutlined />} onClick={() => setRefreshKey((k) => k + 1)}>\n              Reload\n            </Button>\n          </Space>\n        </div>\n        {clientId && !loadedClientId && !loading && (\n          <Alert\n            type=\"info\"\n            showIcon\n            style={{ marginBottom: 12 }}\n            message=\"This client has no detail config of its own yet\"\n            description=\"You are viewing the module default. Saving now creates a config for this client only — the default and every other client are left untouched.\"\n          />\n        )}\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          Customize how each module&apos;s detail view renders: per-field label, prefix/suffix, colour,\n          capitalization, hide, reference lookups (id → name), and merged display fields. These overrides\n          are applied on top of Form Groups and the add/edit forms are unaffected — except &quot;Hide Group&quot;,\n          which is the same flag Form Groups uses, so hiding a group here (or there) hides it in both places.\n          &quot;Hide in Detail&quot; hides the group from the detail view only, leaving the forms untouched.\n        </Text>\n      </AppCard>\n\n      <AppCard styles={{ body: { paddingTop: 8 } }}>\n        <Spin spinning={modulesLoading}>\n          <Tabs activeKey={selected} onChange={setSelected} items={moduleTabs.map((t) => ({ ...t, children: null }))} className=\"admin-module-tabs\" />\n          {error && <Alert type=\"error\" showIcon message={error} style={{ marginBottom: 12 }} />}\n\n          <Spin spinning={loading}>\n            <div className=\"admin-config-table-tools\">\n              <Input allowClear prefix={<SearchOutlined />} placeholder=\"Search groups or fields\" value={query} onChange={(event) => setQuery(event.target.value)} />\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>{groups.length} groups · {fields.length} fields</Text>\n            </div>\n            <Table\n              rowKey={(g) => g.id ?? g.name}\n              dataSource={sortedGroups}\n              columns={groupColumns}\n              pagination={false}\n              size=\"small\"\n              className=\"fg-table\"\n              expandable={{ expandedRowRender: renderGroupFields, rowExpandable: () => true }}\n              locale={{ emptyText: <Empty description=\"Select a module to see its groups and fields.\" image={Empty.PRESENTED_IMAGE_SIMPLE} /> }}\n            />\n\n            <div style={{ margin: '20px 0 8px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n              <Text strong><MergeCellsOutlined /> Merged Fields</Text>\n              <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} disabled={!selected} onClick={() => setMergeDraft({ index: null, merge: null })}>\n                Add Merge\n              </Button>\n            </div>\n            <Table\n              rowKey=\"key\"\n              dataSource={merges}\n              columns={mergeColumns}\n              pagination={false}\n              size=\"small\"\n              className=\"fg-table\"\n              locale={{ emptyText: <Empty description=\"No merged fields. Combine e.g. 'from' + 'to' into one.\" image={Empty.PRESENTED_IMAGE_SIMPLE} /> }}\n            />\n          </Spin>\n        </Spin>\n      </AppCard>\n\n      <FieldOverrideDrawer\n        key={editField?.key ?? 'field-closed'}\n        open={!!editField}\n        fieldMeta={editField}\n        value={editField ? { ...editField.lookupDefaults, ...(fieldCfg[editField.key] ?? {}) } : null}\n        moduleFieldOptions={fieldOptions}\n        onClose={() => setEditField(null)}\n        onSave={applyFieldOverride}\n      />\n\n      <MergeDrawer\n        key={mergeDraft ? `merge-${mergeDraft.index ?? 'new'}` : 'merge-closed'}\n        open={!!mergeDraft}\n        merge={mergeDraft?.merge}\n        fieldOptions={fieldOptions}\n        groupOptions={groupNames}\n        onClose={() => setMergeDraft(null)}\n        onSave={applyMerge}\n      />\n\n      <DefaultsDrawer open={defaultsOpen} onClose={() => setDefaultsOpen(false)} />\n\n      <PreviewDrawer open={previewOpen} module={selected} onClose={() => setPreviewOpen(false)} />\n\n      <OtpGateModal\n        open={!!gate}\n        scope=\"detailConfig\"\n        action={gate?.action}\n        title={gate?.title}\n        description={gate?.description}\n        confirmLabel={gate?.confirmLabel}\n        danger={gate?.danger}\n        onCancel={() => setGate(null)}\n        onVerified={handleGateVerified}\n      />\n    </div>\n  );\n}\n","import { fetchJsonWithAuth } from './authApi';\nimport { AUTH_URL } from './apiConfig';\n\nconst ADMIN_PATH = '/admin/email-templates';\nconst RUNTIME_PATH = '/email-templates';\n\nfunction dataOf(json) { return json?.data ?? json; }\n\nexport async function getEmailTemplates({ offset = 0, limit = 20, search = '', module = '', action = '', active } = {}) {\n  const params = new URLSearchParams({ offset: String(offset), limit: String(limit) });\n  if (search) params.set('search', search);\n  if (module) params.set('module', module);\n  if (action) params.set('action', action);\n  if (active !== undefined) params.set('active', String(active));\n  const payload = dataOf(await fetchJsonWithAuth(AUTH_URL, `${ADMIN_PATH}?${params}`)) ?? {};\n  return { items: Array.isArray(payload.items) ? payload.items : [], totalCount: Number(payload.totalCount ?? 0) };\n}\n\nexport async function getEmailTemplate(id) {\n  return dataOf(await fetchJsonWithAuth(AUTH_URL, `${ADMIN_PATH}/${encodeURIComponent(id)}`));\n}\n\nexport async function createEmailTemplate(payload) {\n  return fetchJsonWithAuth(AUTH_URL, ADMIN_PATH, { method: 'POST', body: JSON.stringify(payload) });\n}\n\nexport async function updateEmailTemplate(id, payload) {\n  return fetchJsonWithAuth(AUTH_URL, `${ADMIN_PATH}/${encodeURIComponent(id)}`, { method: 'PUT', body: JSON.stringify(payload) });\n}\n\nexport async function deleteEmailTemplate(id) {\n  return fetchJsonWithAuth(AUTH_URL, `${ADMIN_PATH}/${encodeURIComponent(id)}`, { method: 'DELETE' });\n}\n\nexport async function getRuntimeEmailTemplates({ module = '', action = '' } = {}) {\n  const params = new URLSearchParams();\n  if (module) params.set('module', module);\n  if (action) params.set('action', action);\n  const suffix = params.toString() ? `?${params}` : '';\n  const payload = dataOf(await fetchJsonWithAuth(AUTH_URL, `${RUNTIME_PATH}${suffix}`));\n  return Array.isArray(payload) ? payload : [];\n}\n\nexport async function getRuntimeEmailTemplate(id) {\n  return dataOf(await fetchJsonWithAuth(AUTH_URL, `${RUNTIME_PATH}/${encodeURIComponent(id)}`));\n}\n\n\nexport async function getSignaturePlaceholders() {\n  const payload = dataOf(await fetchJsonWithAuth(AUTH_URL, '/signature/placeHolder?module=userSignature')) ?? {};\n  const keys = Array.isArray(payload.Keys) ? payload.Keys : Array.isArray(payload.keys) ? payload.keys : [];\n  return {\n    placeHolderStart: payload.placeHolderStart ?? '{{',\n    placeHolderEnd: payload.placeHolderEnd ?? '}}',\n    module: payload.module ?? 'userSignature',\n    keys,\n  };\n}\n\nexport async function getSignatures({ offset = 0, limit = 20, search = '' } = {}) {\n  const params = new URLSearchParams({ offset: String(offset), limit: String(limit), sortBy: 'new', searchValue: search });\n  const payload = dataOf(await fetchJsonWithAuth(AUTH_URL, `/signature/homePage?${params}`)) ?? {};\n  const items = Array.isArray(payload.data) ? payload.data.map((item) => ({ ...item, isActive: item.isActive ?? item.status ?? false })) : [];\n  return { items, totalCount: Number(payload.totalCount ?? items.length) };\n}\n\nexport async function getSignature(id) {\n  return dataOf(await fetchJsonWithAuth(AUTH_URL, `/signature/editPreview?signatureId=${encodeURIComponent(id)}`));\n}\n\nexport async function createSignature(payload) {\n  return fetchJsonWithAuth(AUTH_URL, '/signature/add', { method: 'POST', body: JSON.stringify(payload) });\n}\n\nexport async function updateSignature(payload) {\n  return fetchJsonWithAuth(AUTH_URL, '/signature/edit', { method: 'PUT', body: JSON.stringify(payload) });\n}\n\nexport async function deleteSignature(id) {\n  return fetchJsonWithAuth(AUTH_URL, `/signature/delete?signatureId=${encodeURIComponent(id)}`, { method: 'DELETE' });\n}\n\nexport async function updateSignatureStatus(id, status) {\n  return fetchJsonWithAuth(AUTH_URL, `/signature/statusUpdate?signatureId=${encodeURIComponent(id)}&status=${status}`, { method: 'PUT' });\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n  Alert,\n  Button,\n  Dropdown,\n  Form,\n  Input,\n  Modal,\n  Popconfirm,\n  Select,\n  Space,\n  Spin,\n  Switch,\n  Table,\n  Tag,\n  Tooltip,\n  Typography,\n  message,\n} from 'antd';\nimport {\n  CloudDownloadOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  PlusOutlined,\n  ReloadOutlined,\n  SaveOutlined,\n  ToolOutlined,\n  MoreOutlined,\n  SearchOutlined,\n} from '@ant-design/icons';\n\nimport AppCard from '../../../components/cards/AppCard';\nimport OtpGateModal from '../../../components/admin/OtpGateModal';\nimport {\n  createRowActionConfig,\n  deleteRowActionConfig,\n  getCustomForms,\n  getMenuActions,\n  getMenuModules,\n  getRowActionConfigs,\n  updateRowActionConfig,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\nimport '../../../styles/FormGroupsSection.css';\nimport { getRuntimeEmailTemplates } from '../../../services/emailTemplateApi';\n\n// OTP-gated config actions surfaced as buttons next to \"Add Action\". Each opens\n// the OtpGateModal which mails a code and performs the action on verification.\n// These operate on ALL modules'/roles' row-action configs at once (not just the\n// currently selected module), same as the Form Groups / Detail Groups pattern.\nconst CONFIG_GATE_META = {\n  reset:   { action: 'reset',   title: 'Reset all row actions',   confirmLabel: 'Reset All',       danger: true,\n    description: 'This clears every configured row action for every module in this workspace. Actions have no built-in defaults, so this leaves every module with no actions until reconfigured.' },\n  save:    { action: 'save',    title: 'Save current as default', confirmLabel: 'Save Default',    danger: false,\n    description: 'Snapshots the current row actions for all modules and roles as the saved default you can restore to later.' },\n  restore: { action: 'restore', title: 'Restore saved default',   confirmLabel: 'Restore Default', danger: true,\n    description: 'Replaces the current row actions for all modules and roles with the last saved default.' },\n};\n\nconst { Text } = Typography;\n\nconst ICON_OPTIONS = [\n  { value: 'delete',      label: 'delete (trash)' },\n  { value: 'edit',        label: 'edit (pencil)' },\n  { value: 'mail',        label: 'mail (envelope)' },\n  { value: 'shareAlt',    label: 'shareAlt (share)' },\n  { value: 'swap',        label: 'swap (arrows)' },\n  { value: 'thunderbolt', label: 'thunderbolt (lightning)' },\n  { value: 'userAdd',     label: 'userAdd (add user)' },\n  { value: 'userSwitch',  label: 'userSwitch (switch user)' },\n];\n\nconst ACTION_TYPE_OPTIONS = [\n  { value: 'navigate', label: 'Navigate (open page)' },\n  { value: 'modal',    label: 'Modal (open popup)' },\n  { value: 'api',      label: 'API (call endpoint)' },\n  { value: 'copy',     label: 'Copy (clipboard)' },\n  { value: 'document', label: 'Document (open viewer)' },\n  { value: 'group',    label: 'Group (submenu of child actions)' },\n];\n\nconst API_METHOD_OPTIONS = ['GET', 'POST', 'PUT', 'DELETE'];\nconst BUILT_IN_POPUPS = [\n  'quick-submit', 'add-notes', 'mail', 'change-status', 'tag-to-job',\n  'add-to-groups', 'self-assign', 'others-assign', 'delete', 'vendor-share',\n  'sticky-notes', 'move-to-onboarding', 'approve-rate', 'reject',\n  'add-batch-candidate',\n];\n\nconst EMPTY_ACTION = {\n  key: '', label: '', icon: '', actionType: 'navigate',\n  routeTemplate: '', linkTarget: '_self', apiMethod: 'POST', apiPath: '',\n  popupKey: '', popupStateText: '', copyField: '', documentField: '', allowedTabs: [],\n  popupFieldName: '', popupFieldDataSource: '', popupFieldMasterName: '',\n  popupFieldLabelKey: '', popupFieldValueKey: '',\n  permission: '', permissionModule: '', permissionAction: '', permissionKey: '', allowMultiple: false, danger: false, showInList: true,\n  showInDetail: false, detailPlacement: 'more', requireJobId: false,\n  // Done state (config-driven success terminus). doneField/doneOperator/doneValue\n  // are the split form of the persisted `doneWhen` condition, recombined on save.\n  doneLabel: '', doneField: '', doneOperator: 'notEmpty', doneValue: '', doneTone: 'success',\n};\n\n// Operators offered for the done-state condition — a practical subset of the\n// action-rule operators (the ones that make sense for a single lifecycle flag).\nconst DONE_OPERATOR_OPTIONS = [\n  { value: 'notEmpty', label: 'is set (not empty)' },\n  { value: 'eq',       label: 'equals' },\n  { value: 'ne',       label: 'not equals' },\n  { value: 'isEmpty',  label: 'is empty' },\n];\n\nfunction newKey() {\n  return `action_${Date.now()}`;\n}\n\n/* ── Action editor ─────────────────────────────────────────────────────────── */\nfunction ActionModal({ open, initial, isChild, popupForms, templateOptions, permissionModules, permissionActions, onClose, onSave }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const actionType = Form.useWatch('actionType', form) ?? 'navigate';\n  const showInDetail = Form.useWatch('showInDetail', form) ?? false;\n  const popupKey = Form.useWatch('popupKey', form) ?? '';\n  const doneOperator = Form.useWatch('doneOperator', form) ?? 'notEmpty';\n\n  useEffect(() => {\n    if (open) {\n      // Existing \"permission\" is a flat \"module.action\" string (e.g. \"job.edit\") —\n      // split it into the two dropdowns below; recombined on save.\n      const [permModule = '', permAction = ''] = (initial?.permission ?? '').split('.');\n      form.setFieldsValue({\n        ...EMPTY_ACTION,\n        ...initial,\n        permissionModule: permModule,\n        permissionAction: permAction,\n        popupStateText: initial?.popupState\n          ? JSON.stringify(initial.popupState, null, 2)\n          : '',\n        // Split the persisted doneWhen condition back into its edit fields.\n        doneField: initial?.doneWhen?.field ?? '',\n        doneOperator: initial?.doneWhen?.operator ?? 'notEmpty',\n        doneValue: initial?.doneWhen?.value ?? '',\n        doneLabel: initial?.doneLabel ?? '',\n        doneTone: initial?.doneTone ?? 'success',\n        popupFieldName: initial?.popupFieldOverrides?.[0]?.name ?? '',\n        popupFieldDataSource: initial?.popupFieldOverrides?.[0]?.dataSource ?? '',\n        popupFieldMasterName: initial?.popupFieldOverrides?.[0]?.masterName ?? '',\n        popupFieldLabelKey: initial?.popupFieldOverrides?.[0]?.labelKey ?? '',\n        popupFieldValueKey: initial?.popupFieldOverrides?.[0]?.valueKey ?? '',\n      });\n    }\n  }, [open, initial, form]);\n\n  const handleSave = async () => {\n    const values = await form.validateFields();\n    let popupState;\n    if (values.popupStateText?.trim()) {\n      try {\n        popupState = JSON.parse(values.popupStateText);\n      } catch {\n        form.setFields([{ name: 'popupStateText', errors: ['Enter valid JSON'] }]);\n        return;\n      }\n    }\n    const action = { ...values };\n    delete action.popupStateText;\n    const { permissionModule, permissionAction } = action;\n    delete action.permissionModule;\n    delete action.permissionAction;\n    action.permission = permissionModule && permissionAction ? `${permissionModule}.${permissionAction}` : '';\n\n    // Recombine the done-state edit fields into a single `doneWhen` condition.\n    // A blank field (or an isEmpty/notEmpty operator) drops the value; a blank\n    // field entirely clears the done state.\n    const { doneField, doneOperator, doneValue } = action;\n    delete action.doneField;\n    delete action.doneOperator;\n    delete action.doneValue;\n    if (doneField?.trim()) {\n      const operator = doneOperator || 'notEmpty';\n      const needsValue = operator === 'eq' || operator === 'ne';\n      action.doneWhen = {\n        field: doneField.trim(),\n        operator,\n        ...(needsValue ? { value: (doneValue ?? '').trim() } : {}),\n      };\n      if (!action.doneLabel?.trim()) action.doneLabel = '';\n    } else {\n      action.doneWhen = undefined;\n      action.doneLabel = '';\n    }\n    if (action.actionType !== 'modal' || !['mail', 'vendor-share'].includes(action.popupKey)) {\n      delete action.defaultTemplateId;\n    }\n    if (action.actionType !== 'modal' || action.popupKey !== 'mail') {\n      delete action.requireJobId;\n    }\n    const {\n      popupFieldName,\n      popupFieldDataSource,\n      popupFieldMasterName,\n      popupFieldLabelKey,\n      popupFieldValueKey,\n    } = action;\n    delete action.popupFieldName;\n    delete action.popupFieldDataSource;\n    delete action.popupFieldMasterName;\n    delete action.popupFieldLabelKey;\n    delete action.popupFieldValueKey;\n    const resolvedPopupFieldName = popupFieldName?.trim()\n      || (action.popupKey === 'change-status' ? 'status' : '');\n    const resolvedPopupLabelKey = popupFieldLabelKey?.trim()\n      || (popupFieldMasterName?.trim() === 'clientSubmissions' ? 'clientSubmissionStatusText' : '');\n    const resolvedPopupValueKey = popupFieldValueKey?.trim()\n      || (popupFieldMasterName?.trim() === 'clientSubmissions' ? 'clientSubmissionStatusText' : '');\n    if (action.actionType === 'modal' && resolvedPopupFieldName && popupFieldDataSource) {\n      action.popupFieldOverrides = [{\n        name: resolvedPopupFieldName,\n        dataSource: popupFieldDataSource,\n        ...(popupFieldDataSource === 'master' ? { masterName: popupFieldMasterName?.trim() } : {}),\n        ...(resolvedPopupLabelKey ? { labelKey: resolvedPopupLabelKey } : {}),\n        ...(resolvedPopupValueKey ? { valueKey: resolvedPopupValueKey } : {}),\n      }];\n    } else {\n      action.popupFieldOverrides = undefined;\n    }\n    setSaving(true);\n    try {\n      await onSave({ ...action, ...(popupState ? { popupState } : { popupState: undefined }) });\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  const popupOptions = [\n    ...BUILT_IN_POPUPS.map((key) => ({ value: key, label: `${key} (built-in)` })),\n    ...popupForms.map((popup) => ({\n      value: popup.action,\n      label: `${popup.label} (${popup.action})`,\n    })),\n  ].filter((option, index, options) => options.findIndex((item) => item.value === option.value) === index);\n\n  return (\n    <Modal\n      title={`${initial?.key ? 'Edit' : 'Add'}${isChild ? ' Child' : ''} Action`}\n      width={720}\n      open={open}\n      onCancel={onClose}\n      onOk={handleSave}\n      confirmLoading={saving}\n      okText=\"Save Action\"\n      okButtonProps={{ icon: <SaveOutlined /> }}\n      className=\"fg-editor-modal action-editor-modal\"\n    >\n      <Form form={form} layout=\"vertical\" initialValues={EMPTY_ACTION} className=\"action-editor-form\">\n        <div className=\"action-editor-intro\">\n          Choose what the action does, then decide where it appears and who can use it.\n        </div>\n        <div className=\"action-editor-grid\">\n        <Form.Item name=\"key\" label=\"Key\" rules={[{ required: true, message: 'Key is required' }]}>\n          <Input placeholder=\"e.g. sourceCandidates\" />\n        </Form.Item>\n        <Form.Item name=\"label\" label=\"Label\" rules={[{ required: true, message: 'Label is required' }]}>\n          <Input placeholder=\"e.g. Source Candidates\" />\n        </Form.Item>\n        <Form.Item name=\"icon\" label=\"Icon\" rules={[{ required: false, message: 'Icon is required' }]}>\n          <Select options={ICON_OPTIONS} placeholder=\"Select icon\" allowClear/>\n        </Form.Item>\n        <Form.Item name=\"actionType\" label=\"Action Type\" rules={[{ required: true }]}>\n          <Select\n            options={ACTION_TYPE_OPTIONS}\n          />\n        </Form.Item>\n        </div>\n\n        {actionType === 'group' && (\n          <Alert\n            type=\"info\"\n            showIcon\n            message=\"Group actions don't run anything themselves.\"\n            description='This action renders as a submenu. Save it, then use \"Add Child Action\" on its row to configure what appears inside (e.g. Tag To Job, Send Mail, Add Notes).'\n            style={{ marginBottom: 16 }}\n          />\n        )}\n\n        {actionType !== 'group' && <div className=\"action-editor-section-title\">Behaviour</div>}\n\n        {actionType === 'navigate' && (\n          <>\n            <Form.Item name=\"routeTemplate\" label=\"Route Template\" rules={[{ required: true }]}>\n              <Input placeholder=\"e.g. /app/jobs/edit/:_id\" />\n            </Form.Item>\n            <Form.Item name=\"linkTarget\" label=\"Open in\" tooltip=\"New tab is useful for a reference page the user shouldn't lose their place to (e.g. Open JD from Quick Submit).\">\n              <Select options={[\n                { value: '_self', label: 'Same tab' },\n                { value: '_blank', label: 'New tab' },\n              ]} />\n            </Form.Item>\n          </>\n        )}\n\n        {actionType === 'modal' && (\n          <>\n            <Form.Item name=\"popupKey\" label=\"Popup\" rules={[{ required: true, message: 'Select a popup' }]}\n              tooltip=\"Admin popup forms and built-in popup integrations are listed together.\">\n              <Select showSearch optionFilterProp=\"label\" options={popupOptions} placeholder=\"Select popup form\" />\n            </Form.Item>\n            <Form.Item name=\"popupStateText\" label=\"Popup Context (JSON, optional)\"\n              tooltip='Static context passed to the popup, for example {\"notesfor\":\"candidate\"}'>\n              <Input.TextArea rows={4} placeholder={'{\"notesfor\":\"candidate\"}'} />\n            </Form.Item>\n            <Space.Compact block>\n              <Form.Item name=\"apiMethod\" label=\"Submit Method\" style={{ width: 150 }}>\n                <Select options={API_METHOD_OPTIONS.map((m) => ({ value: m, label: m }))} />\n              </Form.Item>\n            <Form.Item name=\"apiPath\" label=\"Submit API (optional)\" style={{ flex: 1 }}\n                tooltip=\"Leave empty to use the built-in handler for the selected popup key.\">\n                <Input placeholder=\"e.g. /module-data-update\" />\n              </Form.Item>\n            </Space.Compact>\n            <div className=\"action-editor-section-title\">Popup Dropdown Source</div>\n            <Space.Compact block>\n              <Form.Item name=\"popupFieldName\" label=\"Field Name\" style={{ width: '28%' }}\n                tooltip='The popup field to override. For Change Status, use \"status\".'>\n                <Input placeholder=\"status\" />\n              </Form.Item>\n              <Form.Item name=\"popupFieldDataSource\" label=\"Source\" style={{ width: '24%' }}>\n                <Select allowClear options={[\n                  { value: 'master', label: 'Master' },\n                ]} placeholder=\"Default\" />\n              </Form.Item>\n              <Form.Item name=\"popupFieldMasterName\" label=\"Master Name\" style={{ width: '48%' }}>\n                <Input placeholder=\"clientSubmissions\" />\n              </Form.Item>\n            </Space.Compact>\n            <Space.Compact block>\n              <Form.Item name=\"popupFieldLabelKey\" label=\"Label Key\" style={{ width: '50%' }}>\n                <Input placeholder=\"clientSubmissionStatusText\" />\n              </Form.Item>\n              <Form.Item name=\"popupFieldValueKey\" label=\"Value Key\" style={{ width: '50%' }}>\n                <Input placeholder=\"clientSubmissionStatusText\" />\n              </Form.Item>\n            </Space.Compact>\n          </>\n        )}\n\n        {actionType === 'modal' && ['mail', 'vendor-share'].includes(popupKey) && (\n          <Form.Item\n            name=\"defaultTemplateId\"\n            label=\"Default Email Template\"\n            tooltip=\"This template is selected and loaded automatically whenever this action opens the mail composer.\"\n          >\n            <Select allowClear showSearch optionFilterProp=\"label\" options={templateOptions} placeholder=\"No default — user selects in composer\" />\n          </Form.Item>\n        )}\n\n        {actionType === 'modal' && popupKey === 'mail' && (\n          <Form.Item\n            name=\"requireJobId\"\n            label=\"Require Job ID\"\n            valuePropName=\"checked\"\n            tooltip=\"Show a Job ID field in this mail popup. When a valid Job ID is entered, the job-aware bulk-mail API loads the configured Candidate template subject and content. Leave off for modules that do not need a Job ID.\"\n          >\n            <Switch checkedChildren=\"Required\" unCheckedChildren=\"Not required\" />\n          </Form.Item>\n        )}\n\n        {actionType === 'api' && (\n          <>\n            <Form.Item name=\"apiMethod\" label=\"API Method\">\n              <Select options={API_METHOD_OPTIONS.map((m) => ({ value: m, label: m }))} />\n            </Form.Item>\n            <Form.Item name=\"apiPath\" label=\"API Path\">\n              <Input placeholder=\"e.g. /jobs/:_id\" />\n            </Form.Item>\n          </>\n        )}\n\n        {actionType === 'copy' && (\n          <Form.Item name=\"copyField\" label=\"Record Field to Copy\" rules={[{ required: true }]}>\n            <Input placeholder=\"e.g. email or applicantRefrenceId\" />\n          </Form.Item>\n        )}\n\n        {actionType === 'document' && (\n          <Form.Item name=\"documentField\" label=\"Document Field\" rules={[{ required: true }]}>\n            <Input placeholder=\"e.g. resume or attachment\" />\n          </Form.Item>\n        )}\n\n        <div className=\"action-editor-section-title\">Availability and access</div>\n        <Form.Item name=\"allowedTabs\" label=\"Allowed Tabs (optional)\"\n          tooltip=\"Leave empty to show on every tab.\">\n          <Select mode=\"tags\" tokenSeparators={[',']} placeholder=\"e.g. allJobs\" />\n        </Form.Item>\n\n        <Space.Compact block>\n          <Form.Item name=\"permissionModule\" label=\"Role Permission — Module (optional)\" style={{ width: '50%' }}\n            tooltip=\"Which module's RBAC permission gates this action. Leave both empty to show for every permitted role.\">\n            <Select allowClear showSearch optionFilterProp=\"label\" placeholder=\"e.g. job\"\n              options={permissionModules.map((m) => ({ value: m, label: m }))} />\n          </Form.Item>\n          <Form.Item name=\"permissionAction\" label=\"Role Permission — Action\" style={{ width: '50%' }}>\n            <Select allowClear showSearch optionFilterProp=\"label\" placeholder=\"e.g. edit\"\n              options={permissionActions.map((a) => ({ value: a, label: a }))} />\n          </Form.Item>\n        </Space.Compact>\n        <Form.Item name=\"permissionKey\" label=\"Permission Key (row-level gate)\" tooltip=\"Maps to record.actionPermission.<key>. Leave blank to always show.\">\n          <Input placeholder=\"e.g. edit, sourceCandidates, sharePermission\" />\n        </Form.Item>\n\n        <div className=\"action-toggle-grid\">\n          <Form.Item name=\"allowMultiple\" label=\"Multiple Records\" valuePropName=\"checked\">\n            <Switch />\n          </Form.Item>\n          <Form.Item name=\"danger\" label=\"Danger\" valuePropName=\"checked\">\n            <Switch />\n          </Form.Item>\n          <Form.Item name=\"showInList\" label=\"Show in List\" valuePropName=\"checked\">\n            <Switch />\n          </Form.Item>\n          <Form.Item name=\"showInDetail\" label=\"Show in Detail\" valuePropName=\"checked\">\n            <Switch />\n          </Form.Item>\n        </div>\n        {showInDetail && (\n          <Form.Item name=\"detailPlacement\" label=\"Detail Placement\">\n            <Select options={[\n              { value: 'primary', label: 'Primary button' },\n              { value: 'more', label: 'More actions menu' },\n            ]} />\n          </Form.Item>\n        )}\n\n        <div className=\"action-editor-section-title\">Done state (optional)</div>\n        <Alert\n          type=\"info\"\n          showIcon\n          style={{ marginBottom: 12 }}\n          message=\"Turn this action into a disabled success label once a condition is met.\"\n          description='Example: when the record field \"onboardingStatus\" is set, \"Move to Onboarding\" shows as a disabled \"Moved to Onboarded\". Leave the field blank to disable.'\n        />\n        <Form.Item name=\"doneLabel\" label=\"Done Label\"\n          tooltip=\"Text shown once the done condition is met (e.g. Moved to Onboarded). Falls back to the normal label if blank.\">\n          <Input placeholder=\"e.g. Moved to Onboarded\" />\n        </Form.Item>\n        <Space.Compact block>\n          <Form.Item name=\"doneField\" label=\"When Record Field\" style={{ width: '40%' }}\n            tooltip=\"A field on the record to test (dotted paths allowed, e.g. onboardingStatus).\">\n            <Input placeholder=\"e.g. onboardingStatus\" />\n          </Form.Item>\n          <Form.Item name=\"doneOperator\" label=\"Condition\" style={{ width: '30%' }}>\n            <Select options={DONE_OPERATOR_OPTIONS} />\n          </Form.Item>\n          <Form.Item name=\"doneValue\" label=\"Value\" style={{ width: '30%' }}\n            hidden={doneOperator !== 'eq' && doneOperator !== 'ne'}>\n            <Input placeholder=\"e.g. In Progress\" />\n          </Form.Item>\n        </Space.Compact>\n        <Form.Item name=\"doneTone\" label=\"Done Colour\">\n          <Select options={[\n            { value: 'success', label: 'Success (green)' },\n            { value: 'primary', label: 'Primary (blue)' },\n            { value: 'danger', label: 'Danger (red)' },\n          ]} />\n        </Form.Item>\n      </Form>\n    </Modal>\n  );\n}\n\n/* ── Main Section ──────────────────────────────────────────────────────────── */\nexport default function RowActionsSection() {\n  const [modules, setModules] = useState([]);\n  const [selectedModule, setSelectedModule] = useState('');\n  // This screen edits the DEFAULT (All Roles) action library only. Per-role\n  // overrides live in Admin → User Types → Config → Actions (RoleActionsEditor).\n  const selectedRoleId = 0;\n\n  const [configs, setConfigs] = useState([]);\n  const [activeConfig, setActiveConfig] = useState(null);\n  const [actions, setActions] = useState([]);\n  const [dirty, setDirty] = useState(false);\n\n  const [loading, setLoading] = useState(false);\n  const [saving, setSaving] = useState(false);\n  const [error, setError] = useState(null);\n\n  const [drawerOpen, setDrawerOpen] = useState(false);\n  const [editingAction, setEditingAction] = useState(null);\n  const [popupForms, setPopupForms] = useState([]);\n  const [templateOptions, setTemplateOptions] = useState([]);\n  const [gate, setGate] = useState(null); // { action, title, confirmLabel, danger, description }\n  const [query, setQuery] = useState('');\n  const [permissionModules, setPermissionModules] = useState([]);\n  const [permissionActions, setPermissionActions] = useState([]);\n\n  /* Load modules once, from the MENUS registry only (/admin/menu-modules) —\n     the same list the Admin → Menus tab shows.\n\n     It used to merge in every Mongo COLLECTION plus every key already present\n     in rowActionConfig, which buried the ~24 real modules in a long list of\n     internal collections and derived variants (\"submissiondetails\",\n     \"submissionJob\"). Those variants are still fully configurable: this Select\n     is mode=\"tags\", so any key can be TYPED in, and typing is how a surface\n     that is not itself a menu has always been reached. Only what is OFFERED\n     changes.\n\n     The label is kept alongside the key because a menu is recognisable by its\n     name (\"Employer Management\") far more than by its key (\"employers\"); the\n     value written to config is still the key. */\n  useEffect(() => {\n    getMenuModules().then((mods) => {\n      const options = normalizeModuleOptions(mods);\n      setModules(options);\n      setSelectedModule((current) => current || options[0]?.value || '');\n    }).catch(() => {\n      setModules([]);\n    });\n  }, []);\n\n  /* Load the RBAC permission catalog (module/action master data) once, for\n     the Permission dropdowns in the action editor — the same catalog Roles'\n     Permissions tab reads from. */\n  useEffect(() => {\n    Promise.all([getMenuModules().catch(() => []), getMenuActions().catch(() => [])])\n      .then(([mods, actions]) => {\n        setPermissionModules([...new Set(mods.map((m) => m.MENUNAME ?? m.menuName).filter(Boolean))]);\n        setPermissionActions([...new Set(actions.map((a) => a.permissionKey ?? a.PERMISSIONKEY).filter(Boolean))]);\n      });\n  }, []);\n\n  /* Load configs when module changes */\n  const loadConfigs = useCallback(async () => {\n    if (!selectedModule) return;\n    setLoading(true);\n    setError(null);\n    setConfigs([]);\n    try {\n      const data = await getRowActionConfigs(selectedModule);\n      setConfigs(data);\n    } catch (e) {\n      setError(e.message);\n    } finally {\n      setLoading(false);\n    }\n  }, [selectedModule]);\n\n  useEffect(() => { queueMicrotask(() => { loadConfigs(); }); }, [loadConfigs]);\n\n  useEffect(() => {\n    Promise.all([\n      getCustomForms(selectedModule, 'popup').catch(() => []),\n      getRuntimeEmailTemplates({ module: selectedModule }).catch(() => []),\n    ]).then(([forms, templates]) => {\n      setPopupForms(forms);\n      setTemplateOptions(templates.map((template) => ({ value: template._id ?? template.id, label: `${template.name} · ${template.action}` })));\n    });\n  }, [selectedModule]);\n\n  /* Pick the default (roleId 0) config from already-loaded configs. The\n     backend list is alias-tolerant (job/jobs/Job), so prefer the config whose\n     module key matches the selection exactly, then fall back to any alias\n     variant — otherwise editing could target a legacy duplicate. */\n  useEffect(() => {\n    queueMicrotask(() => {\n      const forRole = configs.filter((c) => c.roleId === selectedRoleId);\n      const match = forRole.find((c) => c.module === selectedModule) ?? forRole[0];\n      setActiveConfig(match ?? null);\n      setActions(match ? (match.rowActions ?? []) : []);\n      setDirty(false);\n    });\n  }, [selectedModule, configs]);\n\n  /* Save */\n  const handleSave = async () => {\n    setSaving(true);\n    try {\n      if (activeConfig) {\n        await updateRowActionConfig(activeConfig.id ?? activeConfig._id, actions);\n        setConfigs((prev) => prev.map((config) => (\n          (config.id ?? config._id) === (activeConfig.id ?? activeConfig._id)\n            ? { ...config, rowActions: actions }\n            : config\n        )));\n        message.success('Config saved');\n      } else {\n        const created = await createRowActionConfig({ module: selectedModule, roleId: selectedRoleId, rowActions: actions });\n        const newDoc = created?.data ?? created;\n        setActiveConfig(newDoc);\n        setConfigs((prev) => [...prev, newDoc]);\n        message.success('Config created');\n      }\n      setDirty(false);\n    } catch (e) {\n      message.error(e.message);\n      if (String(e.message ?? '').toLowerCase().includes('already exists')) loadConfigs();\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  /* Delete config */\n  const handleDeleteConfig = async () => {\n    if (!activeConfig) return;\n    try {\n      await deleteRowActionConfig(activeConfig.id ?? activeConfig._id);\n      message.success('Config deleted');\n      await loadConfigs();\n    } catch (e) {\n      message.error(e.message);\n    }\n  };\n\n  /* Action row operations. editingParentKey is set when adding/editing a\n     child of a \"group\" action (e.g. adding \"Tag To Job\" under \"Shortlist\"),\n     null for top-level actions. */\n  const [editingParentKey, setEditingParentKey] = useState(null);\n\n  const openAddDrawer = (parentKey = null) => {\n    // Guard against `onClick={openAddDrawer}` handing this the click's\n    // SyntheticEvent instead of a real key (as happened for \"New action\" —\n    // a truthy non-string parentKey silently routed saves into the \"add\n    // child to a matching group\" branch, which matched nothing and dropped\n    // the new action). Only a string key is ever a valid parent.\n    setEditingParentKey(typeof parentKey === 'string' ? parentKey : null);\n    setEditingAction(null);\n    setDrawerOpen(true);\n  };\n\n  const openEditDrawer = (action, parentKey = null) => {\n    setEditingParentKey(parentKey);\n    setEditingAction(action);\n    setDrawerOpen(true);\n  };\n\n  const handleSaveAction = async (values) => {\n    let nextActions;\n    if (editingParentKey) {\n      nextActions = actions.map((parent) => {\n        if (parent.key !== editingParentKey) return parent;\n        const children = parent.children ?? [];\n        const nextChildren = editingAction\n          ? children.map((c) => (c.key === editingAction.key ? { ...c, ...values } : c))\n          : [...children, { ...EMPTY_ACTION, ...values, _localKey: newKey() }];\n        return { ...parent, children: nextChildren };\n      });\n    } else if (editingAction) {\n      nextActions = actions.map((a) => (a.key === editingAction.key ? { ...a, ...values } : a));\n    } else {\n      nextActions = [...actions, { ...EMPTY_ACTION, ...values, _localKey: newKey() }];\n    }\n\n    try {\n      if (activeConfig) {\n        await updateRowActionConfig(activeConfig.id ?? activeConfig._id, nextActions);\n        setConfigs((prev) => prev.map((config) => (\n          (config.id ?? config._id) === (activeConfig.id ?? activeConfig._id)\n            ? { ...config, rowActions: nextActions }\n            : config\n        )));\n        message.success('Config saved');\n      } else {\n        const created = await createRowActionConfig({ module: selectedModule, roleId: selectedRoleId, rowActions: nextActions });\n        const newDoc = created?.data ?? created;\n        setActiveConfig(newDoc);\n        setConfigs((prev) => [...prev, newDoc]);\n        message.success('Config created');\n      }\n      setActions(nextActions);\n      setDirty(false);\n      setDrawerOpen(false);\n    } catch (e) {\n      message.error(e.message);\n      // 409 \"config already exists\" means our list is stale (e.g. the config\n      // was created under an alias key or in another tab) — resync so the next\n      // save takes the update path instead of failing forever.\n      if (String(e.message ?? '').toLowerCase().includes('already exists')) loadConfigs();\n    }\n  };\n\n  const handleDeleteAction = (actionKey, parentKey = null) => {\n    if (parentKey) {\n      setActions((prev) => prev.map((parent) => (\n        parent.key === parentKey\n          ? { ...parent, children: (parent.children ?? []).filter((c) => c.key !== actionKey) }\n          : parent\n      )));\n    } else {\n      setActions((prev) => prev.filter((a) => a.key !== actionKey));\n    }\n    setDirty(true);\n  };\n\n  const moveAction = (index, dir) => {\n    setActions((prev) => {\n      const next = [...prev];\n      const target = index + dir;\n      if (target < 0 || target >= next.length) return prev;\n      [next[index], next[target]] = [next[target], next[index]];\n      return next;\n    });\n    setDirty(true);\n  };\n\n  /* OTP-gated Reset All / Save Default / Restore Default */\n  function openGate(action) { setGate(CONFIG_GATE_META[action]); }\n  function handleGateVerified() {\n    setGate(null);\n    loadConfigs();\n  }\n\n  const visibleActions = useMemo(() => {\n    const needle = query.trim().toLowerCase();\n    if (!needle) return actions;\n    return actions.filter((action) => [\n      action.label, action.key, action.actionType, action.popupKey,\n      action.routeTemplate, action.apiPath, action.permissionKey,\n    ].some((value) => String(value ?? '').toLowerCase().includes(needle)));\n  }, [actions, query]);\n\n  const columns = [\n    { title: 'Order', key: 'order', width: 76,\n      render: (_, action) => (\n        <Space>\n          <Button size=\"small\" type=\"text\" disabled={action._actionIndex === 0} onClick={() => moveAction(action._actionIndex, -1)}>↑</Button>\n          <Button size=\"small\" type=\"text\" disabled={action._actionIndex === actions.length - 1} onClick={() => moveAction(action._actionIndex, 1)}>↓</Button>\n        </Space>\n      ),\n    },\n    { title: 'Action', key: 'identity', width: 210, render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Text strong>{action.label || action.key}</Text>\n        <Text type=\"secondary\" code>{action.key}</Text>\n      </div>\n    ) },\n    { title: 'Behaviour', key: 'destination', render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Tag color=\"blue\">{action.actionType}</Tag>\n        <Text type=\"secondary\" ellipsis={{ tooltip: true }}>\n          {action.actionType === 'group'\n            ? `${(action.children ?? []).length} child action${(action.children ?? []).length === 1 ? '' : 's'}`\n            : (action.popupKey || action.routeTemplate || action.apiPath || action.copyField || action.documentField || 'No destination')}\n        </Text>\n      </div>\n    ),\n    },\n    { title: 'Visible in', key: 'visibility', width: 210, render: (_, action) => (\n      <Space size={[4, 4]} wrap>\n        {action.showInList && <Tag color=\"green\">List</Tag>}\n        {(action.showInDetail ?? action.showInList) && <Tag color=\"purple\">Detail · {action.detailPlacement || 'more'}</Tag>}\n        {action.allowMultiple && <Tag>Multi-select</Tag>}\n        {action.danger && <Tag color=\"red\">Destructive</Tag>}\n        {!action.showInList && !(action.showInDetail ?? action.showInList) && <Text type=\"secondary\">Nowhere</Text>}\n      </Space>\n    ) },\n    { title: 'Access', key: 'access', width: 170, render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Text type=\"secondary\">{action.permission || 'All permitted roles'}</Text>\n        {action.permissionKey && <Text type=\"secondary\" code>{action.permissionKey}</Text>}\n      </div>\n    ),\n    },\n    { title: '', key: 'actions', width: 110, fixed: 'right',\n      render: (_, record) => (\n        <Space>\n          {record.actionType === 'group' && (\n            <Tooltip title=\"Add child action\">\n              <Button size=\"small\" type=\"text\" icon={<PlusOutlined />} onClick={() => openAddDrawer(record.key)} />\n            </Tooltip>\n          )}\n          <Tooltip title=\"Edit\">\n            <Button size=\"small\" type=\"text\" icon={<EditOutlined />} onClick={() => openEditDrawer(record)} />\n          </Tooltip>\n          <Popconfirm title=\"Remove this action?\" onConfirm={() => handleDeleteAction(record.key)} okText=\"Remove\" okType=\"danger\">\n            <Tooltip title=\"Remove\">\n              <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} />\n            </Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  const childColumns = (parentKey) => [\n    { title: 'Action', key: 'identity', width: 210, render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Text strong>{action.label || action.key}</Text>\n        <Text type=\"secondary\" code>{action.key}</Text>\n      </div>\n    ) },\n    { title: 'Behaviour', key: 'destination', render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Tag color=\"blue\">{action.actionType}</Tag>\n        <Text type=\"secondary\" ellipsis={{ tooltip: true }}>\n          {action.popupKey || action.routeTemplate || action.apiPath || action.copyField || action.documentField || 'No destination'}\n        </Text>\n      </div>\n    ) },\n    { title: 'Access', key: 'access', width: 170, render: (_, action) => (\n      <div className=\"admin-config-primary-cell\">\n        <Text type=\"secondary\">{action.permission || 'All permitted roles'}</Text>\n        {action.permissionKey && <Text type=\"secondary\" code>{action.permissionKey}</Text>}\n      </div>\n    ) },\n    { title: '', key: 'actions', width: 80, fixed: 'right', render: (_, record) => (\n      <Space>\n        <Tooltip title=\"Edit\">\n          <Button size=\"small\" type=\"text\" icon={<EditOutlined />} onClick={() => openEditDrawer(record, parentKey)} />\n        </Tooltip>\n        <Popconfirm title=\"Remove this child action?\" onConfirm={() => handleDeleteAction(record.key, parentKey)} okText=\"Remove\" okType=\"danger\">\n          <Tooltip title=\"Remove\">\n            <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} />\n          </Tooltip>\n        </Popconfirm>\n      </Space>\n    ) },\n  ];\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n\n      {/* Header card */}\n      <AppCard\n        icon={<ToolOutlined />}\n        title=\"Actions\"\n        extra={\n          <Dropdown trigger={['click']} menu={{ items: [\n            { key: 'save', label: 'Save current as default', icon: <SaveOutlined />, onClick: () => openGate('save') },\n            { key: 'restore', label: 'Restore saved default', icon: <CloudDownloadOutlined />, onClick: () => openGate('restore') },\n            { type: 'divider' },\n            { key: 'reset', label: 'Reset all actions', icon: <ReloadOutlined />, danger: true, onClick: () => openGate('reset') },\n          ] }}>\n            <Button size=\"small\" icon={<MoreOutlined />}>Workspace defaults</Button>\n          </Dropdown>\n        }\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\">\n          Build one action once, then control its List and Detail placement, permissions, tabs, and multi-select behaviour.\n        </Text>\n      </AppCard>\n\n      {/* Selector + controls */}\n      <AppCard styles={{ body: { padding: '14px 18px' } }}>\n        <div className=\"admin-config-context\">\n          <div className=\"admin-config-context-copy\">\n            <Text strong>Configuration context</Text>\n            <Text type=\"secondary\">Choose a module. This is the default action library for all roles — per-role overrides are set in User Types → Config → Actions.</Text>\n          </div>\n          <div className=\"admin-config-context-controls\">\n          <label className=\"admin-config-control\">\n            <Text type=\"secondary\" style={{ display: 'block', marginBottom: 4, fontSize: 12 }}>Module</Text>\n            <Select\n              showSearch optionFilterProp=\"label\" style={{ width: 220 }}\n              mode=\"tags\" maxCount={1}\n              placeholder=\"Pick or type a module key\"\n              value={selectedModule ? [selectedModule] : []}\n              onChange={(v) => setSelectedModule(String(v[v.length - 1] ?? '').trim())}\n              // Searchable by BOTH what it is called and what it is keyed as, so\n              // an admin who knows either can find it.\n              options={modules.map((m) => ({\n                value: m.value,\n                label: m.label === m.value ? m.value : `${m.label} (${m.value})`,\n              }))}\n            />\n          </label>\n          <div className=\"admin-config-reload\">\n            <Button icon={<ReloadOutlined />} onClick={loadConfigs} loading={loading}>\n              Reload\n            </Button>\n          </div></div>\n        </div>\n      </AppCard>\n\n      {/* Error */}\n      {error && <Alert type=\"error\" message={error} showIcon />}\n\n      {/* Actions table */}\n      <AppCard\n        icon={<ToolOutlined />}\n        title={\n          <Space wrap>\n            <span>{actions.length} configured action{actions.length === 1 ? '' : 's'}</span>\n            {activeConfig\n              ? <Tag color=\"green\">Default config loaded (All Roles)</Tag>\n              : <Tag color=\"orange\">No config — will create on Save</Tag>\n            }\n          </Space>\n        }\n        extra={\n          <Space wrap>\n            {activeConfig && (\n              <Popconfirm title=\"Delete this entire config?\" onConfirm={handleDeleteConfig} okText=\"Delete\" okType=\"danger\">\n                <Button danger size=\"small\" icon={<DeleteOutlined />}>Delete Config</Button>\n              </Popconfirm>\n            )}\n            <Button icon={<PlusOutlined />} onClick={() => openAddDrawer()}>New action</Button>\n            <Button\n              type=\"primary\"\n              icon={<SaveOutlined />}\n              loading={saving}\n              disabled={!dirty}\n              onClick={handleSave}\n            >\n              Save Config\n            </Button>\n          </Space>\n        }\n      >\n        <div className=\"admin-config-table-tools\">\n          <Input\n            allowClear\n            prefix={<SearchOutlined />}\n            placeholder=\"Search actions\"\n            value={query}\n            onChange={(event) => setQuery(event.target.value)}\n          />\n          {dirty && <Text type=\"warning\">Unsaved changes</Text>}\n        </div>\n        <Spin spinning={loading}>\n          <Table\n            dataSource={visibleActions.map((a, i) => ({\n              ...a,\n              _actionIndex: actions.indexOf(a),\n              _rowKey: a.key || a._localKey || i,\n            }))}\n            rowKey=\"_rowKey\"\n            columns={columns}\n            pagination={false}\n            size=\"small\"\n            className=\"fg-table admin-config-table\"\n            scroll={{ x: 820 }}\n            locale={{ emptyText: 'No actions configured. Click \"Add Action\" to start.' }}\n            expandable={{\n              rowExpandable: (record) => record.actionType === 'group',\n              expandedRowRender: (record) => (\n                <Table\n                  dataSource={(record.children ?? []).map((c, i) => ({ ...c, _rowKey: c.key || c._localKey || i }))}\n                  rowKey=\"_rowKey\"\n                  columns={childColumns(record.key)}\n                  pagination={false}\n                  size=\"small\"\n                  className=\"fg-table admin-config-table\"\n                  locale={{ emptyText: 'No child actions yet. Use the + button on this row to add one (e.g. Tag To Job, Send Mail, Add Notes).' }}\n                />\n              ),\n            }}\n          />\n        </Spin>\n      </AppCard>\n\n      <ActionModal\n        open={drawerOpen}\n        initial={editingAction}\n        isChild={!!editingParentKey}\n        popupForms={popupForms}\n        templateOptions={templateOptions}\n        permissionModules={permissionModules}\n        permissionActions={permissionActions}\n        onClose={() => setDrawerOpen(false)}\n        onSave={handleSaveAction}\n      />\n\n      <OtpGateModal\n        open={!!gate}\n        scope=\"rowActions\"\n        action={gate?.action}\n        title={gate?.title}\n        description={gate?.description}\n        confirmLabel={gate?.confirmLabel}\n        danger={gate?.danger}\n        onCancel={() => setGate(null)}\n        onVerified={handleGateVerified}\n      />\n    </div>\n  );\n}\n","import { useEffect, useState } from 'react';\nimport {\n  Alert, Button, Divider, Drawer, Form, Input, Popconfirm,\n  Select, Space, Switch, Table, Tag, Tooltip, Typography, message,\n} from 'antd';\nimport { DeleteOutlined, EditOutlined, PlusOutlined, ThunderboltOutlined } from '@ant-design/icons';\nimport {\n  createModuleActionRule,\n  deleteModuleActionRule,\n  getActionConfigModules,\n  getModuleActionRules,\n  getModuleFields,\n  getRowActionConfigs,\n  updateModuleActionRule,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\n\nconst { Text, Title } = Typography;\n\nconst OPERATOR_OPTIONS = [\n  { value: 'eq',       label: 'equals' },\n  { value: 'ne',       label: 'not equals' },\n  { value: 'isEmpty',  label: 'is empty' },\n  { value: 'notEmpty', label: 'is not empty' },\n  { value: 'contains', label: 'contains' },\n  // Exact list membership — the id-safe alternative to \"contains\" (whose\n  // substring match would let user 1 match user 12). Combine with the\n  // {currentUserId} value token for \"…is/isn't mine\" rules.\n  { value: 'includes',    label: 'list includes (exact)' },\n  { value: 'notIncludes', label: 'list does not include (exact)' },\n  { value: 'fieldEq',  label: 'field = field' },\n  { value: 'scope',    label: 'view scope' },\n];\n\n// Runtime tokens accepted in a condition's value (see utils/actionRuleEngine).\nconst VALUE_TOKEN_OPTIONS = [\n  { value: '{currentUserId}', label: '{currentUserId} — the signed-in user' },\n];\n\nconst SCOPE_VALUES = [\n  { value: 'myJobs',  label: 'My Jobs' },\n  { value: 'allJobs', label: 'All Jobs' },\n];\n\nconst VALUE_NEEDED     = ['eq', 'ne', 'contains', 'includes', 'notIncludes'];\nconst SCOPE_OP         = 'scope';\nconst FIELD_EQ_OP      = 'fieldEq';\n\n// Default rules for the job module — mirrors the previously hardcoded backend logic\nconst JOB_SEED_RULES = [\n  {\n    name: 'Fulfilled jobs — block sourcing',\n    description: 'When a job status is fulfilled and has no recruiters, hide source & quick-submit buttons.',\n    conditions: [\n      { field: 'jobRecruitmentStatus', operator: 'eq', value: 'fulfilled', compareField: '' },\n      { field: 'recruiters',           operator: 'isEmpty', value: '', compareField: '' },\n    ],\n    blockedActions: ['sourceCandidates', 'quickSubmit'],\n    isActive: true,\n  },\n  {\n    name: 'All Jobs scope — restrict actions',\n    description: 'When viewing All Jobs, hide sourcing, quick-submit, change-status, notes and share.',\n    conditions: [\n      { field: '', operator: 'scope', value: 'allJobs', compareField: '' },\n    ],\n    blockedActions: ['sourceCandidates', 'quickSubmit', 'changeStatus', 'addNotes', 'share'],\n    isActive: true,\n  },\n  {\n    name: 'Target submission reached — block sourcing',\n    description: 'When targetSubmission equals submissionCount, no more sourcing is needed.',\n    conditions: [\n      { field: 'targetSubmission', operator: 'fieldEq', value: '', compareField: 'submissionCount' },\n    ],\n    blockedActions: ['sourceCandidates', 'quickSubmit'],\n    isActive: true,\n  },\n];\n\nconst emptyCondition = () => ({ field: '', operator: 'eq', value: '', compareField: '' });\nconst emptyRule      = () => ({ name: '', description: '', conditions: [emptyCondition()], blockedActions: [], disabledActions: [], allowedActions: [], isActive: true });\n\nfunction operatorLabel(op) {\n  return OPERATOR_OPTIONS.find((o) => o.value === op)?.label ?? op;\n}\n\nfunction conditionSummary(c) {\n  if (c.operator === SCOPE_OP)   return `scope = ${c.value}`;\n  if (c.operator === FIELD_EQ_OP) return `${c.field} = field:${c.compareField}`;\n  if (['isEmpty','notEmpty'].includes(c.operator)) return `${c.field} ${operatorLabel(c.operator)}`;\n  return `${c.field} ${operatorLabel(c.operator)} \"${c.value}\"`;\n}\n\nexport default function ModuleActionRulesSection() {\n  const [moduleOptions, setModuleOptions]     = useState([]);\n  const [modulesLoading, setModulesLoading]   = useState(false);\n  const [selectedModule, setSelectedModule]   = useState('');\n  const [rules, setRules]                     = useState([]);\n  const [loading, setLoading]                 = useState(false);\n  const [drawerOpen, setDrawerOpen]           = useState(false);\n  const [editing, setEditing]                 = useState(null);\n  const [form, setForm]                       = useState(emptyRule());\n  const [saving, setSaving]                   = useState(false);\n  const [seeding, setSeeding]                 = useState(false);\n  const [fieldOptions, setFieldOptions]       = useState([]);   // module fields for condition picker\n  const [actionKeyOptions, setActionKeyOptions] = useState([]); // row action keys for blocked actions\n\n  useEffect(() => {\n    let cancelled = false;\n    queueMicrotask(() => {\n      setModulesLoading(true);\n      getActionConfigModules()\n        .then((modules) => {\n          if (cancelled) return;\n          const options = normalizeModuleOptions(modules);\n          setModuleOptions(options);\n          setSelectedModule((current) => (\n            options.some((option) => option.value === current) ? current : options[0]?.value ?? ''\n          ));\n        })\n        .catch(() => {\n          if (!cancelled) {\n            setModuleOptions([]);\n            setSelectedModule('');\n          }\n        })\n        .finally(() => {\n          if (!cancelled) setModulesLoading(false);\n        });\n      });\n    return () => { cancelled = true; };\n  }, []);\n\n  // ── Load rules ──────────────────────────────────────────────────────────────\n  function load(mod) {\n    setLoading(true);\n    getModuleActionRules(mod)\n      .then((data) => setRules(Array.isArray(data) ? data : []))\n      .catch(() => setRules([]))\n      .finally(() => setLoading(false));\n  }\n\n  // ── Load field options for condition field picker ────────────────────────────\n  function loadFieldOptions(mod) {\n    getModuleFields(mod)\n      .then((fields) => {\n        const opts = (Array.isArray(fields) ? fields : []).map((f) => ({\n          value: f.field ?? f.fieldKey ?? f.key ?? f.name,\n          label: `${f.label ?? f.fieldName ?? f.name} (${f.field ?? f.fieldKey ?? f.key ?? f.name})`,\n        })).filter((o) => o.value);\n        setFieldOptions(opts);\n      })\n      .catch(() => setFieldOptions([]));\n  }\n\n  // ── Load row action keys for blocked actions picker ──────────────────────────\n  function loadActionKeyOptions(mod) {\n    getRowActionConfigs(mod)\n      .then((configs) => {\n        const keys = new Set();\n        (Array.isArray(configs) ? configs : []).forEach((cfg) => {\n          (cfg.rowActions ?? []).forEach((a) => { if (a.key) keys.add(a.key); });\n        });\n        setActionKeyOptions([...keys].map((k) => ({ value: k, label: k })));\n      })\n      .catch(() => setActionKeyOptions([]));\n  }\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      if (!selectedModule) {\n        setRules([]);\n        setFieldOptions([]);\n        setActionKeyOptions([]);\n        return;\n      }\n      load(selectedModule);\n      loadFieldOptions(selectedModule);\n      loadActionKeyOptions(selectedModule);\n    });\n  }, [selectedModule]);\n\n  // ── Drawer helpers ───────────────────────────────────────────────────────────\n  function openCreate() {\n    setEditing(null);\n    setForm(emptyRule());\n    setDrawerOpen(true);\n  }\n\n  function openEdit(rule) {\n    setEditing(rule);\n    setForm({\n      name:           rule.name           ?? '',\n      description:    rule.description    ?? '',\n      conditions:     rule.conditions?.length\n                        ? rule.conditions.map((c) => ({ ...c }))\n                        : [emptyCondition()],\n      blockedActions:  rule.blockedActions  ?? [],\n      disabledActions: rule.disabledActions ?? [],\n      // Read back so it round-trips. A key the editor never loads is a setting\n      // that appears to save and then vanishes on the next edit, because the\n      // save writes back the blank the editor was holding.\n      allowedActions:  rule.allowedActions  ?? [],\n      isActive:        rule.isActive        ?? true,\n    });\n    setDrawerOpen(true);\n  }\n\n  async function handleSave() {\n    if (!form.name.trim()) return;\n    setSaving(true);\n    try {\n      if (editing) {\n        await updateModuleActionRule(editing.id, form);\n        message.success('Rule updated');\n      } else {\n        await createModuleActionRule({ ...form, module: selectedModule });\n        message.success('Rule created');\n      }\n      setDrawerOpen(false);\n      load(selectedModule);\n    } catch (e) {\n      message.error(e.message);\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  async function handleDelete(rule) {\n    try {\n      await deleteModuleActionRule(rule.id);\n      message.success('Rule deleted');\n    } catch (e) {\n      message.error(e.message);\n    }\n    load(selectedModule);\n  }\n\n  // ── Seed default rules for job module ────────────────────────────────────────\n  async function handleSeedDefaults() {\n    setSeeding(true);\n    try {\n      for (const rule of JOB_SEED_RULES) {\n        await createModuleActionRule({ ...rule, module: selectedModule });\n      }\n      message.success('Default job rules created');\n      load(selectedModule);\n    } catch (e) {\n      message.error(e.message);\n    } finally {\n      setSeeding(false);\n    }\n  }\n\n  // ── Condition builder helpers ────────────────────────────────────────────────\n  function updateCondition(idx, patch) {\n    setForm((prev) => ({\n      ...prev,\n      conditions: prev.conditions.map((c, i) => (i === idx ? { ...c, ...patch } : c)),\n    }));\n  }\n\n  function addCondition() {\n    setForm((prev) => ({ ...prev, conditions: [...prev.conditions, emptyCondition()] }));\n  }\n\n  function removeCondition(idx) {\n    setForm((prev) => ({\n      ...prev,\n      conditions: prev.conditions.filter((_, i) => i !== idx),\n    }));\n  }\n\n  // ── Table columns ────────────────────────────────────────────────────────────\n  const columns = [\n    {\n      title: 'Rule Name',\n      dataIndex: 'name',\n      key: 'name',\n      width: 200,\n      render: (v, r) => (\n        <div>\n          <Text strong>{v}</Text>\n          {r.description ? <div><Text type=\"secondary\" style={{ fontSize: 11 }}>{r.description}</Text></div> : null}\n        </div>\n      ),\n    },\n    {\n      title: 'Conditions (ALL must match)',\n      key: 'conditions',\n      render: (_, r) => (\n        <Space size={4} direction=\"vertical\">\n          {(r.conditions ?? []).map((c, i) => (\n            <Tag key={i} style={{ fontFamily: 'monospace', fontSize: 11, margin: 0 }}>\n              {conditionSummary(c)}\n            </Tag>\n          ))}\n        </Space>\n      ),\n    },\n    {\n      title: 'Blocked Row Actions',\n      key: 'blockedActions',\n      render: (_, r) => (\n        <Space size={4} wrap>\n          {(r.blockedActions ?? []).map((k) => <Tag key={k} color=\"volcano\">{k}</Tag>)}\n        </Space>\n      ),\n    },\n    {\n      title: 'Disabled Row Actions',\n      key: 'disabledActions',\n      render: (_, r) => (\n        <Space size={4} wrap>\n          {(r.disabledActions ?? []).map((k) => <Tag key={k} color=\"gold\">{k}</Tag>)}\n        </Space>\n      ),\n    },\n    {\n      title: 'Only These Allowed',\n      key: 'allowedActions',\n      render: (_, r) => (\n        <Space size={4} wrap>\n          {(r.allowedActions ?? []).map((k) => <Tag key={k} color=\"green\">{k}</Tag>)}\n        </Space>\n      ),\n    },\n    {\n      title: 'Active',\n      dataIndex: 'isActive',\n      key: 'isActive',\n      width: 70,\n      render: (v) => <Tag color={v ? 'green' : 'default'}>{v ? 'On' : 'Off'}</Tag>,\n    },\n    {\n      title: '',\n      key: 'act',\n      width: 80,\n      render: (_, r) => (\n        <Space>\n          <Tooltip title=\"Edit\"><Button icon={<EditOutlined />} size=\"small\" type=\"text\" onClick={() => openEdit(r)} /></Tooltip>\n          <Popconfirm title=\"Delete this rule?\" onConfirm={() => handleDelete(r)}>\n            <Tooltip title=\"Delete\"><Button danger icon={<DeleteOutlined />} size=\"small\" type=\"text\" /></Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  // ── Render ───────────────────────────────────────────────────────────────────\n  return (\n    <div style={{ padding: '24px 0' }}>\n\n      {/* Header */}\n      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 8, flexWrap: 'wrap' }}>\n        <Title level={5} style={{ margin: 0 }}>Action Rules</Title>\n        <Select\n          options={moduleOptions}\n          value={selectedModule}\n          loading={modulesLoading}\n          placeholder=\"Select module\"\n          onChange={setSelectedModule}\n          style={{ width: 200 }}\n        />\n        <Button icon={<PlusOutlined />} type=\"primary\" disabled={!selectedModule} onClick={openCreate}>\n          Add Rule\n        </Button>\n        {(selectedModule === 'job' || selectedModule === 'jobs') && (\n          <Tooltip title=\"Create the 3 standard job rules that replace the hardcoded backend logic\">\n            <Button\n              icon={<ThunderboltOutlined />}\n              loading={seeding}\n              onClick={handleSeedDefaults}\n            >\n              Seed Job Defaults\n            </Button>\n          </Tooltip>\n        )}\n      </div>\n\n      <Alert\n        type=\"info\"\n        showIcon\n        style={{ marginBottom: 16, fontSize: 12 }}\n        message={\n          <span>\n            Rules are evaluated <b>per row</b> in the list view using the record&apos;s own field values.\n            When <b>all conditions</b> of a rule match, the listed action buttons are hidden for that row.\n            The <b>key</b> of each blocked action must match what is set in <b>Row Actions</b> config.\n          </span>\n        }\n      />\n\n      <Table\n        columns={columns}\n        dataSource={rules}\n        loading={loading}\n        rowKey=\"id\"\n        size=\"small\"\n        pagination={false}\n        locale={{ emptyText: selectedModule ? 'No rules yet. Click \"Add Rule\" to get started.' : 'No modules found. Configure modules first.' }}\n      />\n\n      {/* ── Add / Edit Drawer ─────────────────────────────────────────────── */}\n      <Drawer\n        open={drawerOpen}\n        title={editing ? `Edit: ${editing.name}` : 'Add Action Rule'}\n        width={620}\n        onClose={() => setDrawerOpen(false)}\n        footer={\n          <Space style={{ float: 'right' }}>\n            <Button onClick={() => setDrawerOpen(false)}>Cancel</Button>\n            <Button type=\"primary\" loading={saving} onClick={handleSave}>Save Rule</Button>\n          </Space>\n        }\n      >\n        <Form layout=\"vertical\">\n\n          <Form.Item label=\"Rule Name\" required>\n            <Input\n              value={form.name}\n              placeholder=\"e.g. Fulfilled jobs — block sourcing\"\n              onChange={(e) => setForm((p) => ({ ...p, name: e.target.value }))}\n            />\n          </Form.Item>\n\n          <Form.Item label=\"Description\">\n            <Input.TextArea\n              rows={2}\n              value={form.description}\n              placeholder=\"Explain when this rule applies\"\n              onChange={(e) => setForm((p) => ({ ...p, description: e.target.value }))}\n            />\n          </Form.Item>\n\n          <Form.Item label=\"Active\">\n            <Switch checked={form.isActive} onChange={(v) => setForm((p) => ({ ...p, isActive: v }))} />\n          </Form.Item>\n\n          <Divider orientation=\"left\" orientationMargin={0} style={{ fontSize: 13 }}>\n            Conditions <Text type=\"secondary\" style={{ fontSize: 12 }}>(ALL must match for the rule to fire)</Text>\n          </Divider>\n\n          {form.conditions.map((cond, idx) => (\n            <div\n              key={idx}\n              style={{\n                background: '#fafafa',\n                border: '1px solid #f0f0f0',\n                borderRadius: 6,\n                padding: '10px 12px',\n                marginBottom: 8,\n              }}\n            >\n              <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', flexWrap: 'wrap' }}>\n\n                {/* Operator selector — first so user picks condition type */}\n                <Form.Item label=\"Operator\" style={{ marginBottom: 0, minWidth: 140 }}>\n                  <Select\n                    options={OPERATOR_OPTIONS}\n                    value={cond.operator}\n                    style={{ width: 140 }}\n                    onChange={(v) => updateCondition(idx, { operator: v, value: '', compareField: '' })}\n                  />\n                </Form.Item>\n\n                {/* Field picker — hidden for scope operator */}\n                {cond.operator !== SCOPE_OP && (\n                  <Form.Item label=\"Record Field\" style={{ marginBottom: 0, flex: 1, minWidth: 180 }}>\n                    <Select\n                      showSearch\n                      allowClear\n                      mode=\"tags\"\n                      maxCount={1}\n                      value={cond.field ? [cond.field] : []}\n                      options={fieldOptions}\n                      style={{ width: '100%' }}\n                      placeholder=\"Select or type field name\"\n                      onChange={(v) => updateCondition(idx, { field: v[v.length - 1] ?? '' })}\n                      filterOption={(input, opt) =>\n                        (opt?.label ?? opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n                      }\n                    />\n                    <Text type=\"secondary\" style={{ fontSize: 11 }}>\n                      Field from the record (e.g. <code>jobRecruitmentStatus</code>, <code>recruiters</code>)\n                    </Text>\n                  </Form.Item>\n                )}\n\n                {/* Value input — only for operators that compare to a constant */}\n                {VALUE_NEEDED.includes(cond.operator) && (\n                  <Form.Item label=\"Value\" style={{ marginBottom: 0, minWidth: 180 }}>\n                    <Select\n                      showSearch\n                      allowClear\n                      mode=\"tags\"\n                      maxCount={1}\n                      value={cond.value ? [cond.value] : []}\n                      options={VALUE_TOKEN_OPTIONS}\n                      style={{ width: 200 }}\n                      placeholder='e.g. \"fulfilled\"'\n                      onChange={(v) => updateCondition(idx, { value: v[v.length - 1] ?? '' })}\n                      filterOption={(input, opt) =>\n                        (opt?.label ?? opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n                      }\n                    />\n                    <Text type=\"secondary\" style={{ fontSize: 11 }}>\n                      Type a literal, or pick <code>{'{currentUserId}'}</code> for the signed-in user.\n                    </Text>\n                  </Form.Item>\n                )}\n\n                {/* Scope value — only for scope operator */}\n                {cond.operator === SCOPE_OP && (\n                  <Form.Item label=\"Scope Value\" style={{ marginBottom: 0, minWidth: 140 }}>\n                    <Select\n                      options={SCOPE_VALUES}\n                      value={cond.value || undefined}\n                      style={{ width: 150 }}\n                      placeholder=\"Select scope\"\n                      onChange={(v) => updateCondition(idx, { value: v })}\n                    />\n                    <Text type=\"secondary\" style={{ fontSize: 11 }}>\n                      Current view tab (myJobs / allJobs)\n                    </Text>\n                  </Form.Item>\n                )}\n\n                {/* Compare field — only for fieldEq operator */}\n                {cond.operator === FIELD_EQ_OP && (\n                  <Form.Item label=\"Compare To Field\" style={{ marginBottom: 0, minWidth: 160 }}>\n                    <Select\n                      showSearch\n                      allowClear\n                      mode=\"tags\"\n                      maxCount={1}\n                      value={cond.compareField ? [cond.compareField] : []}\n                      options={fieldOptions}\n                      style={{ width: 170 }}\n                      placeholder=\"Select or type field\"\n                      onChange={(v) => updateCondition(idx, { compareField: v[v.length - 1] ?? '' })}\n                      filterOption={(input, opt) =>\n                        (opt?.label ?? opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n                      }\n                    />\n                    <Text type=\"secondary\" style={{ fontSize: 11 }}>\n                      e.g. <code>submissionCount</code>\n                    </Text>\n                  </Form.Item>\n                )}\n\n                {/* Remove condition */}\n                <div style={{ paddingTop: 22 }}>\n                  <Button\n                    danger\n                    disabled={form.conditions.length <= 1}\n                    icon={<DeleteOutlined />}\n                    size=\"small\"\n                    type=\"text\"\n                    onClick={() => removeCondition(idx)}\n                  />\n                </div>\n              </div>\n\n              {/* Preview of what the condition means */}\n              <div style={{ marginTop: 6 }}>\n                <Text type=\"secondary\" style={{ fontSize: 11 }}>\n                  Preview: <code style={{ color: '#1677ff' }}>{conditionSummary(cond)}</code>\n                </Text>\n              </div>\n            </div>\n          ))}\n\n          <Button size=\"small\" style={{ marginBottom: 16 }} onClick={addCondition}>\n            + Add Condition\n          </Button>\n\n          <Divider orientation=\"left\" orientationMargin={0} style={{ fontSize: 13 }}>\n            Blocked Row Actions\n            <Text type=\"secondary\" style={{ fontSize: 12, marginLeft: 8 }}>\n              (hidden when this rule fires)\n            </Text>\n          </Divider>\n\n          <Form.Item>\n            <Select\n              mode=\"tags\"\n              style={{ width: '100%' }}\n              value={form.blockedActions}\n              options={actionKeyOptions}\n              placeholder=\"Select or type action key (e.g. sourceCandidates, quickSubmit)\"\n              onChange={(v) => setForm((p) => ({ ...p, blockedActions: v }))}\n              filterOption={(input, opt) =>\n                (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n              }\n            />\n            <Text type=\"secondary\" style={{ fontSize: 11 }}>\n              Must match the <b>key</b> of a Row Action (configured in Admin → Row Actions).\n              Common job keys: <code>sourceCandidates</code>, <code>quickSubmit</code>,{' '}\n              <code>changeStatus</code>, <code>share</code>, <code>addNotes</code>, <code>assign</code>.\n            </Text>\n          </Form.Item>\n\n          <Divider orientation=\"left\" orientationMargin={0} style={{ fontSize: 13 }}>\n            Disabled Row Actions\n            <Text type=\"secondary\" style={{ fontSize: 12, marginLeft: 8 }}>\n              (stay visible, greyed out, when this rule fires)\n            </Text>\n          </Divider>\n\n          <Form.Item>\n            <Select\n              mode=\"tags\"\n              style={{ width: '100%' }}\n              value={form.disabledActions}\n              options={actionKeyOptions}\n              placeholder=\"Select or type action key (e.g. approveSubmission, rejectSubmission)\"\n              onChange={(v) => setForm((p) => ({ ...p, disabledActions: v }))}\n              filterOption={(input, opt) =>\n                (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n              }\n            />\n            <Text type=\"secondary\" style={{ fontSize: 11 }}>\n              Unlike Blocked, a disabled action keeps its normal spot and label —\n              it's just unclickable, with this rule's <b>Description</b> shown as\n              the reason on hover. Use this when the user should still see the\n              action exists (e.g. Approve/Reject while awaiting a resubmission)\n              instead of it disappearing.\n            </Text>\n          </Form.Item>\n\n          <Divider orientation=\"left\" orientationMargin={0} style={{ fontSize: 13 }}>\n            Only These Actions Allowed\n            <Text type=\"secondary\" style={{ fontSize: 12, marginLeft: 8 }}>\n              (everything else is hidden when this rule fires)\n            </Text>\n          </Divider>\n\n          <Form.Item>\n            <Select\n              mode=\"tags\"\n              style={{ width: '100%' }}\n              value={form.allowedActions}\n              options={actionKeyOptions}\n              placeholder=\"Leave empty unless you want an allow-list (e.g. delete)\"\n              onChange={(v) => setForm((p) => ({ ...p, allowedActions: v }))}\n              filterOption={(input, opt) =>\n                (opt?.value ?? '').toLowerCase().includes(input.toLowerCase())\n              }\n            />\n            <Text type=\"secondary\" style={{ fontSize: 11 }}>\n              The <b>inverse</b> of Blocked. Use it for &quot;when this happens, only\n              these remain&quot; — e.g. an inactive job where only <code>delete</code>\n              should show. Prefer it over listing every other action in Blocked:\n              an allow-list keeps working when a new action is added later,\n              whereas a blocked list silently lets the new one through on exactly\n              the records the rule exists to lock down.\n              <br />\n              Leave it <b>empty</b> for any normal rule — an allow-list that names\n              nothing would hide everything.\n            </Text>\n          </Form.Item>\n\n        </Form>\n      </Drawer>\n    </div>\n  );\n}\n","import { Tabs } from 'antd';\nimport { ApartmentOutlined, ThunderboltOutlined } from '@ant-design/icons';\nimport RowActionsSection from './RowActionsSection';\nimport ModuleActionRulesSection from './ModuleActionRulesSection';\nimport '../../../styles/FormGroupsSection.css';\n\nexport default function ActionsSection() {\n  return (\n    <Tabs\n      defaultActiveKey=\"actions\"\n      className=\"admin-config-tabs\"\n      destroyOnHidden={false}\n      items={[\n        {\n          key: 'actions',\n          label: 'Action library',\n          icon: <ThunderboltOutlined />,\n          children: <RowActionsSection />,\n        },\n        {\n          key: 'rules',\n          label: 'Visibility rules',\n          icon: <ApartmentOutlined />,\n          children: <ModuleActionRulesSection />,\n        },\n      ]}\n    />\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { Button, Drawer, Empty, Form, Input, message, Popconfirm, Select, Space, Switch, Table, Tabs, Tag, Tooltip, Typography } from 'antd';\nimport { DeleteOutlined, EditOutlined, MailOutlined, PlusOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport TipTapEditor from '../../../components/TipTapEditor';\nimport { getAdminClients, getModuleFields, getAvailableModules, getRowActionConfigs } from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\nimport { createEmailTemplate, createSignature, deleteEmailTemplate, deleteSignature, getEmailTemplate, getEmailTemplates, getSignature, getSignaturePlaceholders, getSignatures, updateEmailTemplate, updateSignature, updateSignatureStatus } from '../../../services/emailTemplateApi';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\nconst EMPTY = { name: '', module: '', action: '', clientId: '', description: '', toMail: [], ccMail: [], bccMail: [], subject: '', body: '', isActive: true };\nconst idOf = (record) => record?._id ?? record?.id;\n\nconst ONBOARDING_MAIL_PLACEHOLDER_GROUPS = [\n  {\n    moduleName: 'Onboarding Employer Details',\n    moduleLabel: 'Employer Details',\n    fields: [\n      { key: 'employerName', value: 'mailContext.employerName', label: 'Employer Name' },\n      { key: 'employerCompanyName', value: 'mailContext.employerCompanyName', label: 'Employer Company Name' },\n      { key: 'employerEmail', value: 'mailContext.employerEmail', label: 'Employer Email' },\n      { key: 'employerContactNumber', value: 'mailContext.employerContactNumber', label: 'Employer Contact Number' },\n      { key: 'employerSigningAuthorityName', value: 'mailContext.employerSigningAuthorityName', label: 'Employer Signing Authority Name' },\n      { key: 'employerSigningAuthorityEmail', value: 'mailContext.employerSigningAuthorityEmail', label: 'Employer Signing Authority Email' },\n      { key: 'employerSigningDocumentLink', value: 'mailContext.employerSigningDocumentLink', label: 'Employer Signing Documents Link' },\n    ],\n  },\n  {\n    moduleName: 'Onboarding Referral Details',\n    moduleLabel: 'Referral Details',\n    fields: [\n      { key: 'referralName', value: 'mailContext.referralName', label: 'Referral Name' },\n      { key: 'referralCompanyName', value: 'mailContext.referralCompanyName', label: 'Referral Company Name' },\n      { key: 'referralEmail', value: 'mailContext.referralEmail', label: 'Referral Email' },\n      { key: 'referralContactNumber', value: 'mailContext.referralContactNumber', label: 'Referral Contact Number' },\n      { key: 'referralRecruiterName', value: 'mailContext.referralRecruiterName', label: 'Referral Recruiter Name' },\n      { key: 'referralRecruiterEmail', value: 'mailContext.referralRecruiterEmail', label: 'Referral Recruiter Email' },\n      { key: 'referralSigningDocumentLink', value: 'mailContext.referralSigningDocumentLink', label: 'Referral Signing Documents Link' },\n    ],\n  },\n  {\n    moduleName: 'Onboarding Signing Documents',\n    moduleLabel: 'Signing Documents',\n    fields: [\n      { key: 'signingDocumentLink', value: 'mailContext.signingDocumentLink', label: 'Signing Documents Link' },\n    ],\n  },\n];\n\nfunction isOnboardingModule(moduleName) {\n  return String(moduleName ?? '').trim().toLowerCase() === 'onboarding';\n}\n\nfunction normalizePlaceholderPath(value) {\n  return String(value ?? '')\n    .trim()\n    .replace(/^{{\\s*/, '')\n    .replace(/\\s*}}$/, '')\n    .trim()\n    .replace(/^\\./, '')\n    .trim();\n}\n\nfunction extractPlaceholderKeys(...values) {\n  const keys = new Set();\n  values.forEach((value) => {\n    // Matches an optional leading dot so templates saved with the older\n    // \"{{.field}}\" syntax still have their placeholders recorded.\n    const regex = /{{\\.?([\\w.]+)}}/g;\n    let match;\n    while ((match = regex.exec(String(value ?? ''))) !== null) keys.add(match[1]);\n  });\n  return keys;\n}\n\nfunction TemplateEditor({ open, templateId, modules, clients, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [body, setBody] = useState('');\n  const [saving, setSaving] = useState(false);\n  const [loading, setLoading] = useState(false);\n  const [actionOptions, setActionOptions] = useState([]);\n  const [allFieldOptions, setAllFieldOptions] = useState([]);\n  const [preferredSources, setPreferredSources] = useState({});\n\n  async function loadModuleActions(module) {\n    if (!module) { setActionOptions([]); return; }\n    const configs = await getRowActionConfigs(module).catch(() => []);\n    const actions = new Map();\n    configs.forEach((config) => (config.rowActions ?? []).forEach((action) => {\n      if (action.key) actions.set(action.key, action.label || action.key);\n    }));\n    setActionOptions([...actions].map(([value, label]) => ({ value, label })));\n  }\n\n  async function loadAllModulePlaceholders() {\n    const groups = await Promise.all((modules ?? []).map(async (moduleOption) => {\n      const moduleName = moduleOption.value;\n      const fields = await getModuleFields(moduleName).catch(() => []);\n      return fields.map((field) => {\n        const rawKey = field.value ?? field.field ?? field.fieldKey ?? field.key ?? field.name;\n        const rawValue = field.path ?? field.value ?? field.field ?? field.fieldKey ?? field.key ?? field.name;\n        return {\n          key: normalizePlaceholderPath(rawKey),\n          value: normalizePlaceholderPath(rawValue),\n          label: field.label ?? field.fieldName ?? field.name ?? field.value,\n          moduleName,\n          moduleLabel: moduleOption.label ?? moduleName,\n        };\n      }).filter((field) => field.key && field.value);\n    }));\n    const flattened = groups.flat();\n\n    // Employer/referral/signing placeholders are runtime mail-context values,\n    // not normal module-data fields, so append them explicitly for onboarding.\n    const hasOnboarding = (modules ?? []).some((moduleOption) => isOnboardingModule(moduleOption.value));\n    if (hasOnboarding) {\n      ONBOARDING_MAIL_PLACEHOLDER_GROUPS.forEach((group) => {\n        group.fields.forEach((field) => {\n          if (!flattened.some((item) => item.key === field.key && item.value === field.value)) {\n            flattened.push({\n              ...field,\n              moduleName: group.moduleName,\n              moduleLabel: group.moduleLabel,\n            });\n          }\n        });\n      });\n    }\n\n    setAllFieldOptions(flattened);\n  }\n\n  useEffect(() => {\n    if (!open) return;\n    let cancelled = false;\n    queueMicrotask(() => {\n      setLoading(true);\n      loadAllModulePlaceholders().catch(() => {});\n      const request = templateId ? getEmailTemplate(templateId) : Promise.resolve(EMPTY);\n      request.then((item) => {\n        if (cancelled) return;\n        const values = {\n          ...EMPTY,\n          ...item,\n          action: item?.action ? [item.action] : [],\n          clientId: item?.clientIdStr || (typeof item?.clientId === 'string' ? item.clientId : ''),\n        };\n        form.setFieldsValue(values);\n        setBody(values.body || '');\n\n        const savedSources = {};\n        (item?.placeholders ?? item?.placeHolder ?? []).forEach((group) => {\n          (group?.holders ?? []).forEach((holder) => {\n            if (holder?.key) { const key = normalizePlaceholderPath(holder.key); savedSources[key] = { moduleName: group.moduleName, value: normalizePlaceholderPath(holder.value) }; }\n          });\n        });\n        setPreferredSources(savedSources);\n        loadModuleActions(values.module);\n      }).catch((error) => message.error(error?.message || 'Could not load template')).finally(() => { if (!cancelled) setLoading(false); });\n    });\n    return () => { cancelled = true; };\n  }, [form, open, templateId, modules]);\n\n  function registerPlaceholderSource(field) {\n    setPreferredSources((current) => ({\n      ...current,\n      [field.key]: { moduleName: field.moduleName, value: field.value },\n    }));\n  }\n\n  function insertPlaceholder(field) {\n    const token = `{{.${field.key}}}`;\n    registerPlaceholderSource(field);\n    setBody((current) => `${current}${current ? ' ' : ''}${token}`);\n    message.success(`Inserted ${token} from ${field.moduleLabel || field.moduleName}`);\n  }\n\n  function dragPlaceholder(event, field) {\n    const token = `{{.${field.key}}}`;\n    registerPlaceholderSource(field);\n    event.dataTransfer.setData('text/plain', token);\n    event.dataTransfer.effectAllowed = 'copy';\n  }\n\n  function resolvePlaceholderSource(key, selectedModule) {\n    const preferred = preferredSources[key];\n    if (preferred?.moduleName && preferred?.value) return preferred;\n\n    const matches = allFieldOptions.filter((field) => field.key === key);\n    const selectedModuleMatch = matches.find((field) => (\n      field.moduleName === selectedModule\n      || (isOnboardingModule(selectedModule) && String(field.moduleName).startsWith('Onboarding '))\n    ));\n    const field = selectedModuleMatch ?? matches[0];\n    return field ? { moduleName: field.moduleName, value: field.value } : null;\n  }\n\n  async function save() {\n    try {\n      const values = await form.validateFields();\n      if (!body.trim()) { message.error('Message body is required'); return; }\n      setSaving(true);\n\n      const used = extractPlaceholderKeys(values.subject, body);\n      const grouped = new Map();\n      used.forEach((key) => {\n        const source = resolvePlaceholderSource(key, values.module);\n        if (!source) return;\n        if (!grouped.has(source.moduleName)) grouped.set(source.moduleName, []);\n        grouped.get(source.moduleName).push({ key, value: source.value });\n      });\n\n      const placeholders = [...grouped].map(([moduleName, holders]) => ({ moduleName, holders }));\n      const payload = {\n        ...values,\n        action: Array.isArray(values.action) ? values.action.at(-1) : values.action,\n        body,\n        placeholders,\n      };\n      if (!payload.clientId) delete payload.clientId;\n      if (templateId) await updateEmailTemplate(templateId, payload);\n      else await createEmailTemplate(payload);\n      message.success(templateId ? 'Template updated' : 'Template created');\n      onSaved();\n    } catch (error) {\n      if (!error?.errorFields) message.error(error?.message || 'Could not save template');\n    } finally { setSaving(false); }\n  }\n\n  const placeholderGroups = useMemo(() => {\n    const groups = new Map();\n    allFieldOptions.forEach((field) => {\n      if (!groups.has(field.moduleName)) groups.set(field.moduleName, { label: field.moduleLabel, fields: [] });\n      groups.get(field.moduleName).fields.push(field);\n    });\n    return [...groups].map(([moduleName, group]) => ({ moduleName, ...group }));\n  }, [allFieldOptions]);\n\n  return (\n    <Drawer open={open} onClose={onClose} width=\"min(1320px, 98vw)\" title={templateId ? 'Edit email template' : 'New email template'} destroyOnClose\n      extra={<Space><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" loading={saving} onClick={save}>{templateId ? 'Update' : 'Create'}</Button></Space>}>\n      <style>{`\n        @media (max-width: 980px) {\n          .template-editor-workspace {\n            grid-template-columns: 1fr !important;\n          }\n          .template-placeholder-panel {\n            position: relative !important;\n            max-height: 420px !important;\n          }\n        }\n      `}</style>\n      <Form form={form} layout=\"vertical\" initialValues={EMPTY} disabled={loading} className=\"template-editor-form\">\n        <div className=\"template-editor-grid\">\n          <Form.Item name=\"name\" label=\"Template name\" rules={[{ required: true }]}><Input placeholder=\"Candidate introduction\" /></Form.Item>\n          <Form.Item name=\"module\" label=\"Module\" rules={[{ required: true }]}><Select showSearch optionFilterProp=\"label\" options={modules} onChange={(module) => { form.setFieldValue('action', ''); loadModuleActions(module); }} /></Form.Item>\n          <Form.Item name=\"action\" label=\"Action\" rules={[{ required: true }]}\n            tooltip={'Pick a Row Action, or TYPE a system action key. Not every email comes from a row action — the credentials mail sent when an employer\\'s recruiters are provisioned uses \"accountCreated\", which is raised by a workflow and so never appears in this list.'}>\n            <Select showSearch mode=\"tags\" maxCount={1} optionFilterProp=\"label\" options={actionOptions}\n              placeholder=\"Select a row action, or type a system key (e.g. accountCreated)\" />\n          </Form.Item>\n          <Form.Item name=\"clientId\" label=\"Client scope (optional)\"><Select allowClear showSearch optionFilterProp=\"label\" options={clients} placeholder=\"Available to every client\" /></Form.Item>\n        </div>\n        <Form.Item name=\"description\" label=\"Description\"><Input.TextArea rows={2} /></Form.Item>\n        <div className=\"template-editor-grid template-editor-grid--three\">\n          <Form.Item name=\"toMail\" label=\"Default To\"><Select mode=\"tags\" open={false} tokenSeparators={[',']} /></Form.Item>\n          <Form.Item name=\"ccMail\" label=\"Default Cc\"><Select mode=\"tags\" open={false} tokenSeparators={[',']} /></Form.Item>\n          <Form.Item name=\"bccMail\" label=\"Default Bcc\"><Select mode=\"tags\" open={false} tokenSeparators={[',']} /></Form.Item>\n        </div>\n        <div\n          className=\"template-editor-workspace\"\n          style={{\n            display: 'grid',\n            gridTemplateColumns: 'minmax(0, 1.2fr) minmax(360px, 0.8fr)',\n            gap: 20,\n            alignItems: 'start',\n            marginTop: 4,\n          }}\n        >\n          <div\n            className=\"template-editor-compose-pane\"\n            style={{\n              minWidth: 0,\n              padding: 16,\n              border: '1px solid #e5e7eb',\n              borderRadius: 10,\n              background: '#fff',\n            }}\n          >\n            <Text strong style={{ display: 'block', marginBottom: 12 }}>Email content</Text>\n            <Form.Item name=\"subject\" label=\"Subject\" rules={[{ required: true }]}>\n              <Input\n                placeholder=\"Email subject — drag placeholders here\"\n                onDragOver={(event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; }}\n              />\n            </Form.Item>\n            <Form.Item label=\"Message\" required style={{ marginBottom: 0 }}>\n              <div\n                onDragOver={(event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; }}\n                style={{ minHeight: 320 }}\n              >\n                <TipTapEditor\n                  value={body}\n                  onChange={setBody}\n                  placeholder=\"Write the reusable email body… Drag placeholders from the right panel.\"\n                />\n              </div>\n            </Form.Item>\n          </div>\n\n          <div\n            className=\"template-placeholder-panel\"\n            style={{\n              position: 'sticky',\n              top: 0,\n              maxHeight: 'calc(100vh - 190px)',\n              overflowY: 'auto',\n              padding: 16,\n              border: '1px solid #dbeafe',\n              borderRadius: 10,\n              background: '#f8fbff',\n            }}\n          >\n            <Text strong style={{ display: 'block' }}>All module placeholders</Text>\n            <Text type=\"secondary\" style={{ display: 'block', marginTop: 4 }}>\n              Drag a placeholder into Subject or Message. You can also click a placeholder to append it to the message.\n            </Text>\n            {placeholderGroups.map((group) => (\n              <div key={group.moduleName} style={{ marginTop: 14 }}>\n                <Text type=\"secondary\" strong>{group.label || group.moduleName}</Text>\n                <div className=\"template-placeholder-list\" style={{ marginTop: 6 }}>\n                  {group.fields.map((field) => (\n                    <Tooltip key={`${group.moduleName}:${field.key}:${field.value}`} title={`${field.label || field.key} · ${field.value}`}>\n                      <Tag\n                        color=\"blue\"\n                        draggable\n                        onDragStart={(event) => dragPlaceholder(event, field)}\n                        onClick={() => insertPlaceholder(field)}\n                        style={{ cursor: 'grab', userSelect: 'none', marginBottom: 6 }}\n                      >\n                        {`{{.${field.key}}}`}\n                      </Tag>\n                    </Tooltip>\n                  ))}\n                </div>\n              </div>\n            ))}\n            {!placeholderGroups.length && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=\"No module fields available\" />}\n          </div>\n        </div>\n\n        <Form.Item name=\"isActive\" label=\"Available in mail composer\" valuePropName=\"checked\" style={{ marginTop: 16 }}>\n          <Switch />\n        </Form.Item>\n      </Form>\n    </Drawer>\n  );\n}\n\nfunction EmailTemplatesPanel() {\n  const [items, setItems] = useState([]);\n  const [total, setTotal] = useState(0);\n  const [loading, setLoading] = useState(false);\n  const [search, setSearch] = useState('');\n  const [page, setPage] = useState(1);\n  const [pageSize, setPageSize] = useState(20);\n  const [modules, setModules] = useState([]);\n  const [clients, setClients] = useState([]);\n  const [editingId, setEditingId] = useState(null);\n  const [editorOpen, setEditorOpen] = useState(false);\n\n  const moduleOptions = useMemo(() => modules.map((item) => ({ value: item.key ?? item.module ?? item.value, label: item.label ?? item.name ?? item.key ?? item.module ?? item.value })).filter((item) => item.value), [modules]);\n\n  function load(nextPage = page, nextSize = pageSize, nextSearch = search) {\n    setLoading(true);\n    getEmailTemplates({ offset: (nextPage - 1) * nextSize, limit: nextSize, search: nextSearch })\n      .then(({ items: data, totalCount }) => { setItems(data); setTotal(totalCount); })\n      .catch((error) => message.error(error?.message || 'Could not load templates'))\n      .finally(() => setLoading(false));\n  }\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      load(1, pageSize, '');\n    });\n  }, []); // eslint-disable-line react-hooks/exhaustive-deps\n  useEffect(() => {\n    Promise.all([getAvailableModules(), getAdminClients({ limit: 200 })]).then(([moduleData, clientData]) => {\n      setModules(normalizeModuleOptions(moduleData).map(({ value, label }) => ({ key: value, label })));\n      setClients(clientData);\n    }).catch(() => {});\n  }, []);\n\n  async function toggleStatus(record, checked) {\n    const id = idOf(record);\n    try { await updateEmailTemplate(id, { ...record, isActive: checked }); setItems((current) => current.map((item) => idOf(item) === id ? { ...item, isActive: checked } : item)); }\n    catch (error) { message.error(error?.message || 'Could not update status'); }\n  }\n\n  async function remove(id) {\n    try { await deleteEmailTemplate(id); message.success('Template deleted'); load(1); setPage(1); }\n    catch (error) { message.error(error?.message || 'Could not delete template'); }\n  }\n\n  const columns = [\n    { title: 'Template', key: 'template', width: 300, ellipsis: true, render: (_, record) => <div className=\"admin-config-primary-cell templates-primary-cell\"><Text strong ellipsis={{ tooltip: record.name }}>{record.name}</Text><Text type=\"secondary\" ellipsis={{ tooltip: record.description || record.subject }}>{record.description || record.subject || 'No description'}</Text></div> },\n    { title: 'Module', dataIndex: 'module', key: 'module', width: 140, ellipsis: true, responsive: ['sm'], render: (value) => value ? <Tag color=\"blue\">{value}</Tag> : '—' },\n    { title: 'Action', dataIndex: 'action', key: 'action', width: 180, ellipsis: true, responsive: ['md'], render: (value) => value ? <Text code ellipsis={{ tooltip: value }}>{value}</Text> : '—' },\n    { title: 'Recipients', key: 'recipients', width: 130, responsive: ['lg'], render: (_, record) => `${(record.toMail?.length ?? 0) + (record.ccMail?.length ?? 0) + (record.bccMail?.length ?? 0)} defaults` },\n    { title: 'Active', dataIndex: 'isActive', key: 'active', width: 80, render: (value, record) => <Switch size=\"small\" checked={value} onChange={(checked) => toggleStatus(record, checked)} /> },\n    { title: '', key: 'actions', width: 84, fixed: 'right', render: (_, record) => <Space size={2}><Tooltip title=\"Edit\"><Button type=\"text\" icon={<EditOutlined />} onClick={() => { setEditingId(idOf(record)); setEditorOpen(true); }} /></Tooltip><Popconfirm title=\"Delete this template?\" onConfirm={() => remove(idOf(record))}><Button type=\"text\" danger icon={<DeleteOutlined />} /></Popconfirm></Space> },\n  ];\n\n  const clientOptions = clients.map((item) => ({ value: item._id ?? item.id, label: item.clientName ?? item.name ?? item._id })).filter((item) => item.value);\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard icon={<MailOutlined />} title=\"Email templates\" extra={<Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditingId(null); setEditorOpen(true); }}>New template</Button>}>\n        <div className=\"admin-accent-bar\" /><Text type=\"secondary\">Create reusable, module-aware email content. Modules, actions and placeholders are read from DB configuration.</Text>\n      </AppCard>\n      <AppCard title={`${total} template${total === 1 ? '' : 's'}`} extra={<Button icon={<ReloadOutlined />} onClick={() => load()}>Reload</Button>}>\n        <div className=\"admin-config-table-tools\"><Input allowClear prefix={<SearchOutlined />} placeholder=\"Search templates\" value={search} onChange={(event) => { const value = event.target.value; setSearch(value); setPage(1); load(1, pageSize, value); }} /></div>\n        <div className=\"templates-table-viewport\">\n          <Table rowKey={idOf} columns={columns} dataSource={items} loading={loading} className=\"fg-table\" size=\"small\" tableLayout=\"fixed\" sticky scroll={{ x: 914, y: 'calc(100vh - 410px)' }} pagination={{ current: page, pageSize, total, showSizeChanger: true, responsive: true, onChange: (nextPage, nextSize) => { setPage(nextPage); setPageSize(nextSize); load(nextPage, nextSize); } }} />\n        </div>\n      </AppCard>\n      <TemplateEditor open={editorOpen} templateId={editingId} modules={moduleOptions} clients={clientOptions} onClose={() => setEditorOpen(false)} onSaved={() => { setEditorOpen(false); load(); }} />\n    </div>\n  );\n}\n\nfunction SignatureEditor({ open, signatureId, onClose, onSaved }) {\n  const [name, setName] = useState('');\n  const [body, setBody] = useState('');\n  const [placeholderMeta, setPlaceholderMeta] = useState({ module: 'userSignature', keys: [] });\n  const [saving, setSaving] = useState(false);\n  const [loadingPlaceholders, setLoadingPlaceholders] = useState(false);\n\n  useEffect(() => {\n    if (!open) return;\n    let cancelled = false;\n    queueMicrotask(() => {\n      setLoadingPlaceholders(true);\n      Promise.all([\n        signatureId ? getSignature(signatureId) : Promise.resolve(null),\n        getSignaturePlaceholders(),\n      ]).then(([item, placeholders]) => {\n        if (cancelled) return;\n        setName(item?.signatureName ?? '');\n        setBody(item?.signature ?? '');\n        setPlaceholderMeta(placeholders ?? { module: 'userSignature', keys: [] });\n      }).catch(() => {\n        if (!cancelled) message.error('Could not load signature details');\n      }).finally(() => {\n        if (!cancelled) setLoadingPlaceholders(false);\n      });\n    });\n    return () => { cancelled = true; };\n  }, [open, signatureId]);\n\n  function insertPlaceholder(item) {\n    const token = `{{.${item.key}}}`;\n    setBody((current) => `${current}${current ? ' ' : ''}${token}`);\n  }\n\n  async function save() {\n    if (!name.trim()) return message.error('Signature name is required');\n    if (!body.trim()) return message.error('Signature content is required');\n    setSaving(true);\n    try {\n      const used = extractPlaceholderKeys(body);\n      const holders = (placeholderMeta.keys ?? [])\n        .filter((item) => used.has(item.key))\n        .map((item) => ({ key: item.key, value: item.value }));\n      const payload = {\n        signatureId,\n        signatureName: name,\n        signature: body,\n        signatureLogoPath: '',\n        placeHolder: holders.length ? [{ moduleName: placeholderMeta.module || 'userSignature', holders }] : [],\n      };\n      if (signatureId) await updateSignature(payload); else await createSignature(payload);\n      message.success(signatureId ? 'Signature updated' : 'Signature created');\n      onSaved();\n    } catch (error) { message.error(error?.message || 'Could not save signature'); }\n    finally { setSaving(false); }\n  }\n\n  const userPlaceholders = (placeholderMeta.keys ?? []).filter((item) => !['Role_id', 'Role_name', 'Reporting_manager'].includes(item.key));\n  const rolePlaceholders = (placeholderMeta.keys ?? []).filter((item) => ['Role_id', 'Role_name', 'Reporting_manager'].includes(item.key));\n  const renderPlaceholderList = (items) => (\n    <div className=\"template-placeholder-list\">\n      {items.map((item) => (\n        <Tooltip key={item.key} title={`Mongo field: ${item.value}`}>\n          <Tag color=\"blue\" style={{ cursor: 'pointer' }} onClick={() => insertPlaceholder(item)}>{`{{.${item.key}}}`}</Tag>\n        </Tooltip>\n      ))}\n    </div>\n  );\n\n  return <Drawer open={open} onClose={onClose} width=\"min(820px, 96vw)\" title={signatureId ? 'Edit signature' : 'New signature'} destroyOnClose\n    extra={<Space><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" loading={saving} onClick={save}>{signatureId ? 'Update' : 'Create'}</Button></Space>}>\n    <Form layout=\"vertical\">\n      <Form.Item label=\"Signature name\" required><Input value={name} onChange={(event) => setName(event.target.value)} /></Form.Item>\n      <Form.Item label=\"Signature content\" required><TipTapEditor value={body} onChange={setBody} placeholder=\"Create the reusable signature…\" /></Form.Item>\n      <div className=\"template-placeholder-panel\">\n        <Text strong>Signature placeholders</Text>\n        <Text type=\"secondary\">Click a placeholder to add it to the signature. Values resolve from MongoDB users and roles when mail is generated.</Text>\n        {loadingPlaceholders ? <Text type=\"secondary\">Loading placeholders…</Text> : <>\n          <div style={{ marginTop: 10 }}><Text strong>User details</Text>{renderPlaceholderList(userPlaceholders)}</div>\n          <div style={{ marginTop: 10 }}><Text strong>Role details</Text>{renderPlaceholderList(rolePlaceholders)}</div>\n          {!placeholderMeta.keys?.length && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=\"No signature placeholders available\" />}\n        </>}\n      </div>\n    </Form>\n  </Drawer>;\n}\n\nfunction SignatureTemplatesPanel() {\n  const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false);\n  const [search, setSearch] = useState(''); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(20);\n  const [editorOpen, setEditorOpen] = useState(false); const [editingId, setEditingId] = useState(null);\n  function load(nextPage = page, nextSize = pageSize, nextSearch = search) {\n    setLoading(true); getSignatures({ offset: (nextPage - 1) * nextSize, limit: nextSize, search: nextSearch })\n      .then(({ items: data, totalCount }) => { setItems(data); setTotal(totalCount); }).catch(() => message.error('Could not load signatures')).finally(() => setLoading(false));\n  }\n  useEffect(() => {\n    queueMicrotask(() => {\n      load(1, pageSize, '');\n    });\n  }, []); // eslint-disable-line react-hooks/exhaustive-deps\n  async function toggle(record, checked) { try { await updateSignatureStatus(record.signatureId, checked); setItems((current) => current.map((item) => item.signatureId === record.signatureId ? { ...item, isActive: checked } : item)); } catch { message.error('Could not update status'); } }\n  async function remove(id) { try { await deleteSignature(id); message.success('Signature deleted'); setPage(1); load(1); } catch { message.error('Could not delete signature'); } }\n  const columns = [\n    { title: 'Signature', dataIndex: 'templateName', key: 'name', width: 300, ellipsis: true, render: (value) => <Text strong ellipsis={{ tooltip: value }}>{value || 'Untitled signature'}</Text> },\n    { title: 'Created', dataIndex: 'createdDt', key: 'created', width: 150, responsive: ['md'], render: (value) => value ? new Date(value).toLocaleDateString() : '—' },\n    { title: 'Active', dataIndex: 'isActive', key: 'active', width: 80, render: (value, record) => <Switch size=\"small\" checked={value} onChange={(checked) => toggle(record, checked)} /> },\n    { title: '', key: 'actions', width: 84, fixed: 'right', render: (_, record) => <Space size={2}><Button type=\"text\" icon={<EditOutlined />} onClick={() => { setEditingId(record.signatureId); setEditorOpen(true); }} /><Popconfirm title=\"Delete this signature?\" onConfirm={() => remove(record.signatureId)}><Button type=\"text\" danger icon={<DeleteOutlined />} /></Popconfirm></Space> },\n  ];\n  return <div className=\"fg-section admin-config-section\"><AppCard icon={<MailOutlined />} title=\"Signature templates\" extra={<Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditingId(null); setEditorOpen(true); }}>New signature</Button>}><Text type=\"secondary\">Existing company and user signatures from the shared DB.</Text></AppCard><AppCard title={`${total} signature${total === 1 ? '' : 's'}`}><div className=\"admin-config-table-tools\"><Input allowClear prefix={<SearchOutlined />} value={search} placeholder=\"Search signatures\" onChange={(event) => { setSearch(event.target.value); setPage(1); load(1, pageSize, event.target.value); }} /></div><div className=\"templates-table-viewport\"><Table rowKey=\"signatureId\" dataSource={items} columns={columns} loading={loading} className=\"fg-table\" size=\"small\" tableLayout=\"fixed\" sticky scroll={{ x: 614, y: 'calc(100vh - 410px)' }} pagination={{ current: page, pageSize, total, responsive: true, onChange: (p, size) => { setPage(p); setPageSize(size); load(p, size); } }} /></div></AppCard><SignatureEditor open={editorOpen} signatureId={editingId} onClose={() => setEditorOpen(false)} onSaved={() => { setEditorOpen(false); load(); }} /></div>;\n}\n\nexport default function TemplatesSection() {\n  return <Tabs defaultActiveKey=\"email\" className=\"admin-config-tabs\" items={[\n    { key: 'email', label: 'Email templates', children: <EmailTemplatesPanel /> },\n    { key: 'signature', label: 'Signatures', children: <SignatureTemplatesPanel /> },\n  ]} />;\n}\n","import { useEffect, useState } from 'react';\nimport { Button, Drawer, Form, Input, Popconfirm, Space, Switch, Table, Tooltip, Typography, message } from 'antd';\nimport { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, ThunderboltOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport { deleteAiServiceConfig, getAiServiceConfigs, saveAiServiceConfig } from '../../../services/adminApi';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\nconst EMPTY = { serviceKey: '', label: '', baseUrl: '', authHeader: '', authValue: '', enabled: true };\n\nfunction ServiceEditor({ open, service, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n\n  useEffect(() => {\n    if (!open) return;\n    form.setFieldsValue({ ...EMPTY, ...service, authValue: '' });\n  }, [open, service, form]);\n\n  async function save() {\n    try {\n      const values = await form.validateFields();\n      setSaving(true);\n      await saveAiServiceConfig(values);\n      message.success('AI service saved');\n      onSaved();\n    } catch (error) {\n      if (!error?.errorFields) message.error(error?.message || 'Could not save AI service');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  return (\n    <Drawer\n      open={open}\n      onClose={onClose}\n      width=\"min(560px, 96vw)\"\n      title={service ? 'Edit AI service' : 'New AI service'}\n      destroyOnClose\n      extra={<Space><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" loading={saving} onClick={save}>Save</Button></Space>}\n    >\n      <Form form={form} layout=\"vertical\" initialValues={EMPTY}>\n        <Form.Item name=\"serviceKey\" label=\"Service Key\" rules={[{ required: true, message: 'Service key is required' }]}\n          tooltip=\"Referenced by an AI Action's Service Key on any form field (e.g. pyOps).\">\n          <Input placeholder=\"pyOps\" disabled={Boolean(service)} className=\"fg-mono-input\" />\n        </Form.Item>\n        <Form.Item name=\"label\" label=\"Label\"><Input placeholder=\"Resume/JD Parsing Service\" /></Form.Item>\n        <Form.Item name=\"baseUrl\" label=\"Base URL\" rules={[{ required: true, message: 'Base URL is required' }]}>\n          <Input placeholder=\"https://ai.example.com\" className=\"fg-mono-input\" />\n        </Form.Item>\n        <Form.Item name=\"authHeader\" label=\"Auth Header (optional)\"><Input placeholder=\"x-api-key\" className=\"fg-mono-input\" /></Form.Item>\n        <Form.Item name=\"authValue\" label=\"Auth Value\" tooltip=\"Write-only — leave blank to keep the currently saved value.\">\n          <Input.Password placeholder={service ? 'Unchanged' : ''} />\n        </Form.Item>\n        <Form.Item name=\"enabled\" label=\"Enabled\" valuePropName=\"checked\"><Switch /></Form.Item>\n      </Form>\n    </Drawer>\n  );\n}\n\nexport default function AiServiceSettingsSection() {\n  const [items, setItems] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [editorOpen, setEditorOpen] = useState(false);\n  const [editing, setEditing] = useState(null);\n\n  function load() {\n    setLoading(true);\n    getAiServiceConfigs()\n      .then((data) => setItems(Array.isArray(data) ? data : []))\n      .catch((error) => message.error(error?.message || 'Could not load AI services'))\n      .finally(() => setLoading(false));\n  }\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      load();\n    });\n  }, []);\n\n  async function toggleEnabled(record, enabled) {\n    try {\n      await saveAiServiceConfig({ ...record, enabled });\n      setItems((current) => current.map((item) => item.serviceKey === record.serviceKey ? { ...item, enabled } : item));\n    } catch (error) {\n      message.error(error?.message || 'Could not update AI service');\n    }\n  }\n\n  async function remove(serviceKey) {\n    try {\n      await deleteAiServiceConfig(serviceKey);\n      message.success('AI service deleted');\n      load();\n    } catch (error) {\n      message.error(error?.message || 'Could not delete AI service');\n    }\n  }\n\n  const columns = [\n    {\n      title: 'Service', key: 'service', render: (_, record) => (\n        <div className=\"admin-config-primary-cell\">\n          <Text strong>{record.label || record.serviceKey}</Text>\n          <Text type=\"secondary\" code>{record.serviceKey}</Text>\n        </div>\n      ),\n    },\n    { title: 'Base URL', dataIndex: 'baseUrl', key: 'baseUrl', ellipsis: true, render: (value) => <Text code ellipsis={{ tooltip: value }}>{value}</Text> },\n    { title: 'Auth Header', dataIndex: 'authHeader', key: 'authHeader', width: 140, render: (value) => value || '—' },\n    { title: 'Enabled', dataIndex: 'enabled', key: 'enabled', width: 90, render: (value, record) => <Switch size=\"small\" checked={value} onChange={(checked) => toggleEnabled(record, checked)} /> },\n    {\n      title: '', key: 'actions', width: 84, fixed: 'right', render: (_, record) => (\n        <Space size={2}>\n          <Tooltip title=\"Edit\"><Button type=\"text\" icon={<EditOutlined />} onClick={() => { setEditing(record); setEditorOpen(true); }} /></Tooltip>\n          <Popconfirm title=\"Delete this AI service?\" onConfirm={() => remove(record.serviceKey)}>\n            <Button type=\"text\" danger icon={<DeleteOutlined />} />\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard\n        icon={<ThunderboltOutlined />}\n        title=\"AI Services\"\n        extra={<Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditing(null); setEditorOpen(true); }}>New service</Button>}\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\">\n          Register the AI/automation backends that admin-configured \"AI Actions\" (Generate/Parse-style buttons on\n          any form field) call. A field's AI Action names a Service Key here — no URL is ever hardcoded in the app.\n        </Text>\n      </AppCard>\n      <AppCard title={`${items.length} service${items.length === 1 ? '' : 's'}`} extra={<Button icon={<ReloadOutlined />} onClick={load}>Reload</Button>}>\n        <Table rowKey=\"serviceKey\" columns={columns} dataSource={items} loading={loading} className=\"fg-table\" size=\"small\" />\n      </AppCard>\n      <ServiceEditor open={editorOpen} service={editing} onClose={() => setEditorOpen(false)} onSaved={() => { setEditorOpen(false); load(); }} />\n    </div>\n  );\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport {\n  Alert, Button, Col, Drawer, Form, Input, Popconfirm, Radio, Row, Select,\n  Space, Switch, Table, Tag, Typography, message,\n} from 'antd';\nimport {\n  ApiOutlined, DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined,\n} from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport {\n  deleteIntegrationConfig,\n  getIntegrationConfigs,\n  saveIntegrationConfig,\n  testIntegrationConnection,\n} from '../../../services/adminApi';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\nconst EMPTY = {\n  integrationKey: '', label: '', category: 'GENERAL', updateMethod: 'MANUAL',\n  enabled: true, provider: '', baseUrl: '', authType: 'API_KEY',\n  authHeader: 'x-api-key', authValue: '', clientId: '', clientSecret: '',\n  tokenUrl: '', createPath: '', statusPath: '', testPath: '', webhookSecret: '',\n  targetModule: '', targetField: '', stageMatchField: '', stageMatchValue: '',\n  stageStatusField: '', providerStatusPath: '', providerReferencePath: '',\n  statusMappings: [{ providerStatus: '', applicationStatus: '' }],\n};\nconst AUTH_OPTIONS = [\n  { label: 'API Key', value: 'API_KEY' },\n  { label: 'Bearer Token', value: 'BEARER_TOKEN' },\n  { label: 'Basic Authentication', value: 'BASIC_AUTH' },\n  { label: 'OAuth 2.0 Client Credentials', value: 'OAUTH2_CLIENT_CREDENTIALS' },\n];\n\nfunction integrationPayload(values) {\n  const statusValues = Object.fromEntries(\n    (values.statusMappings ?? [])\n      .filter((row) => row?.providerStatus && row?.applicationStatus)\n      .map((row) => [row.providerStatus.trim(), row.applicationStatus.trim()]),\n  );\n  const payload = {\n    ...values,\n    statusMapping: values.updateMethod === 'API' ? {\n      targetModule: values.targetModule,\n      targetField: values.targetField,\n      stageMatchField: values.stageMatchField,\n      stageMatchValue: values.stageMatchValue,\n      stageStatusField: values.stageStatusField,\n      providerStatusPath: values.providerStatusPath,\n      providerReferencePath: values.providerReferencePath,\n      values: statusValues,\n    } : undefined,\n  };\n  [\n    'statusMappings', 'targetModule', 'targetField', 'stageMatchField',\n    'stageMatchValue', 'stageStatusField', 'providerStatusPath',\n    'providerReferencePath',\n  ].forEach((key) => delete payload[key]);\n  return payload;\n}\n\nfunction IntegrationEditor({ open, integration, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const [testing, setTesting] = useState(false);\n  const method = Form.useWatch('updateMethod', form);\n  const authType = Form.useWatch('authType', form);\n  const apiMode = method === 'API';\n  const oauth = authType === 'OAUTH2_CLIENT_CREDENTIALS';\n\n  useEffect(() => {\n    if (!open) return;\n    const mapping = integration?.statusMapping ?? {};\n    form.setFieldsValue({\n      ...EMPTY, ...integration, authValue: '', clientSecret: '', webhookSecret: '',\n      targetModule: mapping.targetModule ?? '',\n      targetField: mapping.targetField ?? '',\n      stageMatchField: mapping.stageMatchField ?? '',\n      stageMatchValue: mapping.stageMatchValue ?? '',\n      stageStatusField: mapping.stageStatusField ?? '',\n      providerStatusPath: mapping.providerStatusPath ?? '',\n      providerReferencePath: mapping.providerReferencePath ?? '',\n      statusMappings: Object.entries(mapping.values ?? {}).map(([providerStatus, applicationStatus]) => ({\n        providerStatus,\n        applicationStatus,\n      })).concat(Object.keys(mapping.values ?? {}).length ? [] : [{ providerStatus: '', applicationStatus: '' }]),\n    });\n  }, [form, integration, open]);\n\n  async function save() {\n    try {\n      const values = await form.validateFields();\n      const payload = integrationPayload(values);\n      setSaving(true);\n      await saveIntegrationConfig(payload);\n      message.success('Integration saved');\n      onSaved();\n    } catch (error) {\n      if (!error?.errorFields) message.error(error?.message || 'Could not save integration');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  async function testConnection() {\n    try {\n      const values = await form.validateFields([\n        'integrationKey', 'baseUrl', 'testPath', 'authType', 'authHeader',\n        'authValue', 'clientId', 'clientSecret', 'tokenUrl',\n      ]);\n      setTesting(true);\n      const result = await testIntegrationConnection(integrationPayload({\n        ...form.getFieldsValue(true),\n        ...values,\n      }));\n      message.success(result?.message || `Connection successful${result?.statusCode ? ` (${result.statusCode})` : ''}`);\n    } catch (error) {\n      if (!error?.errorFields) message.error(error?.message || 'Connection test failed');\n    } finally {\n      setTesting(false);\n    }\n  }\n\n  return (\n    <Drawer\n      open={open}\n      onClose={onClose}\n      width=\"min(680px, 96vw)\"\n      title={integration ? `Edit ${integration.label}` : 'Add Integration'}\n      destroyOnClose\n      extra={(\n        <Space>\n          {apiMode && <Button loading={testing} onClick={testConnection}>Test Connection</Button>}\n          <Button onClick={onClose}>Cancel</Button>\n          <Button type=\"primary\" loading={saving} onClick={save}>Save</Button>\n        </Space>\n      )}\n    >\n      <Form form={form} layout=\"vertical\" initialValues={EMPTY}>\n        <Row gutter={16}>\n          <Col xs={24} md={12}>\n            <Form.Item name=\"label\" label=\"Integration Name\" rules={[{ required: true }]}>\n              <Input placeholder=\"Background Check\" />\n            </Form.Item>\n          </Col>\n          <Col xs={24} md={12}>\n            <Form.Item\n              name=\"integrationKey\"\n              label=\"Integration Key\"\n              rules={[\n                { required: true },\n                { pattern: /^[a-z][a-z0-9_-]{1,63}$/, message: 'Use lowercase letters, numbers, _ or -' },\n              ]}\n            >\n              <Input placeholder=\"bgc\" disabled={Boolean(integration)} />\n            </Form.Item>\n          </Col>\n        </Row>\n        <Row gutter={16}>\n          <Col xs={24} md={12}>\n            <Form.Item name=\"category\" label=\"Category\">\n              <Select options={[\n                { value: 'ONBOARDING', label: 'Onboarding' },\n                { value: 'HRMS', label: 'HRMS' },\n                { value: 'PAYROLL', label: 'Payroll' },\n                { value: 'ESIGNATURE', label: 'E-Signature' },\n                { value: 'VMS', label: 'VMS' },\n                { value: 'GENERAL', label: 'General / Custom' },\n              ]} />\n            </Form.Item>\n          </Col>\n          <Col xs={24} md={12}>\n            <Form.Item name=\"enabled\" label=\"Enabled\" valuePropName=\"checked\"><Switch /></Form.Item>\n          </Col>\n        </Row>\n        <Form.Item name=\"updateMethod\" label=\"Update Method\" rules={[{ required: true }]}>\n          <Radio.Group optionType=\"button\" buttonStyle=\"solid\" options={[\n            { label: 'Manual Update', value: 'MANUAL' },\n            { label: 'API Integration', value: 'API' },\n          ]} />\n        </Form.Item>\n        {!apiMode && <Alert type=\"info\" showIcon message=\"This integration will use manual updates.\" />}\n        {apiMode && (\n          <>\n            <Alert\n              type={integration?.credentialsConfigured ? 'success' : 'warning'}\n              showIcon\n              message={integration?.credentialsConfigured ? 'Credentials configured' : 'Credentials required'}\n              description=\"Secrets are write-only. Leave a secret blank while editing to keep its current value.\"\n              style={{ marginBottom: 16 }}\n            />\n            <Row gutter={16}>\n              <Col xs={24} md={12}><Form.Item name=\"provider\" label=\"Provider\" rules={[{ required: true }]}><Input placeholder=\"Provider name\" /></Form.Item></Col>\n              <Col xs={24} md={12}><Form.Item name=\"baseUrl\" label=\"API Base URL\" rules={[{ required: true, type: 'url' }]}><Input placeholder=\"https://api.provider.com\" /></Form.Item></Col>\n              <Col xs={24} md={12}><Form.Item name=\"createPath\" label=\"Create/Submit Path\" rules={[{ required: true }]}><Input placeholder=\"/v1/requests\" /></Form.Item></Col>\n              <Col xs={24} md={12}><Form.Item name=\"statusPath\" label=\"Status Path\" rules={[{ required: true }]} tooltip=\"Use {referenceId} as a placeholder.\"><Input placeholder=\"/v1/requests/{referenceId}\" /></Form.Item></Col>\n              <Col xs={24} md={12}><Form.Item name=\"testPath\" label=\"Test Connection Path\" rules={[{ required: true }]} tooltip=\"A safe GET endpoint used only to validate URL and credentials.\"><Input placeholder=\"/v1/health\" /></Form.Item></Col>\n            </Row>\n            <Form.Item name=\"authType\" label=\"Authentication Type\" rules={[{ required: true }]}><Select options={AUTH_OPTIONS} /></Form.Item>\n            {oauth ? (\n              <Row gutter={16}>\n                <Col xs={24} md={12}><Form.Item name=\"clientId\" label=\"Client ID\" rules={[{ required: true }]}><Input /></Form.Item></Col>\n                <Col xs={24} md={12}><Form.Item name=\"clientSecret\" label=\"Client Secret\"><Input.Password placeholder={integration?.credentialsConfigured ? 'Unchanged' : 'Required'} /></Form.Item></Col>\n                <Col xs={24}><Form.Item name=\"tokenUrl\" label=\"Token URL\" rules={[{ required: true, type: 'url' }]}><Input /></Form.Item></Col>\n              </Row>\n            ) : (\n              <Row gutter={16}>\n                <Col xs={24} md={12}><Form.Item name=\"authHeader\" label=\"Authentication Header\"><Input placeholder=\"x-api-key\" /></Form.Item></Col>\n                <Col xs={24} md={12}><Form.Item name=\"authValue\" label=\"API Credential\"><Input.Password placeholder={integration?.credentialsConfigured ? 'Unchanged' : 'Required'} /></Form.Item></Col>\n              </Row>\n            )}\n            <Form.Item name=\"webhookSecret\" label=\"Webhook Signing Secret (optional)\"><Input.Password placeholder={integration?.webhookConfigured ? 'Unchanged' : ''} /></Form.Item>\n            <AppCard title=\"Status Mapping\">\n              <Text type=\"secondary\">\n                Map a status from the provider response into a module field or a matching workflow stage.\n              </Text>\n              <Row gutter={16} style={{ marginTop: 16 }}>\n                <Col xs={24} md={12}>\n                  <Form.Item name=\"targetModule\" label=\"Target Module\" rules={[{ required: true }]}>\n                    <Input placeholder=\"onboarding\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item name=\"targetField\" label=\"Target Field\" rules={[{ required: true }]} tooltip=\"Use stages for a stage-array update, or a direct field name.\">\n                    <Input placeholder=\"stages\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item name=\"providerStatusPath\" label=\"Provider Status JSON Path\" rules={[{ required: true }]}>\n                    <Input placeholder=\"data.status\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item name=\"providerReferencePath\" label=\"Provider Reference JSON Path\">\n                    <Input placeholder=\"data.id\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={8}>\n                  <Form.Item name=\"stageMatchField\" label=\"Stage Match Field\">\n                    <Input placeholder=\"stageCode\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={8}>\n                  <Form.Item name=\"stageMatchValue\" label=\"Stage Match Value\">\n                    <Input placeholder=\"BGC\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={8}>\n                  <Form.Item name=\"stageStatusField\" label=\"Stage Status Field\">\n                    <Input placeholder=\"status\" />\n                  </Form.Item>\n                </Col>\n              </Row>\n              <Text strong>Status Values</Text>\n              <Form.List name=\"statusMappings\">\n                {(fields, { add, remove }) => (\n                  <Space direction=\"vertical\" style={{ width: '100%', marginTop: 8 }}>\n                    {fields.map((field) => (\n                      <Row gutter={12} key={field.key}>\n                        <Col flex=\"1 1 220px\">\n                          <Form.Item {...field} name={[field.name, 'providerStatus']} rules={[{ required: true, message: 'Provider status is required' }]}>\n                            <Input placeholder=\"Provider status, e.g. completed\" />\n                          </Form.Item>\n                        </Col>\n                        <Col flex=\"1 1 220px\">\n                          <Form.Item {...field} name={[field.name, 'applicationStatus']} rules={[{ required: true, message: 'Application status is required' }]}>\n                            <Input placeholder=\"Zinnext status, e.g. CLEARED\" />\n                          </Form.Item>\n                        </Col>\n                        <Col><Button danger onClick={() => remove(field.name)}>Remove</Button></Col>\n                      </Row>\n                    ))}\n                    <Button type=\"dashed\" icon={<PlusOutlined />} onClick={() => add({ providerStatus: '', applicationStatus: '' })}>\n                      Add Status Mapping\n                    </Button>\n                  </Space>\n                )}\n              </Form.List>\n            </AppCard>\n          </>\n        )}\n      </Form>\n    </Drawer>\n  );\n}\n\nexport default function IntegrationSettingsSection() {\n  const [items, setItems] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [editorOpen, setEditorOpen] = useState(false);\n  const [editing, setEditing] = useState(null);\n\n  const load = useCallback(() => {\n    setLoading(true);\n    getIntegrationConfigs()\n      .then((rows) => setItems(Array.isArray(rows) ? rows : []))\n      .catch((error) => message.error(error?.message || 'Could not load integrations'))\n      .finally(() => setLoading(false));\n  }, []);\n\n  useEffect(() => { queueMicrotask(load); }, [load]);\n\n  async function remove(key) {\n    try {\n      await deleteIntegrationConfig(key);\n      message.success('Integration deleted');\n      load();\n    } catch (error) {\n      message.error(error?.message || 'Could not delete integration');\n    }\n  }\n\n  const columns = [\n    { title: 'Integration', key: 'name', render: (_, row) => <div className=\"admin-config-primary-cell\"><Text strong>{row.label}</Text><Text type=\"secondary\" code>{row.integrationKey}</Text></div> },\n    { title: 'Category', dataIndex: 'category', width: 130, render: (value) => value || 'GENERAL' },\n    { title: 'Method', dataIndex: 'updateMethod', width: 110, render: (value) => <Tag color={value === 'API' ? 'blue' : 'default'}>{value}</Tag> },\n    { title: 'Provider', dataIndex: 'provider', render: (value) => value || '—' },\n    { title: 'Enabled', dataIndex: 'enabled', width: 90, render: (value) => <Tag color={value ? 'green' : 'default'}>{value ? 'Yes' : 'No'}</Tag> },\n    { title: '', key: 'actions', width: 90, render: (_, row) => <Space size={2}><Button type=\"text\" icon={<EditOutlined />} onClick={() => { setEditing(row); setEditorOpen(true); }} /><Popconfirm title=\"Delete this integration?\" onConfirm={() => remove(row.integrationKey)}><Button type=\"text\" danger icon={<DeleteOutlined />} /></Popconfirm></Space> },\n  ];\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard\n        icon={<ApiOutlined />}\n        title=\"Integrations\"\n        extra={<Space><Button icon={<ReloadOutlined />} onClick={load}>Reload</Button><Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditing(null); setEditorOpen(true); }}>Add Integration</Button></Space>}\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\">Configure reusable manual or API integrations for onboarding, payroll, e-signature, VMS, HRMS, and custom workflows.</Text>\n      </AppCard>\n      <AppCard title={`${items.length} integration${items.length === 1 ? '' : 's'}`}>\n        <Table rowKey=\"integrationKey\" columns={columns} dataSource={items} loading={loading} size=\"small\" className=\"fg-table\" />\n      </AppCard>\n      <IntegrationEditor open={editorOpen} integration={editing} onClose={() => setEditorOpen(false)} onSaved={() => { setEditorOpen(false); load(); }} />\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n  Alert,\n  Badge,\n  Button,\n  Empty,\n  Input,\n  InputNumber,\n  Modal,\n  Radio,\n  Select,\n  Space,\n  Spin,\n  Switch,\n  Table,\n  Tabs,\n  Tag,\n  Tooltip,\n  Typography,\n  message,\n} from 'antd';\nimport {\n  ApartmentOutlined,\n  DatabaseOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  PlusOutlined,\n  SaveOutlined,\n  ThunderboltOutlined,\n} from '@ant-design/icons';\nimport {\n  getAvailableModules,\n  getModuleAutomations,\n  saveModuleAutomations,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\nimport AppCard from '../../../components/cards/AppCard';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\n// =============================================================================\n// Automations — the Admin surface for models.ModuleStrategies (Be_Auth_DevOps).\n// This is the config-driven replacement for logic legacy services used to\n// hardcode in Go: reference-id generation, duplicate checks, cross-module\n// field snapshots, reporting-chain hierarchy expansion (assign a job up to\n// admin, notify a submission up the whole chain), board updates, mail,\n// cache invalidation. Nothing here is module-specific — every field maps\n// directly onto models.ModuleConfig.Gateway / .Strategies.\n// =============================================================================\n\n// ── Shared value-map row editors ────────────────────────────────────────────\n// Two flavours: PlainFieldMapRows keeps values as plain strings (used for\n// FieldMap-type maps: sourceField -> destField, both dot-paths, never\n// templated). KeyValueRows attempts JSON.parse on save so a value can be a\n// literal (number/bool/array/object) OR a \"{{field.path}}\" template token —\n// exactly what resolveTemplateValue on the backend expects.\n\nfunction PlainFieldMapRows({ rows, onChange, keyPlaceholder, valuePlaceholder }) {\n  const update = (i, patch) => onChange(rows.map((r, idx) => (idx === i ? { ...r, ...patch } : r)));\n  const remove = (i) => onChange(rows.filter((_, idx) => idx !== i));\n  const add = () => onChange([...rows, { key: '', value: '' }]);\n  return (\n    <div>\n      {rows.map((r, i) => (\n        <div key={i} style={{ display: 'flex', gap: 6, marginTop: 6 }}>\n          <Input size=\"small\" style={{ flex: 1 }} placeholder={keyPlaceholder} value={r.key} onChange={(e) => update(i, { key: e.target.value })} className=\"fg-mono-input\" />\n          <span style={{ color: '#94a3b8', alignSelf: 'center' }}>→</span>\n          <Input size=\"small\" style={{ flex: 1 }} placeholder={valuePlaceholder} value={r.value} onChange={(e) => update(i, { value: e.target.value })} className=\"fg-mono-input\" />\n          <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} onClick={() => remove(i)} />\n        </div>\n      ))}\n      <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} style={{ marginTop: 6 }} onClick={add}>Add</Button>\n    </div>\n  );\n}\n\nfunction KeyValueRows({ rows, onChange, keyPlaceholder = 'field', valuePlaceholder = 'literal or {{field.path}}' }) {\n  const update = (i, patch) => onChange(rows.map((r, idx) => (idx === i ? { ...r, ...patch } : r)));\n  const remove = (i) => onChange(rows.filter((_, idx) => idx !== i));\n  const add = () => onChange([...rows, { key: '', value: '' }]);\n  return (\n    <div>\n      {rows.map((r, i) => (\n        <div key={i} style={{ display: 'flex', gap: 6, marginTop: 6 }}>\n          <Input size=\"small\" style={{ flex: 1 }} placeholder={keyPlaceholder} value={r.key} onChange={(e) => update(i, { key: e.target.value })} className=\"fg-mono-input\" />\n          <Input size=\"small\" style={{ flex: 1.6 }} placeholder={valuePlaceholder} value={r.value} onChange={(e) => update(i, { value: e.target.value })} className=\"fg-mono-input\" />\n          <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} onClick={() => remove(i)} />\n        </div>\n      ))}\n      <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} style={{ marginTop: 6 }} onClick={add}>Add</Button>\n      <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 4 }}>\n        Values are read as JSON when possible (true, 123, [\"a\",\"b\"]) — otherwise kept as literal text.\n        Use <code>{'{{field.path}}'}</code> to reference a payload field, or <code>{'{{now}}'}</code> for the current time.\n      </Text>\n    </div>\n  );\n}\n\nfunction objToPlainRows(obj) {\n  return Object.entries(obj ?? {}).map(([key, value]) => ({ key, value: String(value ?? '') }));\n}\n\nfunction plainRowsToObj(rows) {\n  const out = {};\n  for (const r of rows ?? []) {\n    if (!r.key?.trim()) continue;\n    out[r.key.trim()] = r.value ?? '';\n  }\n  return out;\n}\n\nfunction objToRows(obj) {\n  return Object.entries(obj ?? {}).map(([key, value]) => ({\n    key,\n    value: typeof value === 'string' ? value : JSON.stringify(value),\n  }));\n}\n\nfunction rowsToObj(rows) {\n  const out = {};\n  for (const r of rows ?? []) {\n    if (!r.key?.trim()) continue;\n    let v = r.value;\n    if (typeof v === 'string') {\n      const trimmed = v.trim();\n      if (trimmed !== '') {\n        try { v = JSON.parse(trimmed); } catch { /* keep as raw string — a template token or plain literal */ }\n      }\n    }\n    out[r.key.trim()] = v;\n  }\n  return out;\n}\n\n// ── Denormalize Rule Drawer ─────────────────────────────────────────────────\nfunction DenormalizeDrawer({ open, rule, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    sourceModule: '', sourceIdField: '', required: false,\n    ...(rule ?? {}),\n    fieldMapRows: objToPlainRows(rule?.fieldMap),\n  }));\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.sourceModule?.trim()) return message.error('Source module is required');\n    if (!draft.sourceIdField?.trim()) return message.error('Source id field is required');\n    const { fieldMapRows, ...rest } = draft;\n    onSave({ ...rest, fieldMap: plainRowsToObj(fieldMapRows) });\n  };\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={640} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><DatabaseOutlined /> {rule ? 'Edit Denormalize Rule' : 'New Denormalize Rule'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Source module</Text>\n            <Input size=\"small\" placeholder=\"job\" value={draft.sourceModule ?? ''} onChange={(e) => set('sourceModule', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Source id field (on THIS payload)</Text>\n            <Input size=\"small\" placeholder=\"jobId\" value={draft.sourceIdField ?? ''} onChange={(e) => set('sourceIdField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={!!draft.required} onChange={(v) => set('required', v)} />\n          <Text style={{ fontSize: 13 }}>Required — block the write if the source record can't be found</Text>\n        </div>\n        <div style={{ marginTop: 16 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Field map (source field → this payload's field)</Text>\n          <PlainFieldMapRows\n            rows={draft.fieldMapRows ?? []}\n            onChange={(rows) => set('fieldMapRows', rows)}\n            keyPlaceholder=\"jobTitle\"\n            valuePlaceholder=\"jobTitle\"\n          />\n        </div>\n      </div>\n    </Modal>\n  );\n}\n\n// ── Array Enrich Drawer ──────────────────────────────────────────────────────\nfunction ArrayEnrichDrawer({ open, rule, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    sourceField: '', targetField: '', sourceCollection: '', idField: '', idOutputKey: '', stampNow: '',\n    ...(rule ?? {}),\n    fieldMapRows: objToPlainRows(rule?.fieldMap),\n  }));\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.sourceField?.trim()) return message.error('Source field is required');\n    if (!draft.targetField?.trim()) return message.error('Target field is required');\n    const { fieldMapRows, ...rest } = draft;\n    onSave({ ...rest, fieldMap: plainRowsToObj(fieldMapRows) });\n  };\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={640} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><ApartmentOutlined /> {rule ? 'Edit Array Enrichment' : 'New Array Enrichment'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Source field (array of ids on this payload)</Text>\n            <Input size=\"small\" placeholder=\"recruitersData\" value={draft.sourceField ?? ''} onChange={(e) => set('sourceField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Target field (enriched array written here)</Text>\n            <Input size=\"small\" placeholder=\"recruiters\" value={draft.targetField ?? ''} onChange={(e) => set('targetField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Source collection</Text>\n            <Input size=\"small\" placeholder=\"users (default)\" value={draft.sourceCollection ?? ''} onChange={(e) => set('sourceCollection', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Id field on that collection</Text>\n            <Input size=\"small\" placeholder=\"legacyUserId (default)\" value={draft.idField ?? ''} onChange={(e) => set('idField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n        <div style={{ marginTop: 16 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Field map (source collection field → output key)</Text>\n          <PlainFieldMapRows\n            rows={draft.fieldMapRows ?? []}\n            onChange={(rows) => set('fieldMapRows', rows)}\n            keyPlaceholder=\"firstName\"\n            valuePlaceholder=\"recruiterName\"\n          />\n        </div>\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Also write the matched id as</Text>\n            <Input size=\"small\" placeholder=\"recruiterId\" value={draft.idOutputKey ?? ''} onChange={(e) => set('idOutputKey', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Also stamp the current time as</Text>\n            <Input size=\"small\" placeholder=\"assignedDateTime\" value={draft.stampNow ?? ''} onChange={(e) => set('stampNow', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n      </div>\n    </Modal>\n  );\n}\n\n// ── File Field Map Drawer ─────────────────────────────────────────────────────\nfunction FileFieldMapDrawer({ open, rule, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    sourceField: '', targetField: '', uploadedFileNameField: '', uniqueNameField: '',\n    uploadedAtField: '', uploadedByField: '', arrayMode: false, nameFromField: '', nameOutputField: '',\n    historyField: '', historySnapshotKey: '', historyReason: '',\n    ...(rule ?? {}),\n    staticFieldRows: objToPlainRows(rule?.staticFields),\n    arrayFieldNameRows: objToPlainRows(rule?.arrayFieldNames),\n  }));\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.sourceField?.trim()) return message.error('Source field (the multipart upload key) is required');\n    if (!draft.targetField?.trim()) return message.error('Target field is required');\n    const { staticFieldRows, arrayFieldNameRows, ...rest } = draft;\n    onSave({\n      ...rest,\n      staticFields: plainRowsToObj(staticFieldRows),\n      arrayFieldNames: plainRowsToObj(arrayFieldNameRows),\n    });\n  };\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={760} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><DatabaseOutlined /> {rule ? 'Edit File Field Map' : 'New File Field Map'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 10 }}>\n          Turns one uploaded file field into a nested object (or array of objects) instead of a flat S3 path string —\n          for schemas like a candidate's resume/passport/visa that store location + filename + who/when as sub-fields.\n        </Text>\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Source field (multipart upload key)</Text>\n            <Input size=\"small\" placeholder=\"resume\" value={draft.sourceField ?? ''} onChange={(e) => set('sourceField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Target field {draft.arrayMode ? '(array)' : '(location sub-field)'}</Text>\n            <Input size=\"small\" placeholder={draft.arrayMode ? 'documents' : 'resume.location'} value={draft.targetField ?? ''} onChange={(e) => set('targetField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={!!draft.arrayMode} onChange={(v) => set('arrayMode', v)} />\n          <Text style={{ fontSize: 13 }}>Array mode — every uploaded file becomes one element (e.g. \"documents\")</Text>\n        </div>\n\n        {draft.arrayMode ? (\n          <>\n            <div style={{ marginTop: 12 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>Sub-field names (location / uploadedFileName / uniqueName → this schema's names)</Text>\n              <PlainFieldMapRows rows={draft.arrayFieldNameRows ?? []} onChange={(rows) => set('arrayFieldNameRows', rows)} keyPlaceholder=\"location\" valuePlaceholder=\"documentCopyLocation\" />\n            </div>\n            <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Take each element's display name from (payload array field)</Text>\n                <Input size=\"small\" placeholder=\"documents\" value={draft.nameFromField ?? ''} onChange={(e) => set('nameFromField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>...reading its field</Text>\n                <Input size=\"small\" placeholder=\"documentName\" value={draft.nameOutputField ?? ''} onChange={(e) => set('nameOutputField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n            </div>\n          </>\n        ) : (\n          <>\n            <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Original filename field</Text>\n                <Input size=\"small\" placeholder=\"resume.uploadedFileName\" value={draft.uploadedFileNameField ?? ''} onChange={(e) => set('uploadedFileNameField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Unique name field</Text>\n                <Input size=\"small\" placeholder=\"resume.uniqueName\" value={draft.uniqueNameField ?? ''} onChange={(e) => set('uniqueNameField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n            </div>\n            <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Uploaded-at field</Text>\n                <Input size=\"small\" placeholder=\"resume.uploadedAt\" value={draft.uploadedAtField ?? ''} onChange={(e) => set('uploadedAtField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Uploaded-by field</Text>\n                <Input size=\"small\" placeholder=\"resume.uploadedBy\" value={draft.uploadedByField ?? ''} onChange={(e) => set('uploadedByField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n            </div>\n            <div style={{ marginTop: 12 }}>\n              <Text type=\"secondary\" style={{ fontSize: 12 }}>Static fields (literal value written alongside the upload)</Text>\n              <PlainFieldMapRows rows={draft.staticFieldRows ?? []} onChange={(rows) => set('staticFieldRows', rows)} keyPlaceholder=\"resume.source\" valuePlaceholder=\"candidate\" />\n            </div>\n            <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>Append a snapshot to (history array field)</Text>\n                <Input size=\"small\" placeholder=\"resumeHistory\" value={draft.historyField ?? ''} onChange={(e) => set('historyField', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>...under snapshot key</Text>\n                <Input size=\"small\" placeholder=\"resume\" value={draft.historySnapshotKey ?? ''} onChange={(e) => set('historySnapshotKey', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n              <div style={{ flex: 1 }}>\n                <Text type=\"secondary\" style={{ fontSize: 12 }}>...with reason</Text>\n                <Input size=\"small\" placeholder=\"Initial resume upload\" value={draft.historyReason ?? ''} onChange={(e) => set('historyReason', e.target.value)} className=\"fg-mono-input\" />\n              </div>\n            </div>\n          </>\n        )}\n      </div>\n    </Modal>\n  );\n}\n\n// ── Hierarchy Expand Drawer ──────────────────────────────────────────────────\nfunction HierarchyExpandDrawer({ open, rule, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    name: '', seedField: '', direction: 'up', stopRole: 0, includeSeed: true,\n    ...(rule ?? {}),\n  }));\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.name?.trim()) return message.error('Name is required — this is how RelatedUpdates/Notify reference the result');\n    if (!/^[a-zA-Z0-9_]+$/.test(draft.name)) return message.error('Name: letters, numbers, underscores only');\n    onSave(draft);\n  };\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={620} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><ApartmentOutlined /> {rule ? 'Edit Hierarchy Expansion' : 'New Hierarchy Expansion'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Name</Text>\n            <Input size=\"small\" placeholder=\"chain\" value={draft.name ?? ''} onChange={(e) => set('name', e.target.value)} className=\"fg-mono-input\" />\n            <Text type=\"secondary\" style={{ fontSize: 11 }}>Referenced as <code>{'{{hierarchy.' + (draft.name || 'name') + '}}'}</code></Text>\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Seed field (blank = the caller)</Text>\n            <Input size=\"small\" placeholder=\"recruitersData\" value={draft.seedField ?? ''} onChange={(e) => set('seedField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Direction</Text>\n            <Select\n              size=\"small\" style={{ width: '100%' }} value={draft.direction || 'up'}\n              onChange={(v) => set('direction', v)}\n              options={[\n                { value: 'up', label: 'Up — toward admin (reporting chain)' },\n                { value: 'down', label: 'Down — toward subordinates (team)' },\n              ]}\n            />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Stop at role id (up only, 0 = walk to the top)</Text>\n            <InputNumber size=\"small\" style={{ width: '100%' }} min={0} value={draft.stopRole ?? 0} onChange={(v) => set('stopRole', v ?? 0)} disabled={draft.direction !== 'up'} />\n          </div>\n        </div>\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={draft.includeSeed !== false} onChange={(v) => set('includeSeed', v)} />\n          <Text style={{ fontSize: 13 }}>Include the seed user(s) themselves in the result</Text>\n        </div>\n      </div>\n    </Modal>\n  );\n}\n\n// ── Related Update Drawer ────────────────────────────────────────────────────\nfunction RelatedUpdateDrawer({ open, rule, hierarchyNames, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    collectionName: '', targetModule: '', matchField: '', scopeTenant: false,\n    forEach: '', insertMode: !!(rule?.insertIfMissing && Object.keys(rule.insertIfMissing).length),\n    ...(rule ?? {}),\n    extraFilterRows: objToRows(rule?.extraFilter),\n    pullRows: objToRows(rule?.pull),\n    pushRows: objToRows(rule?.push),\n    setRows: objToRows(rule?.set),\n    setIfNonBlankRows: objToRows(rule?.setIfNonBlank),\n    insertIfMissingRows: objToRows(rule?.insertIfMissing),\n  }));\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.collectionName?.trim() && !draft.targetModule?.trim()) {\n      return message.error('Set either a collection name or a target module');\n    }\n    const {\n      extraFilterRows, pullRows, pushRows, setRows, setIfNonBlankRows, insertIfMissingRows, insertMode,\n      ...rest\n    } = draft;\n    const out = {\n      ...rest,\n      extraFilter: rowsToObj(extraFilterRows),\n      pull: insertMode ? {} : rowsToObj(pullRows),\n      push: insertMode ? {} : rowsToObj(pushRows),\n      set: insertMode ? {} : rowsToObj(setRows),\n      setIfNonBlank: insertMode ? {} : rowsToObj(setIfNonBlankRows),\n      insertIfMissing: insertMode ? rowsToObj(insertIfMissingRows) : {},\n    };\n    onSave(out);\n  };\n\n  const foreachOptions = (hierarchyNames ?? []).map((n) => ({ value: `hierarchy.${n}`, label: `{{hierarchy.${n}}}` }));\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={820} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><ThunderboltOutlined /> {rule ? 'Edit Related Update' : 'New Related Update'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Apply</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-form-section-label\">Target</div>\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Collection name (used verbatim)</Text>\n            <Input size=\"small\" placeholder=\"hiringProgress\" value={draft.collectionName ?? ''} onChange={(e) => set('collectionName', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>— or — target module</Text>\n            <Input size=\"small\" placeholder=\"job\" value={draft.targetModule ?? ''} onChange={(e) => set('targetModule', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n        </div>\n\n        <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Match field (this payload's field holding the target _id)</Text>\n            <Input size=\"small\" placeholder=\"jobId (blank for a tenant-scoped board)\" value={draft.matchField ?? ''} onChange={(e) => set('matchField', e.target.value)} className=\"fg-mono-input\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Repeat once per element of (ForEach)</Text>\n            <Select\n              size=\"small\" style={{ width: '100%' }} allowClear showSearch\n              placeholder=\"e.g. {{hierarchy.chain}}\"\n              value={draft.forEach || undefined}\n              onChange={(v) => set('forEach', v ?? '')}\n              options={foreachOptions}\n            />\n          </div>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14 }}>\n          <Switch size=\"small\" checked={!!draft.scopeTenant} onChange={(v) => set('scopeTenant', v)} />\n          <Text style={{ fontSize: 13 }}>Scope filter to the caller's tenant/business/businessUnit</Text>\n        </div>\n\n        <div style={{ marginTop: 14 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>Extra filter (merged into the match filter)</Text>\n          <KeyValueRows rows={draft.extraFilterRows ?? []} onChange={(rows) => set('extraFilterRows', rows)} keyPlaceholder=\"recruiterId\" valuePlaceholder='{\"$in\":\"{{hierarchy.chain}}\"}' />\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 18 }}>\n          <Switch size=\"small\" checked={!!draft.insertMode} onChange={(v) => set('insertMode', v)} />\n          <Text style={{ fontSize: 13 }}>Insert-only-if-missing (seed a new document instead of updating an existing one)</Text>\n        </div>\n\n        {draft.insertMode ? (\n          <div style={{ marginTop: 10 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Document to insert when the filter matches nothing</Text>\n            <KeyValueRows rows={draft.insertIfMissingRows ?? []} onChange={(rows) => set('insertIfMissingRows', rows)} keyPlaceholder=\"hiringProgressJobStatus\" valuePlaceholder='\"unread\"' />\n          </div>\n        ) : (\n          <Tabs\n            size=\"small\"\n            style={{ marginTop: 10 }}\n            items={[\n              { key: 'pull', label: 'Pull', children: <KeyValueRows rows={draft.pullRows ?? []} onChange={(rows) => set('pullRows', rows)} keyPlaceholder=\"submitted\" valuePlaceholder='{\"candidateId\":\"{{applicantId}}\"}' /> },\n              { key: 'push', label: 'Push', children: <KeyValueRows rows={draft.pushRows ?? []} onChange={(rows) => set('pushRows', rows)} keyPlaceholder=\"submitted\" valuePlaceholder='{\"status\":\"{{submissionStatus}}\"}' /> },\n              { key: 'set', label: 'Set', children: <KeyValueRows rows={draft.setRows ?? []} onChange={(rows) => set('setRows', rows)} keyPlaceholder=\"hiringProgressJobStatus\" valuePlaceholder='\"unread\"' /> },\n              { key: 'setIfNonBlank', label: 'Set if non-blank', children: <KeyValueRows rows={draft.setIfNonBlankRows ?? []} onChange={(rows) => set('setIfNonBlankRows', rows)} keyPlaceholder=\"resume.location\" valuePlaceholder=\"{{resume.location}}\" /> },\n            ]}\n          />\n        )}\n      </div>\n    </Modal>\n  );\n}\n\n// ── Generic list-of-rules table (Denormalize / ArrayEnrich / HierarchyExpand / RelatedUpdate) ──\nfunction RuleListCard({ icon, title, description, rules, columns, onAdd, onEdit, onDelete }) {\n  return (\n    <AppCard\n      title={<span>{icon} {title}</span>}\n      extra={<Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} onClick={onAdd}>Add</Button>}\n      styles={{ body: { paddingTop: 8 } }}\n    >\n      {description && <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 10 }}>{description}</Text>}\n      <Table\n        rowKey={(r, i) => i}\n        dataSource={rules}\n        columns={[...columns, {\n          title: '', key: 'actions', width: 80, align: 'right',\n          render: (_, r, i) => (\n            <Space size={4}>\n              <Tooltip title=\"Edit\"><Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => onEdit(i, r)} /></Tooltip>\n              <Tooltip title=\"Delete\"><Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} onClick={() => onDelete(i)} /></Tooltip>\n            </Space>\n          ),\n        }]}\n        pagination={false}\n        size=\"small\"\n        className=\"fg-table\"\n        locale={{ emptyText: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=\"Not configured\" /> }}\n      />\n    </AppCard>\n  );\n}\n\n// ── Main Section ──────────────────────────────────────────────────────────────\nconst emptyStrategies = {\n  sequence: null,\n  duplicateCheck: null,\n  fileVersioning: null,\n  denormalizations: [],\n  arrayEnrichments: [],\n  fileFieldMaps: [],\n  sanitizeFields: [],\n  defaults: {},\n  hierarchyExpands: [],\n  relatedUpdates: [],\n  notify: null,\n  cacheInvalidate: [],\n};\n\nexport default function AutomationsSection() {\n  const [modules, setModules] = useState([]);\n  const [modulesLoading, setModulesLoading] = useState(true);\n  const [selected, setSelected] = useState('');\n\n  const [gateway, setGateway] = useState({ storage: 'mongo' });\n  const [originalStorage, setOriginalStorage] = useState('mongo');\n  const [strategies, setStrategies] = useState(emptyStrategies);\n  const [loading, setLoading] = useState(false);\n  const [saving, setSaving] = useState(false);\n  const [error, setError] = useState('');\n\n  const [denormDraft, setDenormDraft] = useState(null); // { index, rule } | { index: null }\n  const [arrayEnrichDraft, setArrayEnrichDraft] = useState(null);\n  const [fileFieldMapDraft, setFileFieldMapDraft] = useState(null);\n  const [hierarchyDraft, setHierarchyDraft] = useState(null);\n  const [relatedUpdateDraft, setRelatedUpdateDraft] = useState(null);\n\n  useEffect(() => {\n    getAvailableModules()\n      .then((raw) => {\n        const mods = normalizeModuleOptions(raw).map(({ value, label }) => ({ key: value, label }));\n        setModules(mods);\n        if (mods.length) setSelected(mods[0].key);\n      })\n      .catch(() => setModules([]))\n      .finally(() => setModulesLoading(false));\n  }, []);\n\n  useEffect(() => {\n    if (!selected) return;\n    let cancelled = false;\n    (async () => {\n      setLoading(true); setError('');\n      try {\n        const cfg = await getModuleAutomations(selected);\n        if (cancelled) return;\n        const gw = cfg.gateway ?? { storage: 'mongo' };\n        setGateway(gw);\n        setOriginalStorage(gw.storage || 'mongo');\n        setStrategies({ ...emptyStrategies, ...(cfg.strategies ?? {}) });\n      } catch (e) {\n        if (!cancelled) setError(e?.message || 'Failed to load automations');\n      } finally {\n        if (!cancelled) setLoading(false);\n      }\n    })();\n    return () => { cancelled = true; };\n  }, [selected]);\n\n  const hierarchyNames = useMemo(() => (strategies.hierarchyExpands ?? []).map((h) => h.name).filter(Boolean), [strategies.hierarchyExpands]);\n\n  function setStrategy(key, value) {\n    setStrategies((prev) => ({ ...prev, [key]: value }));\n  }\n\n  // Replace one duplicate-check row in place, leaving the order (which IS the\n  // priority) and every other row untouched.\n  function updateStage(index, stage) {\n    setStrategies((prev) => {\n      const dc = prev.duplicateCheck ?? {};\n      const stages = [...(dc.stages ?? [])];\n      stages[index] = stage;\n      return { ...prev, duplicateCheck: { ...dc, stages } };\n    });\n  }\n\n  function doSave() {\n    setSaving(true);\n    const payload = {\n      ...strategies,\n      denormalizations: strategies.denormalizations?.length ? strategies.denormalizations : undefined,\n      arrayEnrichments: strategies.arrayEnrichments?.length ? strategies.arrayEnrichments : undefined,\n      fileFieldMaps: strategies.fileFieldMaps?.length ? strategies.fileFieldMaps : undefined,\n      sanitizeFields: strategies.sanitizeFields?.length ? strategies.sanitizeFields : undefined,\n      hierarchyExpands: strategies.hierarchyExpands?.length ? strategies.hierarchyExpands : undefined,\n      relatedUpdates: strategies.relatedUpdates?.length ? strategies.relatedUpdates : undefined,\n      cacheInvalidate: strategies.cacheInvalidate?.length ? strategies.cacheInvalidate : undefined,\n      defaults: Object.keys(strategies.defaults ?? {}).length ? strategies.defaults : undefined,\n    };\n    saveModuleAutomations(selected, { gateway, strategies: payload })\n      .then(() => {\n        setOriginalStorage(gateway.storage || 'mongo');\n        message.success('Automations saved');\n      })\n      .catch((e) => message.error(e?.message || 'Could not save automations'))\n      .finally(() => setSaving(false));\n  }\n\n  function handleSave() {\n    if ((gateway.storage || 'mongo') !== originalStorage) {\n      Modal.confirm({\n        title: 'Change how this module persists writes?',\n        content: `You're switching ${selected} from \"${originalStorage}\" to \"${gateway.storage}\". ` +\n          (gateway.storage === 'mongo'\n            ? 'This module will stop calling its downstream service and this gateway will own the write + every Strategy below.'\n            : 'This module will stop using the Strategies below and go back to calling its downstream service.') +\n          ' Make sure the downstream service / e2e checks are ready before confirming.',\n        okText: 'Confirm cutover',\n        okButtonProps: { danger: true },\n        onOk: doSave,\n      });\n      return;\n    }\n    doSave();\n  }\n\n  const denormColumns = [\n    { title: 'Source module', dataIndex: 'sourceModule', key: 'sourceModule', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'Source id field', dataIndex: 'sourceIdField', key: 'sourceIdField' },\n    { title: 'Fields', key: 'fields', render: (_, r) => <Badge count={Object.keys(r.fieldMap ?? {}).length} showZero color=\"var(--color-brand)\" /> },\n    { title: 'Required', dataIndex: 'required', key: 'required', width: 90, render: (v) => (v ? <Tag color=\"volcano\">Required</Tag> : <Text type=\"secondary\" style={{ fontSize: 12 }}>optional</Text>) },\n  ];\n\n  const arrayEnrichColumns = [\n    { title: 'Source field', dataIndex: 'sourceField', key: 'sourceField', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'Target field', dataIndex: 'targetField', key: 'targetField', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'From collection', key: 'coll', render: (_, r) => r.sourceCollection || 'users' },\n    { title: 'Fields', key: 'fields', render: (_, r) => <Badge count={Object.keys(r.fieldMap ?? {}).length} showZero color=\"var(--color-brand)\" /> },\n  ];\n\n  const fileFieldMapColumns = [\n    { title: 'Source field', dataIndex: 'sourceField', key: 'sourceField', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'Target field', dataIndex: 'targetField', key: 'targetField', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'Mode', dataIndex: 'arrayMode', key: 'arrayMode', width: 100, render: (v) => (v ? <Tag color=\"blue\">Array</Tag> : <Tag>Single</Tag>) },\n    { title: 'History', dataIndex: 'historyField', key: 'historyField', render: (v) => v || <Text type=\"secondary\" style={{ fontSize: 12 }}>—</Text> },\n  ];\n\n  const hierarchyColumns = [\n    { title: 'Name', dataIndex: 'name', key: 'name', render: (v) => <code className=\"fg-table-code\">{'{{hierarchy.' + v + '}}'}</code> },\n    { title: 'Seed field', dataIndex: 'seedField', key: 'seedField', render: (v) => v || <Text type=\"secondary\" style={{ fontSize: 12 }}>caller</Text> },\n    { title: 'Direction', dataIndex: 'direction', key: 'direction', render: (v) => <Tag color={v === 'down' ? 'blue' : 'purple'}>{v === 'down' ? 'Down — team' : 'Up — chain'}</Tag> },\n    { title: 'Stop role', dataIndex: 'stopRole', key: 'stopRole', width: 90, render: (v) => v || <Text type=\"secondary\" style={{ fontSize: 12 }}>top</Text> },\n  ];\n\n  const relatedUpdateColumns = [\n    { title: 'Target', key: 'target', render: (_, r) => <code className=\"fg-table-code\">{r.collectionName || r.targetModule}</code> },\n    { title: 'Match', key: 'match', render: (_, r) => r.matchField || <Text type=\"secondary\" style={{ fontSize: 12 }}>tenant-scoped</Text> },\n    { title: 'For each', key: 'forEach', render: (_, r) => (r.forEach ? <Tag color=\"geekblue\">{`{{${r.forEach}}}`}</Tag> : <Text type=\"secondary\" style={{ fontSize: 12 }}>once</Text>) },\n    { title: 'Mode', key: 'mode', render: (_, r) => (Object.keys(r.insertIfMissing ?? {}).length ? <Tag color=\"green\">Insert if missing</Tag> : <Tag>Update</Tag>) },\n  ];\n\n  const moduleTabs = modules.map((m) => ({ key: m.key, label: m.label }));\n\n  return (\n    <div className=\"fg-section\">\n      <AppCard\n        icon={<ThunderboltOutlined />}\n        title=\"Automations\"\n        extra={\n          <Button type=\"primary\" size=\"small\" icon={<SaveOutlined />} loading={saving} disabled={!selected} onClick={handleSave}>\n            Save Automations\n          </Button>\n        }\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          Config-driven side-effects the common CRUD gateway runs around a create — reference ids, duplicate checks,\n          cross-module field snapshots, reporting-chain hierarchy expansion, board updates, notifications, cache\n          invalidation. Nothing here is module-specific: the same engine serves every module.\n        </Text>\n      </AppCard>\n\n      <AppCard styles={{ body: { paddingTop: 8 } }}>\n        <Spin spinning={modulesLoading}>\n          <Tabs activeKey={selected} onChange={setSelected} items={moduleTabs.map((t) => ({ ...t, children: null }))} className=\"admin-module-tabs\" />\n          {error && <Alert type=\"error\" showIcon message={error} style={{ marginBottom: 12 }} />}\n\n          <Spin spinning={loading}>\n            {/* ── Gateway (the write-path switch) ───────────────────────────── */}\n            <AppCard title=\"Gateway\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 10 }}>\n                Selects how a write to this module persists. \"Proxy\" forwards to a downstream microservice (which\n                owns every side-effect below itself). \"Mongo\" makes THIS gateway own the write and run every\n                Strategy configured below.\n              </Text>\n              <div className=\"fg-field-meta-row\">\n                <div style={{ flex: 1 }}>\n                  <Text type=\"secondary\" style={{ fontSize: 12 }}>Storage</Text>\n                  <Select\n                    size=\"small\" style={{ width: '100%' }} value={gateway.storage || 'mongo'}\n                    onChange={(v) => setGateway((g) => ({ ...g, storage: v }))}\n                    options={[{ value: 'mongo', label: 'Mongo — this gateway owns the write' }, { value: 'proxy', label: 'Proxy — forward to a downstream service' }]}\n                  />\n                </div>\n                <div style={{ flex: 1 }}>\n                  <Text type=\"secondary\" style={{ fontSize: 12 }}>File field key</Text>\n                  <Input size=\"small\" placeholder=\"file\" value={gateway.fileKey ?? ''} onChange={(e) => setGateway((g) => ({ ...g, fileKey: e.target.value }))} className=\"fg-mono-input\" />\n                </div>\n              </div>\n              {gateway.storage === 'proxy' && (\n                <>\n                  <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Base URL env var</Text>\n                      <Input size=\"small\" placeholder=\"JOBS_SERVICE_URL\" value={gateway.baseUrlEnv ?? ''} onChange={(e) => setGateway((g) => ({ ...g, baseUrlEnv: e.target.value }))} className=\"fg-mono-input\" />\n                    </div>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Base URL (fallback)</Text>\n                      <Input size=\"small\" placeholder=\"http://...\" value={gateway.baseUrl ?? ''} onChange={(e) => setGateway((g) => ({ ...g, baseUrl: e.target.value }))} className=\"fg-mono-input\" />\n                    </div>\n                  </div>\n                  <div className=\"fg-field-meta-row\" style={{ marginTop: 12 }}>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Create path</Text>\n                      <Input size=\"small\" placeholder=\"/v1/jobs\" value={gateway.createPath ?? ''} onChange={(e) => setGateway((g) => ({ ...g, createPath: e.target.value }))} className=\"fg-mono-input\" />\n                    </div>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Update path (%s = id)</Text>\n                      <Input size=\"small\" placeholder=\"/v1/edit/%s\" value={gateway.updatePath ?? ''} onChange={(e) => setGateway((g) => ({ ...g, updatePath: e.target.value }))} className=\"fg-mono-input\" />\n                    </div>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Update method</Text>\n                      <Select size=\"small\" style={{ width: '100%' }} value={gateway.updateMethod || 'PUT'} onChange={(v) => setGateway((g) => ({ ...g, updateMethod: v }))} options={['PUT', 'POST', 'PATCH'].map((m) => ({ value: m, label: m }))} />\n                    </div>\n                  </div>\n                </>\n              )}\n            </AppCard>\n\n            {/* ── Sequence ─────────────────────────────────────────────────── */}\n            <AppCard title=\"Reference ID (Sequence)\" styles={{ body: { paddingTop: 8 } }}>\n              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>\n                <Switch size=\"small\" checked={!!strategies.sequence} onChange={(v) => setStrategy('sequence', v ? { field: '', prefix: '', counterKey: '' } : null)} />\n                <Text style={{ fontSize: 13 }}>Generate a \"{'{prefix}{n}'}\" reference id on create</Text>\n              </div>\n              {strategies.sequence && (\n                <div className=\"fg-field-meta-row\">\n                  <div style={{ flex: 1 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>Payload field</Text>\n                    <Input size=\"small\" placeholder=\"submissionId\" value={strategies.sequence.field ?? ''} onChange={(e) => setStrategy('sequence', { ...strategies.sequence, field: e.target.value })} className=\"fg-mono-input\" />\n                  </div>\n                  <div style={{ flex: 1 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>Prefix</Text>\n                    <Input size=\"small\" placeholder=\"sub\" value={strategies.sequence.prefix ?? ''} onChange={(e) => setStrategy('sequence', { ...strategies.sequence, prefix: e.target.value })} className=\"fg-mono-input\" />\n                  </div>\n                  <div style={{ flex: 1 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>Counter key</Text>\n                    <Input size=\"small\" placeholder=\"submissions\" value={strategies.sequence.counterKey ?? ''} onChange={(e) => setStrategy('sequence', { ...strategies.sequence, counterKey: e.target.value })} className=\"fg-mono-input\" />\n                  </div>\n                </div>\n              )}\n            </AppCard>\n\n            {/* ── Duplicate Check ──────────────────────────────────────────── */}\n            <AppCard title=\"Check for someone already on file\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 10 }}>\n                Before a new record is saved, look for one that already matches. This is what\n                stops the same person being added twice under slightly different details.\n              </Text>\n              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>\n                <Switch size=\"small\" checked={!!strategies.duplicateCheck}\n                  onChange={(v) => setStrategy('duplicateCheck', v ? { stages: [], policy: 'prompt', displayFields: [], message: '' } : null)} />\n                <Text style={{ fontSize: 13 }}>Check before saving a new record</Text>\n              </div>\n              {strategies.duplicateCheck && (\n                <>\n                  {/* Checks run IN ORDER and stop at the first match — which is\n                      how \"email or phone first, then name\" is expressed. */}\n                  <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 6 }}>\n                    <b>Checks run in order, top first, and stop at the first match.</b> Put your\n                    most certain check first — matching an email or a phone number is near\n                    proof; matching a name alone is only a maybe, so it belongs lower down.\n                  </Text>\n                  {(strategies.duplicateCheck.stages ?? []).map((stage, i) => (\n                    <div key={i} className=\"fg-field-meta-row\" style={{ marginBottom: 8, alignItems: 'flex-end' }}>\n                      <div style={{ flex: 1.6 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>Check {i + 1} — compare these</Text>\n                        <Select mode=\"tags\" size=\"small\" style={{ width: '100%' }}\n                          placeholder=\"email, contactNumber\"\n                          value={stage.fields ?? []}\n                          onChange={(v) => updateStage(i, { ...stage, fields: v })} />\n                      </div>\n                      <div style={{ flex: 1 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>Counts as a match when</Text>\n                        <Select size=\"small\" style={{ width: '100%' }}\n                          value={stage.match ?? 'all'}\n                          onChange={(v) => updateStage(i, { ...stage, match: v })}\n                          options={[\n                            { value: 'any', label: 'Any one of them matches' },\n                            { value: 'all', label: 'All of them match' },\n                          ]} />\n                      </div>\n                      <div style={{ flex: 0.8 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>How sure is it?</Text>\n                        <Select size=\"small\" style={{ width: '100%' }}\n                          value={stage.weight ?? 'strong'}\n                          onChange={(v) => updateStage(i, { ...stage, weight: v })}\n                          options={[\n                            { value: 'strong', label: 'Almost certainly the same' },\n                            { value: 'weak', label: 'Possibly the same' },\n                          ]} />\n                      </div>\n                      <div style={{ flex: 2 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>What to tell the user</Text>\n                        <Input size=\"small\"\n                          placeholder=\"A candidate with this email already exists — {name}, last updated {age}.\"\n                          value={stage.message ?? ''}\n                          onChange={(e) => updateStage(i, { ...stage, message: e.target.value })} />\n                      </div>\n                      <Button size=\"small\" danger type=\"text\"\n                        onClick={() => setStrategy('duplicateCheck', {\n                          ...strategies.duplicateCheck,\n                          stages: (strategies.duplicateCheck.stages ?? []).filter((_, x) => x !== i),\n                        })}>Remove</Button>\n                    </div>\n                  ))}\n                  <Button size=\"small\" type=\"dashed\" style={{ marginBottom: 12 }}\n                    onClick={() => setStrategy('duplicateCheck', {\n                      ...strategies.duplicateCheck,\n                      stages: [...(strategies.duplicateCheck.stages ?? []), { fields: [], match: 'any', weight: 'strong' }],\n                    })}>Add another check</Button>\n\n                  <div className=\"fg-field-meta-row\">\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>When a match is found</Text>\n                      <Select size=\"small\" style={{ width: '100%' }}\n                        value={strategies.duplicateCheck.policy ?? 'prompt'}\n                        onChange={(v) => setStrategy('duplicateCheck', { ...strategies.duplicateCheck, policy: v })}\n                        options={[\n                          { value: 'prompt', label: 'Ask, and offer to update the existing one' },\n                          { value: 'block', label: 'Refuse to save, and name the existing one' },\n                        ]} />\n                    </div>\n                    <div style={{ flex: 1.2 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Which details identify the record</Text>\n                      <Select mode=\"tags\" size=\"small\" style={{ width: '100%' }}\n                        placeholder=\"firstName, lastName, email\"\n                        value={strategies.duplicateCheck.displayFields ?? []}\n                        onChange={(v) => setStrategy('duplicateCheck', { ...strategies.duplicateCheck, displayFields: v })} />\n                    </div>\n                  </div>\n                  <div className=\"fg-field-meta-row\" style={{ marginTop: 10 }}>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Where to open the existing record</Text>\n                      <Input size=\"small\" className=\"fg-mono-input\"\n                        placeholder=\"/candidate/edit/:id\"\n                        value={strategies.duplicateCheck.editRoute ?? ''}\n                        onChange={(e) => setStrategy('duplicateCheck', { ...strategies.duplicateCheck, editRoute: e.target.value })} />\n                    </div>\n                  </div>\n                  <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 6 }}>\n                    The page that opens when someone chooses to update the record you already\n                    have. Use <b>:id</b> where the record&apos;s id goes. This has to be filled in —\n                    it cannot be worked out, because addresses follow no single pattern (this app\n                    uses <code>/candidate/edit/:id</code> but <code>/clients/edit/:id</code>).\n                    Left blank, the dialog still appears and simply does not navigate, rather than\n                    sending anyone to a page that does not exist.\n                  </Text>\n                  <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 8 }}>\n                    In any message you can use <b>{'{name}'}</b> for the matched record and\n                    <b> {'{age}'}</b> for how long ago it was last touched (&quot;about 2 months\n                    ago&quot;). <b>{'{updatedOn}'}</b> gives the date instead. Only the details\n                    listed above are shown — nothing else about the record is revealed.\n                  </Text>\n                </>\n              )}\n            </AppCard>\n\n            {/* ── File versioning ──────────────────────────────────────────── */}\n            <AppCard title=\"Keep previous versions of an uploaded file\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 10 }}>\n                Normally a new upload replaces the old one and it is gone. Turn this on and the\n                last few are kept instead — useful when someone sends an updated CV and you may\n                want to look back at the earlier one. Everywhere in the app still shows the\n                newest; the older ones sit behind it.\n              </Text>\n              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>\n                <Switch size=\"small\" checked={!!strategies.fileVersioning}\n                  onChange={(v) => setStrategy('fileVersioning', v\n                    ? { fields: [], keep: 2, historyKey: '', s3Prefix: '', deleteEvicted: false }\n                    : null)} />\n                <Text style={{ fontSize: 13 }}>Keep previous uploads</Text>\n              </div>\n              {strategies.fileVersioning && (\n                <>\n                  <div style={{ marginBottom: 10 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12, display: 'block' }}>Where the older versions are kept</Text>\n                    <Radio.Group\n                      size=\"small\"\n                      value={strategies.fileVersioning.store === 'documents' ? 'documents' : 'record'}\n                      onChange={(e) => {\n                        const store = e.target.value;\n                        const next = { ...strategies.fileVersioning, store: store === 'documents' ? 'documents' : '' };\n                        if (store === 'documents') {\n                          // Sensible companions, only filled if the admin has not\n                          // set them. Choosing this option without them would\n                          // leave the versions filed correctly but the old\n                          // per-record arrays still sitting on every record.\n                          next.linkField = next.linkField || 'documentIds';\n                          next.clearRecordKeys = next.clearRecordKeys?.length\n                            ? next.clearRecordKeys\n                            : (next.fields ?? []).flatMap((f) => [`${f}History`, `${f}Versions`]);\n                        }\n                        setStrategy('fileVersioning', next);\n                      }}\n                    >\n                      <Radio value=\"documents\">In Documents (recommended)</Radio>\n                      <Radio value=\"record\">On the record itself</Radio>\n                    </Radio.Group>\n                    <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 6 }}>\n                      <b>In Documents</b> keeps the file and all its earlier versions in one place,\n                      the same place every other document lives. The record just points at it — so\n                      when a candidate is submitted for a job, the submission shows the very same\n                      file, and replacing it updates both at once. <b>On the record itself</b> is\n                      the older way: each record keeps its own copy of the history, which is why\n                      the same résumé could end up recorded several times over and the copies\n                      could disagree.\n                    </Text>\n                  </div>\n                  {strategies.fileVersioning.store === 'documents' && (\n                    <div className=\"fg-field-meta-row\" style={{ marginBottom: 10 }}>\n                      <div style={{ flex: 1 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>List of attached documents is kept in</Text>\n                        <Input size=\"small\" placeholder=\"documentIds\"\n                          value={strategies.fileVersioning.linkField ?? ''}\n                          onChange={(e) => setStrategy('fileVersioning', { ...strategies.fileVersioning, linkField: e.target.value })} />\n                      </div>\n                      <div style={{ flex: 1.6 }}>\n                        <Text type=\"secondary\" style={{ fontSize: 12 }}>Old history fields to clear off the record</Text>\n                        <Select mode=\"tags\" size=\"small\" style={{ width: '100%' }} placeholder=\"resumeHistory\"\n                          value={strategies.fileVersioning.clearRecordKeys ?? []}\n                          onChange={(v) => setStrategy('fileVersioning', { ...strategies.fileVersioning, clearRecordKeys: v })} />\n                      </div>\n                    </div>\n                  )}\n                  <div className=\"fg-field-meta-row\">\n                    <div style={{ flex: 1.4 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Which uploads</Text>\n                      <Select mode=\"tags\" size=\"small\" style={{ width: '100%' }} placeholder=\"resume\"\n                        value={strategies.fileVersioning.fields ?? []}\n                        onChange={(v) => setStrategy('fileVersioning', { ...strategies.fileVersioning, fields: v })} />\n                    </div>\n                    <div style={{ flex: 0.7 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>How many to keep</Text>\n                      <Input size=\"small\" type=\"number\" min={1}\n                        value={strategies.fileVersioning.keep ?? 2}\n                        onChange={(e) => setStrategy('fileVersioning', { ...strategies.fileVersioning, keep: Number(e.target.value) || 1 })} />\n                    </div>\n                    <div style={{ flex: 1.4 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Where the files are grouped</Text>\n                      <Input size=\"small\" placeholder=\"candidates/{recordId}/resume\"\n                        value={strategies.fileVersioning.s3Prefix ?? ''}\n                        onChange={(e) => setStrategy('fileVersioning', { ...strategies.fileVersioning, s3Prefix: e.target.value })} />\n                    </div>\n                  </div>\n                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>\n                    <Switch size=\"small\" checked={!!strategies.fileVersioning.deleteEvicted}\n                      onChange={(v) => setStrategy('fileVersioning', { ...strategies.fileVersioning, deleteEvicted: v })} />\n                    <Text style={{ fontSize: 13 }}>Also delete the file once it drops off the end</Text>\n                  </div>\n                  <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginTop: 6 }}>\n                    Leave that switch OFF unless you are sure. With it off, an older file simply\n                    stops being shown and can still be recovered. With it on, it is deleted from\n                    storage permanently and cannot be brought back. Keeping 2 means a third\n                    upload pushes the first one off the end.\n                  </Text>\n                </>\n              )}\n            </AppCard>\n\n            {/* ── Denormalizations ─────────────────────────────────────────── */}\n            <RuleListCard\n              icon={<DatabaseOutlined />}\n              title=\"Denormalizations\"\n              description=\"Copy fields from ANOTHER module's record onto this payload before insert (e.g. a submission snapshotting job title/client).\"\n              rules={strategies.denormalizations ?? []}\n              columns={denormColumns}\n              onAdd={() => setDenormDraft({ index: null, rule: null })}\n              onEdit={(i, r) => setDenormDraft({ index: i, rule: r })}\n              onDelete={(i) => setStrategy('denormalizations', (strategies.denormalizations ?? []).filter((_, idx) => idx !== i))}\n            />\n\n            {/* ── Array Enrichments ────────────────────────────────────────── */}\n            <RuleListCard\n              icon={<ApartmentOutlined />}\n              title=\"Array Enrichments\"\n              description=\"Enrich a payload array of ids (e.g. recruitersData) into objects carrying looked-up fields (name, email) before insert.\"\n              rules={strategies.arrayEnrichments ?? []}\n              columns={arrayEnrichColumns}\n              onAdd={() => setArrayEnrichDraft({ index: null, rule: null })}\n              onEdit={(i, r) => setArrayEnrichDraft({ index: i, rule: r })}\n              onDelete={(i) => setStrategy('arrayEnrichments', (strategies.arrayEnrichments ?? []).filter((_, idx) => idx !== i))}\n            />\n\n            {/* ── File Field Maps ──────────────────────────────────────────── */}\n            <RuleListCard\n              icon={<DatabaseOutlined />}\n              title=\"File Field Maps\"\n              description=\"Turn an uploaded file field into a nested object (location + filename + who/when) or an array of such objects, instead of a flat S3 path string — needed for schemas like resume/passport/visa.\"\n              rules={strategies.fileFieldMaps ?? []}\n              columns={fileFieldMapColumns}\n              onAdd={() => setFileFieldMapDraft({ index: null, rule: null })}\n              onEdit={(i, r) => setFileFieldMapDraft({ index: i, rule: r })}\n              onDelete={(i) => setStrategy('fileFieldMaps', (strategies.fileFieldMaps ?? []).filter((_, idx) => idx !== i))}\n            />\n\n            {/* ── Sanitize Fields ──────────────────────────────────────────── */}\n            <AppCard title=\"Sanitize Fields\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n                Trim and HTML-escape these payload fields before anything else runs — basic XSS-safety for free-text\n                fields (e.g. firstName/lastName) that might later be embedded in an HTML activity comment or email.\n              </Text>\n              <Select\n                mode=\"tags\" style={{ width: '100%' }}\n                placeholder=\"firstName, lastName, email\"\n                value={strategies.sanitizeFields ?? []}\n                onChange={(v) => setStrategy('sanitizeFields', v)}\n              />\n            </AppCard>\n\n            {/* ── Defaults ─────────────────────────────────────────────────── */}\n            <AppCard title=\"Defaults\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n                Set a field only when the payload doesn't already carry a non-blank value — status defaults, empty arrays.\n              </Text>\n              <KeyValueRows\n                rows={objToRows(strategies.defaults)}\n                onChange={(rows) => setStrategy('defaults', rowsToObj(rows))}\n                keyPlaceholder=\"internalSubmissionStatus.internalSubmissionStatusText\"\n                valuePlaceholder='\"Under Evaluation\"'\n              />\n            </AppCard>\n\n            {/* ── Hierarchy Expansions ─────────────────────────────────────── */}\n            <RuleListCard\n              icon={<ApartmentOutlined />}\n              title=\"Hierarchy Expansions\"\n              description=\"Walk the reporting chain up (toward admin) or down (toward a team) from a seed user, publishing the result as {{hierarchy.<name>}} for Related Updates / Notify to use.\"\n              rules={strategies.hierarchyExpands ?? []}\n              columns={hierarchyColumns}\n              onAdd={() => setHierarchyDraft({ index: null, rule: null })}\n              onEdit={(i, r) => setHierarchyDraft({ index: i, rule: r })}\n              onDelete={(i) => setStrategy('hierarchyExpands', (strategies.hierarchyExpands ?? []).filter((_, idx) => idx !== i))}\n            />\n\n            {/* ── Related Updates ──────────────────────────────────────────── */}\n            <RuleListCard\n              icon={<ThunderboltOutlined />}\n              title=\"Related Updates\"\n              description=\"Best-effort side-effect writes to other collections after a successful insert — board state, activity logs. Combine with ForEach + a Hierarchy Expansion to seed one document per user in a chain.\"\n              rules={strategies.relatedUpdates ?? []}\n              columns={relatedUpdateColumns}\n              onAdd={() => setRelatedUpdateDraft({ index: null, rule: null })}\n              onEdit={(i, r) => setRelatedUpdateDraft({ index: i, rule: r })}\n              onDelete={(i) => setStrategy('relatedUpdates', (strategies.relatedUpdates ?? []).filter((_, idx) => idx !== i))}\n            />\n\n            {/* ── Notify ───────────────────────────────────────────────────── */}\n            <AppCard title=\"Notify\" styles={{ body: { paddingTop: 8 } }}>\n              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>\n                <Switch size=\"small\" checked={!!strategies.notify} onChange={(v) => setStrategy('notify', v ? { action: '', subjectDefault: '', bodyDefault: '', toReportingManager: false, toHierarchy: '' } : null)} />\n                <Text style={{ fontSize: 13 }}>Send a best-effort email after a successful insert</Text>\n              </div>\n              {strategies.notify && (\n                <>\n                  <div className=\"fg-field-meta-row\">\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Action (matched against an EmailTemplates doc)</Text>\n                      <Input size=\"small\" placeholder=\"internalSubmit\" value={strategies.notify.action ?? ''} onChange={(e) => setStrategy('notify', { ...strategies.notify, action: e.target.value })} className=\"fg-mono-input\" />\n                    </div>\n                    <div style={{ flex: 1 }}>\n                      <Text type=\"secondary\" style={{ fontSize: 12 }}>Notify entire hierarchy chain</Text>\n                      <Select size=\"small\" style={{ width: '100%' }} allowClear placeholder=\"pick a Hierarchy Expansion\" value={strategies.notify.toHierarchy || undefined} onChange={(v) => setStrategy('notify', { ...strategies.notify, toHierarchy: v ?? '' })} options={hierarchyNames.map((n) => ({ value: n, label: n }))} />\n                    </div>\n                  </div>\n                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>\n                    <Switch size=\"small\" checked={!!strategies.notify.toReportingManager} onChange={(v) => setStrategy('notify', { ...strategies.notify, toReportingManager: v })} />\n                    <Text style={{ fontSize: 13 }}>Also notify the caller's direct reporting manager</Text>\n                  </div>\n                  <div style={{ marginTop: 12 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>Default subject</Text>\n                    <Input size=\"small\" placeholder=\"New submission\" value={strategies.notify.subjectDefault ?? ''} onChange={(e) => setStrategy('notify', { ...strategies.notify, subjectDefault: e.target.value })} />\n                  </div>\n                  <div style={{ marginTop: 12 }}>\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>Default body (used when no EmailTemplates doc matches)</Text>\n                    <Input.TextArea rows={4} value={strategies.notify.bodyDefault ?? ''} onChange={(e) => setStrategy('notify', { ...strategies.notify, bodyDefault: e.target.value })} className=\"fg-mono-input\" />\n                  </div>\n                </>\n              )}\n            </AppCard>\n\n            {/* ── Cache Invalidate ─────────────────────────────────────────── */}\n            <AppCard title=\"Cache Invalidate\" styles={{ body: { paddingTop: 8 } }}>\n              <Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n                Redis key patterns (with {'{{field}}'} tokens) to SCAN+DEL after a successful insert.\n              </Text>\n              <Select\n                mode=\"tags\" style={{ width: '100%' }}\n                placeholder=\"jobs:{{tenantId}}:{{businessId}}:{{businessUnitId}}:*\"\n                value={strategies.cacheInvalidate ?? []}\n                onChange={(v) => setStrategy('cacheInvalidate', v)}\n              />\n            </AppCard>\n          </Spin>\n        </Spin>\n      </AppCard>\n\n      <DenormalizeDrawer\n        key={denormDraft ? `denorm-${denormDraft.index ?? 'new'}` : 'denorm-closed'}\n        open={!!denormDraft} rule={denormDraft?.rule} onClose={() => setDenormDraft(null)}\n        onSave={(rule) => {\n          setStrategy('denormalizations', denormDraft.index === null\n            ? [...(strategies.denormalizations ?? []), rule]\n            : (strategies.denormalizations ?? []).map((r, i) => (i === denormDraft.index ? rule : r)));\n          setDenormDraft(null);\n        }}\n      />\n\n      <ArrayEnrichDrawer\n        key={arrayEnrichDraft ? `enrich-${arrayEnrichDraft.index ?? 'new'}` : 'enrich-closed'}\n        open={!!arrayEnrichDraft} rule={arrayEnrichDraft?.rule} onClose={() => setArrayEnrichDraft(null)}\n        onSave={(rule) => {\n          setStrategy('arrayEnrichments', arrayEnrichDraft.index === null\n            ? [...(strategies.arrayEnrichments ?? []), rule]\n            : (strategies.arrayEnrichments ?? []).map((r, i) => (i === arrayEnrichDraft.index ? rule : r)));\n          setArrayEnrichDraft(null);\n        }}\n      />\n\n      <FileFieldMapDrawer\n        key={fileFieldMapDraft ? `filemap-${fileFieldMapDraft.index ?? 'new'}` : 'filemap-closed'}\n        open={!!fileFieldMapDraft} rule={fileFieldMapDraft?.rule} onClose={() => setFileFieldMapDraft(null)}\n        onSave={(rule) => {\n          setStrategy('fileFieldMaps', fileFieldMapDraft.index === null\n            ? [...(strategies.fileFieldMaps ?? []), rule]\n            : (strategies.fileFieldMaps ?? []).map((r, i) => (i === fileFieldMapDraft.index ? rule : r)));\n          setFileFieldMapDraft(null);\n        }}\n      />\n\n      <HierarchyExpandDrawer\n        key={hierarchyDraft ? `hier-${hierarchyDraft.index ?? 'new'}` : 'hier-closed'}\n        open={!!hierarchyDraft} rule={hierarchyDraft?.rule} onClose={() => setHierarchyDraft(null)}\n        onSave={(rule) => {\n          setStrategy('hierarchyExpands', hierarchyDraft.index === null\n            ? [...(strategies.hierarchyExpands ?? []), rule]\n            : (strategies.hierarchyExpands ?? []).map((r, i) => (i === hierarchyDraft.index ? rule : r)));\n          setHierarchyDraft(null);\n        }}\n      />\n\n      <RelatedUpdateDrawer\n        key={relatedUpdateDraft ? `ru-${relatedUpdateDraft.index ?? 'new'}` : 'ru-closed'}\n        open={!!relatedUpdateDraft} rule={relatedUpdateDraft?.rule} hierarchyNames={hierarchyNames} onClose={() => setRelatedUpdateDraft(null)}\n        onSave={(rule) => {\n          setStrategy('relatedUpdates', relatedUpdateDraft.index === null\n            ? [...(strategies.relatedUpdates ?? []), rule]\n            : (strategies.relatedUpdates ?? []).map((r, i) => (i === relatedUpdateDraft.index ? rule : r)));\n          setRelatedUpdateDraft(null);\n        }}\n      />\n    </div>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n  Alert, Badge, Button, Empty, Input, InputNumber, Modal, Popconfirm, Select,\n  Space, Spin, Switch, Table, Tag, Tooltip, Typography, message,\n} from 'antd';\nimport {\n  ApartmentOutlined, DeleteOutlined, EditOutlined, PlusOutlined,\n  ReloadOutlined, SaveOutlined,\n} from '@ant-design/icons';\nimport {\n  getAvailableModules, listPlatformDocs, savePlatformDoc, deletePlatformDoc,\n} from '../../../services/adminApi';\nimport { normalizeModuleOptions } from '../../../utils/moduleOptions';\nimport AppCard from '../../../components/cards/AppCard';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\n// =============================================================================\n// Workflows — the Admin surface for platformWorkflows metadata: event-driven\n// behavior (module, event, condition, ordered actions) executed by the\n// backend Workflow Engine. This is where the jobs/candidates/submissions\n// create flows live after migration — and where ANY module's automation is\n// authored, with zero backend code.\n// =============================================================================\n\nconst EVENTS = ['beforeCreate', 'afterCreate', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete'];\n// Mirrors the backend Action Registry (workflowEngine.go) — validated server-side too.\nconst ACTION_TYPES = [\n  'sanitizeFields', 'generateSequence', 'duplicateCheck', 'copyFields', 'arrayEnrich',\n  'setDefaults', 'resolve', 'updateRelated', 'notify', 'invalidateCache', 'webhook',\n  // Document sharing. linkDocuments makes one record's files visible from\n  // another (a candidate's pack on the submission they were put forward with)\n  // WITHOUT copying them; captureFileUrls files an already-generated remote\n  // file — a formatted résumé, an attestation PDF — as a real document row.\n  'linkDocuments', 'captureFileUrls',\n];\n\n// Plain-language description + a starting config for each action, shown beside\n// the type picker. Without this the editor is a bare JSON box and an admin has\n// to already know the shape, which is exactly the barrier this screen exists to\n// remove.\nconst ACTION_HELP = {\n  linkDocuments: {\n    text: 'Share one record\\u2019s uploaded files with another, without making a second copy. '\n      + 'Used so a submission shows the candidate\\u2019s r\\u00e9sum\\u00e9 and paperwork, and anything '\n      + 'uploaded during the submission appears on the candidate too. Both records get the '\n      + 'list of document ids written onto them.',\n    sample: {\n      sourceModule: 'candidates',\n      sourceIdField: 'applicantId',\n      targetModule: 'submissions',\n      linkField: 'documentIds',\n      fieldNames: [],\n      backLink: true,\n    },\n  },\n  captureFileUrls: {\n    text: 'File a document that was generated elsewhere and handed to us as a link \\u2014 a '\n      + 'formatted r\\u00e9sum\\u00e9 or an attestation PDF \\u2014 so it sits with every other '\n      + 'attachment instead of being a loose field on the record.',\n    sample: {\n      linkField: 'documentIds',\n      files: [\n        { urlField: 'resumeUrl', nameField: 'resumeFileName', fieldName: 'formattedResume', defaultName: 'Formatted Resume.pdf' },\n        { urlField: 'attestationUrl', nameField: 'attestationFileName', fieldName: 'attestation', defaultName: 'Attestation.pdf' },\n      ],\n    },\n  },\n};\n\nfunction pretty(v) { return JSON.stringify(v ?? {}, null, 2); }\n\n// One action row: a type select + its config as JSON (config shapes match the\n// Automations strategies exactly — see the plan doc).\nfunction ActionRow({ action, onChange, onRemove }) {\n  const [text, setText] = useState(() => pretty(action.config));\n  const [bad, setBad] = useState(false);\n  return (\n    <div style={{ border: '1px solid #e2e8f0', borderRadius: 8, padding: 10, marginTop: 8 }}>\n      <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\n        <Select\n          size=\"small\" style={{ width: 200 }} showSearch value={action.type || undefined}\n          placeholder=\"action type\" options={ACTION_TYPES.map((t) => ({ value: t }))}\n          onChange={(v) => {\n            // Picking an action whose config is still empty seeds a WORKING\n            // example rather than leaving a blank JSON box the admin has to\n            // guess the shape of. An action that already has config is left\n            // alone — switching type must never discard someone's settings.\n            const hasConfig = action.config && Object.keys(action.config).length > 0;\n            const sample = ACTION_HELP[v]?.sample;\n            onChange(hasConfig || !sample\n              ? { ...action, type: v }\n              : { ...action, type: v, config: sample });\n          }}\n        />\n        {bad && <Tag color=\"red\">invalid JSON</Tag>}\n        <Button size=\"small\" type=\"text\" danger icon={<DeleteOutlined />} style={{ marginLeft: 'auto' }} onClick={onRemove} />\n      </div>\n      {ACTION_HELP[action.type] && (\n        <p style={{ margin: '8px 0 0', fontSize: 12, color: '#64748b', lineHeight: 1.5 }}>\n          {ACTION_HELP[action.type].text}\n        </p>\n      )}\n      <Input.TextArea\n        rows={Math.min(14, Math.max(3, text.split('\\n').length))}\n        value={text}\n        className=\"fg-mono-input\"\n        style={{ marginTop: 8, fontSize: 12 }}\n        onChange={(e) => {\n          setText(e.target.value);\n          try {\n            onChange({ ...action, config: JSON.parse(e.target.value || '{}') });\n            setBad(false);\n          } catch { setBad(true); }\n        }}\n      />\n    </div>\n  );\n}\n\nfunction WorkflowDrawer({ open, doc, moduleOptions, onClose, onSave }) {\n  const [draft, setDraft] = useState(() => ({\n    key: '', module: '', event: 'afterCreate', order: 10, isActive: true,\n    condition: {}, actions: [],\n    ...(doc ?? {}),\n  }));\n  const [condText, setCondText] = useState(() => pretty(doc?.condition));\n  const [condBad, setCondBad] = useState(false);\n  const set = (k, v) => setDraft((d) => ({ ...d, [k]: v }));\n\n  const handleSave = () => {\n    if (!draft.key?.trim()) return message.error('Key is required');\n    if (!draft.module?.trim()) return message.error('Module is required');\n    if (condBad) return message.error('Condition JSON is invalid');\n    if (!(draft.actions ?? []).length) return message.error('At least one action is required');\n    if ((draft.actions ?? []).some((a) => !a.type)) return message.error('Every action needs a type');\n    const rest = { ...draft };\n    delete rest.id;\n    delete rest._id;\n    onSave(rest);\n  };\n\n  return (\n    <Modal\n      open={open} onCancel={onClose} width={840} centered destroyOnClose maskClosable={false}\n      className=\"fg-editor-modal\"\n      title={<span className=\"fg-drawer-title\"><ApartmentOutlined /> {doc ? 'Edit Workflow' : 'New Workflow'}</span>}\n      footer={<div className=\"fg-drawer-footer\"><Button onClick={onClose}>Cancel</Button><Button type=\"primary\" icon={<SaveOutlined />} onClick={handleSave}>Save Workflow</Button></div>}\n    >\n      <div className=\"fg-form-section\">\n        <div className=\"fg-field-meta-row\">\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Key</Text>\n            <Input size=\"small\" placeholder=\"jobs-create-after\" value={draft.key ?? ''} onChange={(e) => set('key', e.target.value)} className=\"fg-mono-input\" disabled={!!doc} />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Module</Text>\n            <Select size=\"small\" style={{ width: '100%' }} showSearch value={draft.module || undefined} options={moduleOptions} onChange={(v) => set('module', v)} placeholder=\"jobs\" />\n          </div>\n          <div style={{ flex: 1 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Event</Text>\n            <Select size=\"small\" style={{ width: '100%' }} value={draft.event} options={EVENTS.map((e) => ({ value: e }))} onChange={(v) => set('event', v)} />\n          </div>\n          <div style={{ width: 90 }}>\n            <Text type=\"secondary\" style={{ fontSize: 12 }}>Order</Text>\n            <InputNumber size=\"small\" style={{ width: '100%' }} value={draft.order ?? 10} onChange={(v) => set('order', v ?? 10)} />\n          </div>\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>\n          <Switch size=\"small\" checked={draft.isActive !== false} onChange={(v) => set('isActive', v)} />\n          <Text style={{ fontSize: 13 }}>Active</Text>\n        </div>\n\n        <div style={{ marginTop: 12 }}>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>\n            Condition (all must match the payload; empty = always run) {condBad && <Tag color=\"red\">invalid JSON</Tag>}\n          </Text>\n          <Input.TextArea\n            rows={2} value={condText} className=\"fg-mono-input\" style={{ fontSize: 12 }}\n            onChange={(e) => {\n              setCondText(e.target.value);\n              try { set('condition', JSON.parse(e.target.value || '{}')); setCondBad(false); } catch { setCondBad(true); }\n            }}\n          />\n        </div>\n\n        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 14 }}>\n          <Text strong style={{ fontSize: 13 }}>Actions (run in order)</Text>\n          <Button size=\"small\" type=\"dashed\" icon={<PlusOutlined />} onClick={() => set('actions', [...(draft.actions ?? []), { type: '', config: {} }])}>Add Action</Button>\n        </div>\n        {(draft.actions ?? []).map((a, i) => (\n          <ActionRow\n            key={i} action={a}\n            onChange={(next) => set('actions', draft.actions.map((x, idx) => (idx === i ? next : x)))}\n            onRemove={() => set('actions', draft.actions.filter((_, idx) => idx !== i))}\n          />\n        ))}\n        <Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginTop: 8 }}>\n          Config supports <code>{'{{field.path}}'}</code>, <code>{'{{now}}'}</code>, <code>{'{{__userId}}'}</code>,{' '}\n          <code>{'{{__userName}}'}</code>, and <code>{'{{hierarchy.<name>}}'}</code> from a <code>resolve</code> action.\n        </Text>\n      </div>\n    </Modal>\n  );\n}\n\nexport default function WorkflowsSection() {\n  const [docs, setDocs] = useState([]);\n  const [modules, setModules] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState('');\n  const [draft, setDraft] = useState(null); // { doc } | { doc: null }\n  const [moduleFilter, setModuleFilter] = useState('');\n\n  const [refreshKey, setRefreshKey] = useState(0);\n\n  // The effect performs only async state updates; the Reload button (and every\n  // save/delete) sets the spinner synchronously in its own handler, then bumps\n  // refreshKey to re-run this fetch.\n  useEffect(() => {\n    let cancelled = false;\n    listPlatformDocs('workflows')\n      .then((d) => { if (!cancelled) setDocs(d); })\n      .catch((e) => { if (!cancelled) setError(e?.message || 'Failed to load workflows'); })\n      .finally(() => { if (!cancelled) setLoading(false); });\n    return () => { cancelled = true; };\n  }, [refreshKey]);\n\n  useEffect(() => {\n    getAvailableModules()\n      .then((raw) => setModules(normalizeModuleOptions(raw).map(({ value, label }) => ({ value, label }))))\n      .catch(() => setModules([]));\n  }, []);\n\n  const load = () => {\n    setLoading(true); setError('');\n    setRefreshKey((k) => k + 1);\n  };\n\n  async function handleSave(doc) {\n    try {\n      await savePlatformDoc('workflows', doc);\n      message.success(`Workflow \"${doc.key}\" saved`);\n      setDraft(null);\n      load();\n    } catch (e) {\n      message.error(e?.message || 'Could not save workflow');\n    }\n  }\n\n  async function handleDelete(key) {\n    try {\n      await deletePlatformDoc('workflows', key);\n      message.success(`Workflow \"${key}\" deleted`);\n      load();\n    } catch (e) {\n      message.error(e?.message || 'Could not delete workflow');\n    }\n  }\n\n  async function toggleActive(doc, active) {\n    const rest = { ...doc };\n    delete rest.id;\n    delete rest._id;\n    try {\n      await savePlatformDoc('workflows', { ...rest, isActive: active });\n      load();\n    } catch (e) {\n      message.error(e?.message || 'Could not update workflow');\n    }\n  }\n\n  const rows = useMemo(\n    () => docs.filter((d) => !moduleFilter || d.module === moduleFilter),\n    [docs, moduleFilter],\n  );\n\n  const columns = [\n    { title: 'Key', dataIndex: 'key', key: 'key', render: (v) => <code className=\"fg-table-code\">{v}</code> },\n    { title: 'Module', dataIndex: 'module', key: 'module', width: 130, render: (v) => <Tag color=\"geekblue\">{v}</Tag> },\n    { title: 'Event', dataIndex: 'event', key: 'event', width: 130, render: (v) => <Tag color={String(v).startsWith('before') ? 'purple' : 'green'}>{v}</Tag> },\n    {\n      title: 'Actions', key: 'acts',\n      render: (_, d) => (\n        <Space size={4} wrap>\n          {(d.actions ?? []).map((a, i) => <Tag key={i} style={{ margin: 0 }}>{a.type}</Tag>)}\n        </Space>\n      ),\n    },\n    { title: 'Order', dataIndex: 'order', key: 'order', width: 70, align: 'center' },\n    {\n      title: 'Active', key: 'active', width: 80, align: 'center',\n      render: (_, d) => <Switch size=\"small\" checked={d.isActive !== false} onChange={(v) => toggleActive(d, v)} />,\n    },\n    {\n      title: '', key: 'ops', width: 90, align: 'right',\n      render: (_, d) => (\n        <Space size={4}>\n          <Tooltip title=\"Edit\"><Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => setDraft({ doc: d })} /></Tooltip>\n          <Popconfirm title={`Delete workflow \"${d.key}\"?`} onConfirm={() => handleDelete(d.key)}>\n            <Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} />\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <div className=\"fg-section\">\n      <AppCard\n        icon={<ApartmentOutlined />}\n        title=\"Workflows\"\n        extra={\n          <Space size={8}>\n            <Select\n              size=\"small\" style={{ minWidth: 160 }} allowClear placeholder=\"Filter by module\"\n              options={modules} value={moduleFilter || undefined} onChange={(v) => setModuleFilter(v ?? '')}\n            />\n            <Button size=\"small\" icon={<ReloadOutlined />} onClick={load}>Reload</Button>\n            <Button type=\"primary\" size=\"small\" icon={<PlusOutlined />} onClick={() => setDraft({ doc: null })}>New Workflow</Button>\n          </Space>\n        }\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          Event-driven behavior per module — reference ids, duplicate checks, snapshots, hierarchy fan-outs,\n          board updates, notifications, cache — executed by the platform Workflow Engine on every create/update/delete.\n          <Tag style={{ marginLeft: 8 }}>before*</Tag> actions can block the write; <Tag>after*</Tag> actions are best-effort.\n        </Text>\n      </AppCard>\n\n      <AppCard styles={{ body: { paddingTop: 8 } }}>\n        {error && <Alert type=\"error\" showIcon message={error} style={{ marginBottom: 12 }} />}\n        <Spin spinning={loading}>\n          <div style={{ marginBottom: 8 }}>\n            <Badge count={rows.length} showZero color=\"var(--color-brand)\" /> <Text type=\"secondary\" style={{ fontSize: 12 }}>workflows</Text>\n          </div>\n          <Table\n            rowKey=\"key\" dataSource={rows} columns={columns} pagination={false} size=\"small\" className=\"fg-table\"\n            locale={{ emptyText: <Empty description=\"No workflows configured.\" image={Empty.PRESENTED_IMAGE_SIMPLE} /> }}\n          />\n        </Spin>\n      </AppCard>\n\n      <WorkflowDrawer\n        key={draft ? (draft.doc?.key ?? 'new') : 'closed'}\n        open={!!draft} doc={draft?.doc} moduleOptions={modules}\n        onClose={() => setDraft(null)} onSave={handleSave}\n      />\n    </div>\n  );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport {\n  Button, Empty, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Table, Tag, Tooltip, Typography, message,\n} from 'antd';\nimport { DatabaseOutlined, DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport {\n  listModuleRecords, createModuleRecordGeneric, updateModuleRecordGeneric, deleteModuleRecordGeneric,\n  getLocationMasterOptions,\n} from '../../../services/adminApi';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\nconst idOf = (record) => record?._id ?? record?.id;\nconst MASTER_COLLECTION_MODULE = 'masters';\n\nfunction scopePayload() {\n  return {\n    tenantId: localStorage.getItem('tenantId') || '',\n    businessId: localStorage.getItem('businessId') || '',\n    businessUnitId: localStorage.getItem('businessUnitId') || '',\n  };\n}\n\nfunction oidValue(value) {\n  if (value && typeof value === 'object') return value.$oid ?? value.oid ?? value.id ?? '';\n  return value ?? '';\n}\n\nfunction recordScopeValue(record, keys) {\n  return keys.map((key) => oidValue(record?.[key])).find((value) => value !== undefined && value !== null && value !== '') ?? '';\n}\n\nfunction recordMatchesScope(record, scope) {\n  const pairs = [\n    [scope.tenantId, ['tid', 'tenantId']],\n    [scope.businessId, ['bid', 'businessId']],\n    [scope.businessUnitId, ['buid', 'businessUnitId']],\n  ];\n  return pairs.every(([expected, keys]) => {\n    if (!expected) return true;\n    const actual = String(recordScopeValue(record, keys));\n    return !actual || actual === String(expected);\n  });\n}\n\nfunction masterFeeds(record) {\n  return Array.isArray(record?.masterFeeds) ? record.masterFeeds : [];\n}\n\nfunction nextFeedUniqueId(feeds) {\n  const max = feeds.reduce((highest, feed) => Math.max(highest, Number(feed?.uniqueId) || 0), 0);\n  return max + 1;\n}\n\n// ── tax value / history helpers ──────────────────────────────────────────────\nfunction taxHistoryList(record) {\n  return Array.isArray(record?.taxHistory) ? record.taxHistory : [];\n}\n\nfunction currentTaxValue(record) {\n  const root = record?.taxValue;\n  if (root !== undefined && root !== null && root !== '') return Number(root);\n  const last = taxHistoryList(record).at(-1);\n  const value = last?.taxValue ?? last?.value;\n  return value !== undefined && value !== null && value !== '' ? Number(value) : undefined;\n}\n\nfunction formatDateTime(value) {\n  if (!value) return '—';\n  const parsed = new Date(value);\n  if (Number.isNaN(parsed.getTime())) return '—';\n  return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(parsed);\n}\n\nfunction latestTaxUpdatedAt(record) {\n  const last = taxHistoryList(record).at(-1);\n  return last?.updatedAt ?? last?.timestamp ?? record?.updatedAt;\n}\n\n// ── Location + Tax editor ────────────────────────────────────────────────────\n// Location is chosen from the locationMasters collection. Once a record exists,\n// the location is locked and only the tax is editable (every tax change is kept\n// in taxHistory with its timestamp).\nfunction LocationEditor({ open, record, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const [options, setOptions] = useState([]);\n  const [searching, setSearching] = useState(false);\n  const searchTimer = useRef(null);\n  const isEdit = Boolean(record);\n\n  useEffect(() => {\n    if (!open) return;\n    queueMicrotask(() => {\n      form.resetFields();\n      form.setFieldsValue({ name: record?.name ?? undefined, taxValue: currentTaxValue(record) });\n      // Seed the select with the current location so it renders on edit without a search.\n      setOptions(record?.name ? [{ label: record.name, value: record.name }] : []);\n    });\n  }, [open, record, form]);\n\n  function runSearch(search) {\n    if (searchTimer.current) clearTimeout(searchTimer.current);\n    if (!search || search.trim().length < 2) { setOptions([]); return; }\n    setSearching(true);\n    searchTimer.current = setTimeout(() => {\n      getLocationMasterOptions(search.trim())\n        .then(setOptions)\n        .catch(() => setOptions([]))\n        .finally(() => setSearching(false));\n    }, 350);\n  }\n\n  async function save() {\n    const values = await form.validateFields();\n    const taxValue = Number(values.taxValue);\n    const payload = {\n      name: values.name,\n      // Root taxValue stays the current value — configured submission lookups\n      // read locations.taxValue directly. The gateway appends {taxValue,\n      // updatedAt, updatedBy} to taxHistory (config-driven appendHistory).\n      taxValue,\n      taxHistory: { taxValue },\n    };\n    setSaving(true);\n    try {\n      if (isEdit) await updateModuleRecordGeneric('locations', idOf(record), payload);\n      else await createModuleRecordGeneric('locations', payload);\n      message.success(isEdit ? 'Tax updated' : 'Location and tax created');\n      onSaved();\n    } catch (error) {\n      message.error(error?.message || 'Could not save location and tax');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      onOk={save}\n      confirmLoading={saving}\n      destroyOnHidden\n      title={isEdit ? `Edit Tax — ${record?.name ?? ''}` : 'New Location'}\n    >\n      <Form form={form} layout=\"vertical\">\n        <Form.Item\n          name=\"name\"\n          label=\"Location\"\n          rules={[{ required: true, message: 'Location is required' }]}\n          tooltip={isEdit ? 'Location cannot be changed once created — only the tax is editable.' : 'Search and pick from the location master.'}\n        >\n          <Select\n            showSearch\n            disabled={isEdit}\n            placeholder=\"Type at least 2 characters to search…\"\n            filterOption={false}\n            onSearch={runSearch}\n            notFoundContent={searching ? 'Searching…' : null}\n            options={options}\n          />\n        </Form.Item>\n\n        <Form.Item\n          name=\"taxValue\"\n          label=\"Tax\"\n          rules={[\n            { required: true, message: 'Tax is required' },\n            { type: 'number', min: 0, max: 100, message: 'Tax must be between 0 and 100' },\n          ]}\n        >\n          <InputNumber style={{ width: '100%' }} min={0} max={100} step={0.01} suffix=\"%\" placeholder=\"8.875\" autoFocus={isEdit} />\n        </Form.Item>\n      </Form>\n    </Modal>\n  );\n}\n\n// ── Tax timeline (expanded row) ──────────────────────────────────────────────\nfunction TaxTimeline({ record }) {\n  const history = [...taxHistoryList(record)].reverse(); // newest first\n  if (!history.length) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=\"No tax history yet\" />;\n  return (\n    <Space direction=\"vertical\" size={4} style={{ padding: '4px 8px' }}>\n      {history.map((entry, index) => (\n        <Space key={index} size={10}>\n          <Tag color={index === 0 ? 'green' : 'default'} style={{ margin: 0 }}>\n            {entry.taxValue ?? entry.value}%\n          </Tag>\n          <Text type=\"secondary\" style={{ fontSize: 12 }}>{formatDateTime(entry.updatedAt ?? entry.timestamp)}</Text>\n          {index === 0 && <Text type=\"secondary\" style={{ fontSize: 12 }}>(current)</Text>}\n        </Space>\n      ))}\n    </Space>\n  );\n}\n\nfunction LocationsPanel() {\n  const [items, setItems] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [editorOpen, setEditorOpen] = useState(false);\n  const [editing, setEditing] = useState(null);\n\n  function load() {\n    setLoading(true);\n    listModuleRecords('locations')\n      .then(({ items: data }) => setItems(data))\n      .catch((error) => message.error(error?.message || 'Could not load locations'))\n      .finally(() => setLoading(false));\n  }\n\n  useEffect(() => { queueMicrotask(load); }, []);\n\n  async function remove(id) {\n    try {\n      await deleteModuleRecordGeneric('locations', id);\n      message.success('Location deleted');\n      load();\n    } catch (error) {\n      message.error(error?.message || 'Could not delete location');\n    }\n  }\n\n  const columns = [\n    { title: 'Location', dataIndex: 'name', key: 'name' },\n    {\n      title: 'Tax',\n      key: 'taxValue',\n      width: 100,\n      render: (_, record) => {\n        const value = currentTaxValue(record);\n        return Number.isFinite(value) ? <Tag color=\"blue\">{value}%</Tag> : '—';\n      },\n    },\n    { title: 'Tax updated', key: 'taxUpdatedAt', render: (_, record) => formatDateTime(latestTaxUpdatedAt(record)) },\n    { title: 'Created', key: 'createdAt', responsive: ['lg'], render: (_, record) => formatDateTime(record?.createdAt) },\n    {\n      title: '',\n      key: 'actions',\n      width: 90,\n      render: (_, record) => (\n        <Space size={4}>\n          <Tooltip title=\"Edit tax\">\n            <Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => { setEditing(record); setEditorOpen(true); }} />\n          </Tooltip>\n          <Popconfirm title=\"Delete this location?\" onConfirm={() => remove(idOf(record))}>\n            <Tooltip title=\"Delete\"><Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} /></Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard\n        title={`${items.length} location${items.length === 1 ? '' : 's'}`}\n        extra={(\n          <Space>\n            <Button icon={<ReloadOutlined />} onClick={load}>Reload</Button>\n            <Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditing(null); setEditorOpen(true); }}>\n              New location\n            </Button>\n          </Space>\n        )}\n      >\n        <Table\n          rowKey={idOf}\n          columns={columns}\n          dataSource={items}\n          loading={loading}\n          size=\"small\"\n          pagination={false}\n          className=\"fg-table\"\n          expandable={{\n            expandedRowRender: (record) => <TaxTimeline record={record} />,\n            rowExpandable: (record) => taxHistoryList(record).length > 0,\n          }}\n          locale={{ emptyText: 'No locations yet. Click \"New location\" to add one.' }}\n        />\n      </AppCard>\n      <LocationEditor\n        open={editorOpen}\n        record={editing}\n        onClose={() => setEditorOpen(false)}\n        onSaved={() => { setEditorOpen(false); load(); }}\n      />\n    </div>\n  );\n}\n\nfunction MasterCollectionEditor({ open, record, onClose, onSaved }) {\n  const [form] = Form.useForm();\n  const [saving, setSaving] = useState(false);\n  const isEdit = Boolean(record);\n  const watchedMasterName = Form.useWatch('masterName', form);\n  const watchedFeeds = Form.useWatch('masterFeeds', form) ?? [];\n  const isClientSubmissionStatusMaster = ['clientsubmissionstatus', 'clientsubmission', 'clientsubmissions']\n    .includes(String(watchedMasterName ?? record?.masterName ?? '').trim().toLowerCase());\n  const statusFeedOptions = watchedFeeds\n    .map((feed) => ({\n      label: String(feed?.name ?? '').trim() || `Status ${feed?.uniqueId ?? ''}`,\n      value: Number(feed?.uniqueId),\n    }))\n    .filter((option) => Number.isInteger(option.value) && option.value > 0);\n\n  function setSingleInitialStatus(rowIndex, enabled) {\n    if (!enabled) {\n      form.setFieldValue(['masterFeeds', rowIndex, 'isInitialStatus'], false);\n      return;\n    }\n\n    const feeds = form.getFieldValue('masterFeeds') ?? [];\n    feeds.forEach((_, index) => {\n      form.setFieldValue(['masterFeeds', index, 'isInitialStatus'], index === rowIndex);\n    });\n  }\n\n  function setTerminalStatus(rowIndex, enabled) {\n    form.setFieldValue(['masterFeeds', rowIndex, 'isTerminalStatus'], enabled);\n    if (enabled) {\n      form.setFieldValue(['masterFeeds', rowIndex, 'allowedNextStatusIds'], []);\n    }\n  }\n\n  useEffect(() => {\n    if (!open) return;\n    queueMicrotask(() => {\n      form.resetFields();\n\n      const masterName = record?.masterName ?? '';\n      const clientStatusMaster = ['clientsubmissionstatus', 'clientsubmission', 'clientsubmissions']\n        .includes(String(masterName).trim().toLowerCase());\n      const existingFeeds = masterFeeds(record);\n      let editorFeeds = existingFeeds.length\n        ? existingFeeds.map((feed) => ({ ...feed }))\n        : [{ uniqueId: 1, name: '', type: 'neutral', status: true, isdeleted: false }];\n\n      // Backward compatibility for existing clientSubmissionStatus masters that\n      // were created before Initial/Terminal/transition fields were introduced.\n      // If there is no active Initial status, make the first active feed Initial\n      // so the record can be edited/saved without manual migration first.\n      if (clientStatusMaster) {\n        const hasActiveInitial = editorFeeds.some((feed) => (\n          feed?.status !== false\n          && feed?.isdeleted !== true\n          && feed?.isInitialStatus === true\n        ));\n\n        if (!hasActiveInitial) {\n          const firstActiveIndex = editorFeeds.findIndex((feed) => (\n            feed?.status !== false && feed?.isdeleted !== true\n          ));\n          if (firstActiveIndex >= 0) {\n            editorFeeds = editorFeeds.map((feed, index) => ({\n              ...feed,\n              isInitialStatus: index === firstActiveIndex,\n              isTerminalStatus: feed?.isTerminalStatus === true,\n              allowedNextStatusIds: Array.isArray(feed?.allowedNextStatusIds)\n                ? feed.allowedNextStatusIds\n                : [],\n            }));\n          }\n        }\n      }\n\n      form.setFieldsValue({\n        masterName,\n        schemaVersion: record?.schemaVersion ?? 1,\n        masterFeeds: editorFeeds,\n      });\n    });\n  }, [open, record, form]);\n\n  useEffect(() => {\n    if (!open || !isClientSubmissionStatusMaster) return;\n    const currentVersion = Number(form.getFieldValue('schemaVersion')) || 1;\n    if (currentVersion < 2) form.setFieldValue('schemaVersion', 2);\n  }, [open, isClientSubmissionStatusMaster, form]);\n\n  async function save() {\n    const values = await form.validateFields();\n    const scope = scopePayload();\n    const clientStatusMaster = ['clientsubmissionstatus', 'clientsubmission', 'clientsubmissions']\n      .includes(String(values.masterName ?? '').trim().toLowerCase());\n    const feeds = (values.masterFeeds ?? [])\n      .map((feed, index) => {\n        const uniqueId = Number(feed.uniqueId) || index + 1;\n        const isTerminalStatus = clientStatusMaster && feed.isTerminalStatus === true;\n        const allowedNextStatusIds = clientStatusMaster && !isTerminalStatus\n          ? [...new Set((feed.allowedNextStatusIds ?? [])\n            .map(Number)\n            .filter((id) => Number.isInteger(id) && id > 0 && id !== uniqueId))]\n          : [];\n        return {\n          uniqueId,\n          name: String(feed.name ?? '').trim(),\n          type: String(feed.type ?? '').trim(),\n          status: feed.status !== false,\n          ...(clientStatusMaster ? {\n            isInitialStatus: feed.isInitialStatus === true,\n            isTerminalStatus,\n            allowedNextStatusIds,\n          } : {}),\n          isdeleted: feed.isdeleted === true,\n        };\n      })\n      .filter((feed) => feed.name);\n\n    if (clientStatusMaster) {\n      let activeInitialStatuses = feeds.filter((feed) => feed.status && !feed.isdeleted && feed.isInitialStatus);\n\n      // Legacy-safe fallback: older master records do not have isInitialStatus.\n      // When none is selected, promote the first active status automatically.\n      if (activeInitialStatuses.length === 0) {\n        const firstActiveIndex = feeds.findIndex((feed) => feed.status && !feed.isdeleted);\n        if (firstActiveIndex >= 0) {\n          feeds[firstActiveIndex] = {\n            ...feeds[firstActiveIndex],\n            isInitialStatus: true,\n          };\n          activeInitialStatuses = [feeds[firstActiveIndex]];\n          form.setFieldValue(['masterFeeds', firstActiveIndex, 'isInitialStatus'], true);\n        }\n      }\n\n      if (activeInitialStatuses.length !== 1) {\n        message.error('Client Submission Status must have exactly one active Initial Status.');\n        return;\n      }\n    }\n    const payload = {\n      ...scope,\n      tid: scope.tenantId,\n      bid: scope.businessId,\n      buid: scope.businessUnitId,\n      schemaVersion: clientStatusMaster ? Math.max(2, Number(values.schemaVersion) || 2) : (Number(values.schemaVersion) || 1),\n      masterName: values.masterName.trim(),\n      masterFeeds: feeds,\n    };\n\n    setSaving(true);\n    try {\n      if (isEdit) await updateModuleRecordGeneric(MASTER_COLLECTION_MODULE, idOf(record), payload);\n      else await createModuleRecordGeneric(MASTER_COLLECTION_MODULE, payload);\n      message.success(isEdit ? 'Master value updated' : 'Master value created');\n      onSaved();\n    } catch (error) {\n      message.error(error?.message || 'Could not save master value');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      onOk={save}\n      confirmLoading={saving}\n      destroyOnHidden\n      title={isEdit ? 'Edit Master Feed' : 'New Master Feed'}\n      width={1040}\n    >\n      <Form form={form} layout=\"vertical\">\n        <Form.Item name=\"masterName\" label=\"Master Name\" rules={[{ required: true, message: 'Master name is required' }]}>\n          <Input placeholder=\"blacklistType\" autoFocus={!isEdit} disabled={isEdit} />\n        </Form.Item>\n        <Form.Item name=\"schemaVersion\" label=\"Schema Version\">\n          <InputNumber min={1} style={{ width: '100%' }} />\n        </Form.Item>\n        <Form.List name=\"masterFeeds\">\n          {(fields, { add, remove }) => (\n            <Space direction=\"vertical\" style={{ width: '100%' }} size={10}>\n              {fields.map(({ key, name }) => (\n                <Space key={key} align=\"baseline\" wrap>\n                  <Form.Item name={[name, 'uniqueId']} label=\"ID\" rules={[{ required: true, message: 'ID required' }]}>\n                    <InputNumber min={1} style={{ width: 90 }} />\n                  </Form.Item>\n                  <Form.Item name={[name, 'name']} label=\"Name\" rules={[{ required: true, message: 'Name required' }]}>\n                    <Input placeholder=\"Dropdown label\" style={{ width: 280 }} />\n                  </Form.Item>\n                  <Form.Item name={[name, 'type']} label=\"Type\">\n                    <Select\n                      allowClear\n                      placeholder=\"Select type\"\n                      style={{ width: 120 }}\n                      options={[\n                        { label: 'Positive', value: 'positive' },\n                        { label: 'Neutral', value: 'neutral' },\n                        { label: 'Negative', value: 'negative' },\n                      ]}\n                    />\n                  </Form.Item>\n                  <Form.Item name={[name, 'status']} label=\"Status\" initialValue>\n                    <Select\n                      style={{ width: 110 }}\n                      options={[{ label: 'Active', value: true }, { label: 'Inactive', value: false }]}\n                    />\n                  </Form.Item>\n                  <Form.Item name={[name, 'isdeleted']} label=\"Deleted\" initialValue={false}>\n                    <Select\n                      style={{ width: 110 }}\n                      options={[{ label: 'No', value: false }, { label: 'Yes', value: true }]}\n                    />\n                  </Form.Item>\n                  {isClientSubmissionStatusMaster && (\n                    <>\n                      <Form.Item\n                        name={[name, 'isInitialStatus']}\n                        label=\"Initial\"\n                        initialValue={false}\n                        tooltip=\"The initial status is the only option shown before a candidate has a client submission status. Only one active initial status is allowed.\"\n                      >\n                        <Select\n                          style={{ width: 100 }}\n                          onChange={(value) => setSingleInitialStatus(name, value === true)}\n                          options={[{ label: 'Yes', value: true }, { label: 'No', value: false }]}\n                        />\n                      </Form.Item>\n                      <Form.Item\n                        name={[name, 'isTerminalStatus']}\n                        label=\"End Status\"\n                        initialValue={false}\n                        tooltip=\"End Status stops the configured client submission flow. Once reached, Change Status is hidden and no next statuses are allowed.\"\n                      >\n                        <Select\n                          style={{ width: 105 }}\n                          onChange={(value) => setTerminalStatus(name, value === true)}\n                          options={[{ label: 'Yes', value: true }, { label: 'No', value: false }]}\n                        />\n                      </Form.Item>\n                      <Form.Item\n                        noStyle\n                        shouldUpdate={(prev, next) => (\n                          prev?.masterFeeds?.[name]?.isTerminalStatus !== next?.masterFeeds?.[name]?.isTerminalStatus\n                          || prev?.masterFeeds?.[name]?.uniqueId !== next?.masterFeeds?.[name]?.uniqueId\n                          || prev?.masterFeeds !== next?.masterFeeds\n                        )}\n                      >\n                        {({ getFieldValue }) => {\n                          const terminal = getFieldValue(['masterFeeds', name, 'isTerminalStatus']) === true;\n                          const currentId = Number(getFieldValue(['masterFeeds', name, 'uniqueId']));\n                          return (\n                            <Form.Item\n                              name={[name, 'allowedNextStatusIds']}\n                              label=\"Allowed Next Statuses\"\n                              tooltip={terminal ? 'End Status cannot move to another status.' : 'Only these statuses will appear after the current status is saved.'}\n                            >\n                              <Select\n                                mode=\"multiple\"\n                                allowClear\n                                disabled={terminal}\n                                placeholder={terminal ? 'End status' : 'Select next statuses'}\n                                style={{ minWidth: 280 }}\n                                options={statusFeedOptions.filter((option) => option.value !== currentId)}\n                              />\n                            </Form.Item>\n                          );\n                        }}\n                      </Form.Item>\n                    </>\n                  )}\n                  <Tooltip title=\"Remove row\">\n                    <Button type=\"text\" danger icon={<DeleteOutlined />} onClick={() => remove(name)} />\n                  </Tooltip>\n                </Space>\n              ))}\n              <Button\n                icon={<PlusOutlined />}\n                onClick={() => add({\n                  uniqueId: nextFeedUniqueId(form.getFieldValue('masterFeeds') ?? []),\n                  name: '',\n                  type: 'neutral',\n                  status: true,\n                  isdeleted: false,\n                  ...(isClientSubmissionStatusMaster ? {\n                    isInitialStatus: false,\n                    isTerminalStatus: false,\n                    allowedNextStatusIds: [],\n                  } : {}),\n                })}\n              >\n                Add feed value\n              </Button>\n            </Space>\n          )}\n        </Form.List>\n      </Form>\n    </Modal>\n  );\n}\n\nfunction MasterCollectionsPanel() {\n  const [items, setItems] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [editorOpen, setEditorOpen] = useState(false);\n  const [editing, setEditing] = useState(null);\n  const [masterName, setMasterName] = useState('');\n\n  function load() {\n    const scope = scopePayload();\n    setLoading(true);\n    listModuleRecords(MASTER_COLLECTION_MODULE, { limit: 500 })\n      .then(({ items: data }) => {\n        const scoped = data.filter((record) => recordMatchesScope(record, scope));\n        setItems(scoped);\n      })\n      .catch((error) => message.error(error?.message || 'Could not load master values'))\n      .finally(() => setLoading(false));\n  }\n\n  useEffect(() => { queueMicrotask(load); }, []);\n\n  async function remove(id) {\n    try {\n      await deleteModuleRecordGeneric(MASTER_COLLECTION_MODULE, id);\n      message.success('Master value deleted');\n      load();\n    } catch (error) {\n      message.error(error?.message || 'Could not delete master value');\n    }\n  }\n\n  const filteredItems = masterName\n    ? items.filter((record) => String(record?.masterName ?? '').toLowerCase() === masterName.toLowerCase())\n    : items;\n  const masterOptions = [...new Set(items.map((record) => record?.masterName).filter(Boolean))]\n    .sort((a, b) => String(a).localeCompare(String(b)))\n    .map((value) => ({ label: value, value }));\n\n  const columns = [\n    { title: 'Master Name', dataIndex: 'masterName', key: 'masterName', width: 180 },\n    {\n      title: 'Feed Values',\n      key: 'masterFeeds',\n      render: (_, record) => (\n        <Space wrap>\n          {masterFeeds(record).filter((feed) => !feed.isdeleted).map((feed) => (\n            <Tag key={feed.uniqueId ?? feed.name} color={feed.status === false ? 'default' : 'blue'}>\n              {feed.name}\n            </Tag>\n          ))}\n        </Space>\n      ),\n    },\n    { title: 'Count', key: 'count', width: 90, render: (_, record) => masterFeeds(record).filter((feed) => !feed.isdeleted).length },\n    { title: 'Updated', key: 'updatedAt', responsive: ['lg'], render: (_, record) => formatDateTime(record?.updatedAt) },\n    {\n      title: '',\n      key: 'actions',\n      width: 90,\n      render: (_, record) => (\n        <Space size={4}>\n          <Tooltip title=\"Edit\">\n            <Button type=\"text\" size=\"small\" icon={<EditOutlined />} onClick={() => { setEditing(record); setEditorOpen(true); }} />\n          </Tooltip>\n          <Popconfirm title=\"Delete this master?\" onConfirm={() => remove(idOf(record))}>\n            <Tooltip title=\"Delete\"><Button type=\"text\" size=\"small\" danger icon={<DeleteOutlined />} /></Tooltip>\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard\n        title={`${filteredItems.length} master${filteredItems.length === 1 ? '' : 's'}`}\n        extra={(\n          <Space wrap>\n            <Select\n              allowClear\n              showSearch\n              placeholder=\"Filter master name\"\n              value={masterName || undefined}\n              options={masterOptions}\n              onChange={(value) => setMasterName(value ?? '')}\n              style={{ minWidth: 220 }}\n            />\n            <Button icon={<ReloadOutlined />} onClick={load}>Reload</Button>\n            <Button type=\"primary\" icon={<PlusOutlined />} onClick={() => { setEditing(null); setEditorOpen(true); }}>\n              New master\n            </Button>\n          </Space>\n        )}\n      >\n        <Table\n          rowKey={idOf}\n          columns={columns}\n          dataSource={filteredItems}\n          loading={loading}\n          size=\"small\"\n          pagination={{ pageSize: 10, showSizeChanger: true }}\n          className=\"fg-table\"\n          locale={{ emptyText: 'No masters yet. Click \"New master\" to add one.' }}\n        />\n      </AppCard>\n      <MasterCollectionEditor\n        open={editorOpen}\n        record={editing}\n        onClose={() => setEditorOpen(false)}\n        onSaved={() => { setEditorOpen(false); load(); }}\n      />\n    </div>\n  );\n}\n\nexport default function MastersSection() {\n  return (\n    <div className=\"fg-section\">\n      <AppCard icon={<DatabaseOutlined />} title=\"Master Collections\">\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          Create, update, and delete master documents, then customize multiple dropdown values inside masterFeeds.\n          Records are saved with the current tenant, business, business unit, and master name.\n        </Text>\n      </AppCard>\n      <MasterCollectionsPanel />\n      <AppCard icon={<DatabaseOutlined />} title=\"Location Tax Master\">\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\" style={{ fontSize: 13 }}>\n          Pick a location from the master list and set its tax. Once added, only the tax can be changed — every\n          change is kept in a timeline with its timestamp. Expand a row to see the full tax history.\n        </Text>\n      </AppCard>\n      <LocationsPanel />\n    </div>\n  );\n}\n","import { useEffect, useState } from 'react';\nimport { Button, Form, InputNumber, Space, Spin, Typography, message } from 'antd';\nimport { ReloadOutlined, SaveOutlined, SettingOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport { getPOMsaConfig, savePOMsaConfig } from '../../../services/adminApi';\nimport '../../../styles/FormGroupsSection.css';\n\nconst { Text } = Typography;\n\nconst DEFAULTS = {\n  employerMsaValidityDays: 365,\n  referralMsaValidityDays: 365,\n  expiryWarningDays: 30,\n};\n\nexport default function POMsaSettingsSection() {\n  const [form] = Form.useForm();\n  const [loading, setLoading] = useState(true);\n  const [saving, setSaving] = useState(false);\n\n  const load = async () => {\n    setLoading(true);\n    try {\n      const data = await getPOMsaConfig();\n      form.setFieldsValue({ ...DEFAULTS, ...(data || {}) });\n    } catch (error) {\n      message.error(error?.message || 'Could not load PO/MSA settings');\n      form.setFieldsValue(DEFAULTS);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  useEffect(() => {\n    load();\n  }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const save = async () => {\n    try {\n      const values = await form.validateFields();\n      setSaving(true);\n      const data = await savePOMsaConfig(values);\n      form.setFieldsValue({ ...DEFAULTS, ...(data || values) });\n      message.success('PO/MSA validity settings saved');\n    } catch (error) {\n      if (!error?.errorFields) message.error(error?.message || 'Could not save PO/MSA settings');\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  return (\n    <div className=\"fg-section admin-config-section\">\n      <AppCard\n        icon={<SettingOutlined />}\n        title=\"PO/MSA Validity Settings\"\n        extra={(\n          <Space>\n            <Button icon={<ReloadOutlined />} onClick={load} disabled={saving}>Reload</Button>\n            <Button type=\"primary\" icon={<SaveOutlined />} loading={saving} onClick={save}>Save</Button>\n          </Space>\n        )}\n      >\n        <div className=\"admin-accent-bar\" />\n        <Text type=\"secondary\">\n          Configure how long a signed MSA remains valid. Employer/referral status is calculated from the signed MSA date plus these values; no validity period is hardcoded in the onboarding UI.\n        </Text>\n      </AppCard>\n\n      <AppCard title=\"Validity Rules\">\n        <Spin spinning={loading}>\n          <Form form={form} layout=\"vertical\" initialValues={DEFAULTS} style={{ maxWidth: 620 }}>\n            <Form.Item\n              name=\"employerMsaValidityDays\"\n              label=\"Employer MSA Validity Days\"\n              tooltip=\"Number of days an employer MSA remains active from its signed date.\"\n              rules={[{ required: true, message: 'Employer MSA validity is required' }]}\n            >\n              <InputNumber min={1} max={3650} precision={0} style={{ width: '100%' }} addonAfter=\"days\" />\n            </Form.Item>\n            <Form.Item\n              name=\"referralMsaValidityDays\"\n              label=\"Referral MSA Validity Days\"\n              tooltip=\"Number of days a referral MSA remains active from its signed date.\"\n              rules={[{ required: true, message: 'Referral MSA validity is required' }]}\n            >\n              <InputNumber min={1} max={3650} precision={0} style={{ width: '100%' }} addonAfter=\"days\" />\n            </Form.Item>\n            <Form.Item\n              name=\"expiryWarningDays\"\n              label=\"Expiry Warning Days\"\n              tooltip=\"Reserved for upcoming-expiry indicators and notifications.\"\n              rules={[{ required: true, message: 'Expiry warning days is required' }]}\n            >\n              <InputNumber min={0} max={3650} precision={0} style={{ width: '100%' }} addonAfter=\"days\" />\n            </Form.Item>\n          </Form>\n        </Spin>\n      </AppCard>\n    </div>\n  );\n}\n","import {\n  Button, Form, Input, InputNumber, message, Modal, Popconfirm, Select, Space, Table, Tag, Typography,\n} from 'antd';\nimport {\n  AppstoreOutlined, BankOutlined, CalendarOutlined, DashboardOutlined, DeleteOutlined,\n  EditOutlined, FileProtectOutlined, FileTextOutlined, FolderOpenOutlined, PlusOutlined,\n  SettingOutlined, TeamOutlined, UploadOutlined, UsergroupAddOutlined, UserOutlined,\n} from '@ant-design/icons';\nimport { useEffect, useMemo, useState } from 'react';\nimport { createMenu, deleteMenu, listMenus, updateMenu } from '../../services/adminCoreApi';\n\nconst { Text, Title } = Typography;\n\nconst MENU_ICON_OPTIONS = [\n  { value: 'Dashboard', label: 'Dashboard', icon: <DashboardOutlined /> },\n  { value: 'ClientManagement', label: 'Client Management', icon: <BankOutlined /> },\n  { value: 'EmployerManagement', label: 'Employer / Referral', icon: <TeamOutlined /> },\n  { value: 'Candidates', label: 'Candidates', icon: <UsergroupAddOutlined /> },\n  { value: 'Jobs', label: 'Jobs', icon: <FileTextOutlined /> },\n  { value: 'Submissions', label: 'Submissions', icon: <FileTextOutlined /> },\n  { value: 'Onboarding', label: 'Onboarding', icon: <UserOutlined /> },\n  { value: 'Assignments', label: 'Assignments', icon: <AppstoreOutlined /> },\n  { value: 'Timesheet', label: 'Timesheet', icon: <CalendarOutlined /> },\n  { value: 'Campaign', label: 'Campaign', icon: <TeamOutlined /> },\n  { value: 'FileProtectOutlined', label: 'PO / MSA', icon: <FileProtectOutlined /> },\n  { value: 'FolderOpenOutlined', label: 'Batches', icon: <FolderOpenOutlined /> },\n  { value: 'BankOutlined', label: 'Billing / Finance', icon: <BankOutlined /> },\n  { value: 'SettingOutlined', label: 'Settings / Admin', icon: <SettingOutlined /> },\n  { value: 'UploadOutlined', label: 'Upload', icon: <UploadOutlined /> },\n  { value: 'AppstoreOutlined', label: 'General Module', icon: <AppstoreOutlined /> },\n];\n\nfunction IconOption({ option }) {\n  return (\n    <Space size={8}>\n      <span style={{ display: 'inline-flex', fontSize: 16 }}>{option.icon}</span>\n      <span>{option.label}</span>\n      <Text type=\"secondary\" style={{ fontSize: 11 }}>{option.value}</Text>\n    </Space>\n  );\n}\n\nfunction updateStoredSidebarMenu(menuKey, values) {\n  const raw = localStorage.getItem('menu');\n  if (!raw) return;\n  try {\n    const parsed = JSON.parse(raw);\n    const items = Array.isArray(parsed) ? parsed : parsed?.menu;\n    if (!Array.isArray(items)) return;\n\n    const targetKey = String(menuKey ?? values.menu_key ?? '').trim().toLowerCase();\n    const patchItems = (list) => list.map((item) => {\n      const currentKey = String(item?.key ?? '').trim().toLowerCase();\n      const next = currentKey === targetKey\n        ? {\n          ...item,\n          icon: values.icon ?? item.icon,\n          label: values.menu_name ?? item.label,\n          status: String(values.status ?? item.status ?? 'ACTIVE').toLowerCase(),\n        }\n        : item;\n      return Array.isArray(next?.children)\n        ? { ...next, children: patchItems(next.children) }\n        : next;\n    });\n\n    const nextItems = patchItems(items);\n    localStorage.setItem('menu', JSON.stringify(Array.isArray(parsed) ? nextItems : { ...parsed, menu: nextItems }));\n    window.dispatchEvent(new Event('menu:updated'));\n  } catch {\n    // A malformed/stale login cache should not block saving an admin menu.\n  }\n}\n\nexport default function MenusSection() {\n  const [form] = Form.useForm();\n  const [menus, setMenus] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [saving, setSaving] = useState(false);\n  const [editing, setEditing] = useState(null);\n  const [open, setOpen] = useState(false);\n\n  async function loadMenus() {\n    setLoading(true);\n    try {\n      setMenus(await listMenus());\n    } catch (error) {\n      message.error(error.message || 'Unable to load menus');\n    } finally {\n      setLoading(false);\n    }\n  }\n\n  useEffect(() => { loadMenus(); }, []);\n\n  const parentOptions = useMemo(() => menus\n    .filter((menu) => !editing || menu.menu_id !== editing.menu_id)\n    .map((menu) => ({ label: menu.menu_name, value: menu.menu_id })), [editing, menus]);\n\n  function showCreate() {\n    setEditing(null);\n    form.resetFields();\n    form.setFieldsValue({ menu_type: 'MENU', display_order: menus.length + 1, status: 'ACTIVE' });\n    setOpen(true);\n  }\n\n  function showEdit(menu) {\n    setEditing(menu);\n    form.setFieldsValue(menu);\n    setOpen(true);\n  }\n\n  async function submit(values) {\n    setSaving(true);\n    try {\n      if (editing) {\n        await updateMenu(editing.menu_id, values);\n        updateStoredSidebarMenu(editing.menu_key, values);\n      } else {\n        await createMenu(values);\n      }\n      message.success(editing ? 'Menu updated' : 'Menu created');\n      setOpen(false);\n      await loadMenus();\n    } catch (error) {\n      message.error(error.message || 'Unable to save menu');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  async function remove(menuId) {\n    try {\n      await deleteMenu(menuId);\n      message.success('Menu deleted');\n      await loadMenus();\n    } catch (error) {\n      message.error(error.message || 'Unable to delete menu');\n    }\n  }\n\n  const columns = [\n    { title: 'Name', dataIndex: 'menu_name' },\n    { title: 'Key', dataIndex: 'menu_key', render: (value) => <Tag>{value}</Tag> },\n    { title: 'Route / API', dataIndex: 'api_url' },\n    { title: 'Icon', dataIndex: 'icon', width: 170, render: (value) => <Tag>{value || 'Auto'}</Tag> },\n    { title: 'Type', dataIndex: 'menu_type', width: 110 },\n    { title: 'Order', dataIndex: 'display_order', width: 80 },\n    { title: 'Status', dataIndex: 'status', width: 100, render: (value) => <Tag color={value === 'ACTIVE' ? 'green' : 'default'}>{value}</Tag> },\n    {\n      title: '', key: 'actions', width: 90, render: (_, row) => (\n        <Space size={4}>\n          <Button aria-label=\"Edit menu\" size=\"small\" icon={<EditOutlined />} onClick={() => showEdit(row)} />\n          <Popconfirm title=\"Delete menu?\" onConfirm={() => remove(row.menu_id)}>\n            <Button aria-label=\"Delete menu\" danger size=\"small\" icon={<DeleteOutlined />} />\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <section className=\"admin-section\">\n      <div className=\"admin-section-head\">\n        <div><Title level={4}>Menus</Title><Text type=\"secondary\">Manage records in the MongoDB menus collection.</Text></div>\n        <Button type=\"primary\" icon={<PlusOutlined />} onClick={showCreate}>Add Menu</Button>\n      </div>\n      <Table rowKey=\"menu_id\" loading={loading} columns={columns} dataSource={menus} size=\"small\" pagination={{ pageSize: 10 }} />\n      <Modal title={editing ? 'Edit Menu' : 'Add Menu'} open={open} onCancel={() => setOpen(false)} onOk={() => form.submit()} confirmLoading={saving} destroyOnHidden>\n        <Form form={form} layout=\"vertical\" onFinish={submit}>\n          <Form.Item name=\"menu_name\" label=\"Menu name\" rules={[{ required: true }]}><Input /></Form.Item>\n          <Form.Item name=\"menu_key\" label=\"Menu key\" rules={[{ required: true }]}><Input placeholder=\"jobs\" /></Form.Item>\n          <Form.Item name=\"api_url\" label=\"Route / API URL\"><Input placeholder=\"/jobs\" /></Form.Item>\n          <Form.Item name=\"component_name\" label=\"Component\"><Input placeholder=\"Jobs\" /></Form.Item>\n          <div className=\"admin-form-row\">\n            <Form.Item name=\"menu_type\" label=\"Type\"><Select options={[{ value: 'MENU' }, { value: 'FOOTER' }, { value: 'CHILD' }]} /></Form.Item>\n            <Form.Item name=\"parent_menu_id\" label=\"Parent\"><Select allowClear options={parentOptions} /></Form.Item>\n          </div>\n          <div className=\"admin-form-row\">\n            <Form.Item name=\"display_order\" label=\"Display order\"><InputNumber min={0} /></Form.Item>\n            <Form.Item name=\"status\" label=\"Status\"><Select options={[{ value: 'ACTIVE' }, { value: 'INACTIVE' }]} /></Form.Item>\n          </div>\n          <Form.Item\n            name=\"icon\"\n            label=\"Sidebar icon\"\n            extra=\"Saved in the menus collection and used dynamically in the application sidebar.\"\n          >\n            <Select\n              allowClear\n              showSearch\n              placeholder=\"Select sidebar icon\"\n              optionFilterProp=\"label\"\n              options={MENU_ICON_OPTIONS.map(({ value, label }) => ({ value, label }))}\n              optionRender={(selectOption) => {\n                const value = selectOption?.value ?? selectOption?.data?.value;\n                const option = MENU_ICON_OPTIONS.find((item) => item.value === value);\n                return option ? <IconOption option={option} /> : value;\n              }}\n            />\n          </Form.Item>\n        </Form>\n      </Modal>\n    </section>\n  );\n}\n","import {\n  Button,\n  Checkbox,\n  Empty,\n  Form,\n  Input,\n  Layout,\n  Menu as AntMenu,\n  message,\n  Modal,\n  Popconfirm,\n  Select,\n  Space,\n  Spin,\n  Table,\n  Tabs,\n  Tag,\n  Typography,\n} from 'antd';\nimport {\n  ApartmentOutlined,\n  AppstoreAddOutlined,\n  AppstoreOutlined,\n  ArrowDownOutlined,\n  ArrowUpOutlined,\n  BgColorsOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  LogoutOutlined,\n  MailOutlined,\n  MenuOutlined,\n  PlusOutlined,\n  ReloadOutlined,\n  SaveOutlined,\n  SafetyCertificateOutlined,\n  TeamOutlined,\n  ThunderboltOutlined,\n  UserOutlined,\n} from '@ant-design/icons';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n  createUser,\n  createRole,\n  deleteRole,\n  deleteUser,\n  getRoleMenuPermissions,\n  listUserTypes,\n  listMenus,\n  listMenuPermissions,\n  listUsers,\n  getUsersFromRole,\n  saveRoleMenuPermissions,\n  updateUser,\n  updateRole,\n} from '../../services/adminCoreApi';\nimport {\n  getAvailableCollections,\n  getFieldConfigSeedStatus,\n  seedFieldConfig,\n} from '../../services/adminApi';\nimport { getStoredUser, logout } from '../../services/authApi';\nimport { isPermissionApplicable } from '../../utils/permissionApplicability';\nimport AppCard from '../../components/cards/AppCard';\nimport ParamListView from '../../components/ParamListView';\nimport ModuleFieldConfigEditor from '../Modules/Admin/components/ModuleFieldConfigEditor';\nimport RoleFormPermissionsEditor from '../Modules/Admin/components/RoleFormPermissionsEditor';\nimport RoleActionsEditor from '../Modules/Admin/components/RoleActionsEditor';\nimport FormGroupsSection from '../Modules/Admin/FormGroupsSection';\nimport DetailGroupsSection from '../Modules/Admin/DetailGroupsSection';\nimport ActionsSection from '../Modules/Admin/ActionsSection';\nimport TemplatesSection from '../Modules/Admin/TemplatesSection';\nimport AiServiceSettingsSection from '../Modules/Admin/AiServiceSettingsSection';\nimport IntegrationSettingsSection from '../Modules/Admin/IntegrationSettingsSection';\nimport AutomationsSection from '../Modules/Admin/AutomationsSection';\nimport WorkflowsSection from '../Modules/Admin/WorkflowsSection';\nimport MastersSection from '../Modules/Admin/MastersSection';\nimport POMsaSettingsSection from '../Modules/Admin/POMsaSettingsSection';\nimport MenusSection from './MenusSection';\nimport './AdminDashboard.css';\n\nconst { Content, Header, Sider } = Layout;\nconst { Text, Title } = Typography;\n\nfunction normalizeRoleName(value) {\n  return String(value ?? '').trim().replace(/[\\s_-]+/g, ' ').toUpperCase();\n}\n\nfunction moduleTitle(value) {\n  return String(value || '')\n    .replace(/[-_]/g, ' ')\n    .replace(/\\b\\w/g, (c) => c.toUpperCase())\n    .trim();\n}\n\nfunction normalizeSeedKey(value) {\n  return String(value || '').trim().toLowerCase();\n}\n\nfunction seedOptionValue(item) {\n  return item?.key || item?.collectionName || item?.value || '';\n}\n\nfunction buildSeedOptions(statusModules = [], collections = []) {\n  const options = [];\n  const seenValues = new Set();\n  const seededKeys = new Set();\n  const moduleCollections = new Set();\n\n  statusModules.forEach((module) => {\n    const value = seedOptionValue(module);\n    if (!value) return;\n\n    const key = normalizeSeedKey(module.key || value);\n    const collectionKey = normalizeSeedKey(module.collectionName);\n    if (module.seeded) {\n      seededKeys.add(key);\n      if (collectionKey) seededKeys.add(collectionKey);\n    }\n    if (collectionKey) moduleCollections.add(collectionKey);\n\n    seenValues.add(value);\n    options.push({\n      label: module.label || moduleTitle(value),\n      value,\n      disabled: Boolean(module.seeded),\n    });\n  });\n\n  collections.forEach((collection) => {\n    const value = String(collection || '').trim();\n    if (!value || seenValues.has(value)) return;\n\n    const collectionKey = normalizeSeedKey(value);\n    if (moduleCollections.has(collectionKey) || seededKeys.has(collectionKey)) return;\n\n    seenValues.add(value);\n    options.push({\n      label: moduleTitle(value),\n      value,\n      disabled: false,\n    });\n  });\n\n  return options;\n}\n\nfunction isSuperAdminUserType(userType) {\n  const userTypeName = userType?.user_type_name ?? userType?.userTypeName ?? userType?.name;\n\n  // Identify SUPER ADMIN by NAME only.\n  //\n  // This used to also treat `user_type_id === 1` as super admin. Role ids are\n  // per-deployment: in the migrated US database role 1 is RECRUITER, so that\n  // check silently hid all 135 recruiters from the users list AND from the\n  // \"User Type\" picker when adding a user — they could be neither seen nor\n  // assigned. A magic id cannot identify a role across databases; the name can.\n  return normalizeRoleName(userTypeName) === 'SUPER ADMIN';\n}\n\nfunction getUserDisplayName(user) {\n  const name = `${user?.first_name ?? user?.firstName ?? ''} ${user?.last_name ?? user?.lastName ?? ''}`.trim();\n  return name || user?.username || user?.userName || user?.email || `User ${user?.user_id ?? user?.userId ?? ''}`;\n}\n\nfunction getPermissionRows(groups) {\n  return groups.flatMap((menu) => {\n    const menuId = menu.menu_id ?? menu.menuId ?? menu.MenuID;\n    const menuName = menu.menu_name ?? menu.menuName ?? menu.MenuName ?? `Menu ${menuId ?? ''}`;\n    const menuKey = menu.menu_key ?? menu.menuKey ?? menu.MenuKey ?? '';\n    const permissions = menu.permissions ?? menu.Permissions ?? {};\n\n    return Object.entries(permissions).map(([permissionMapKey, permission]) => {\n      const permissionId = permission.permission_id ?? permission.permissionId ?? permission.PermissionID;\n      const permissionKey = permission.permission_key\n        ?? permission.permissionKey\n        ?? permission.PermissionKey\n        ?? permissionMapKey;\n      const rawValue = permission.value ?? permission.Value ?? permission.access_value ?? permission.accessValue ?? permission;\n\n      return {\n        key: `${menuKey ?? menuName ?? menuId}:${permissionId ?? permissionKey}`,\n        menuId,\n        menuName,\n        menuKey,\n        permissionId,\n        permissionKey,\n        accessValue: Number(rawValue) === 1 ? 1 : 0,\n      };\n    });\n  });\n}\n\nfunction permissionMenuIdentity(row) {\n  return String(row.menuKey ?? row.menuName ?? row.menuId).trim().toLowerCase();\n}\n\nconst REQUIRED_WORKFLOW_PERMISSION_ACTIONS = [\n  // `sendApprove` is already persisted in role_menu_permissions for Onboarding\n  // in older/current databases, but some deployments do not yet return it from\n  // the menu-permission action master endpoint.  Keep the role editor capable\n  // of rendering and saving that existing Mongo permission instead of silently\n  // dropping it from the matrix.\n  { permissionId: null, permissionKey: 'sendApprove', permissionName: 'Send Approve' },\n];\n\nfunction normalizePermissionActions(value) {\n  const candidate = Array.isArray(value) ? value : value?.permissions ?? value?.actions ?? value?.data ?? value;\n  const source = Array.isArray(candidate) ? candidate : Object.values(candidate ?? {});\n  const normalized = source.map((action) => ({\n    permissionId: action.permission_id ?? action.permissionId ?? action.legacyPermissionId ?? action.id ?? null,\n    permissionKey: action.permission_key ?? action.permissionKey ?? action.key,\n    permissionName: action.permission_name ?? action.permissionName ?? action.name ?? action.label,\n  })).filter((action) => action.permissionKey);\n\n  const existingKeys = new Set(normalized.map((action) => String(action.permissionKey).trim().toLowerCase()));\n  REQUIRED_WORKFLOW_PERMISSION_ACTIONS.forEach((action) => {\n    if (!existingKeys.has(action.permissionKey.toLowerCase())) normalized.push(action);\n  });\n  return normalized;\n}\n\nfunction permissionActionLabel(permission = {}) {\n  const explicit = String(permission.permissionName ?? '').trim();\n  if (explicit) return explicit;\n  return String(permission.permissionKey ?? '')\n    .replaceAll('_', ' ')\n    .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n    .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction PermissionEditor({\n  title,\n  description,\n  selectedName,\n  loading,\n  saving,\n  rows,\n  onChange,\n  onMove,\n  onSave,\n}) {\n  const menuRows = Object.values(rows.reduce((groups, row) => {\n    const menuIdentity = permissionMenuIdentity(row);\n    if (!groups[menuIdentity]) {\n      groups[menuIdentity] = {\n        key: menuIdentity,\n        menuName: row.menuName,\n        menuKey: row.menuKey,\n        permissions: [],\n      };\n    }\n    groups[menuIdentity].permissions.push(row);\n    return groups;\n  }, {}));\n\n  const columns = [\n    {\n      title: 'Menu',\n      dataIndex: 'menuName',\n      width: 220,\n      render: (value, row) => (\n        <div className=\"admin-menu-order-cell\">\n          <div className=\"admin-menu-cell\">\n            <span>{value}</span>\n            <Text type=\"secondary\">{row.menuKey}</Text>\n          </div>\n          <Space size={2}>\n            <Button size=\"small\" type=\"text\" icon={<ArrowUpOutlined />} onClick={() => onMove(row.key, -1)} aria-label={`Move ${value} up`} />\n            <Button size=\"small\" type=\"text\" icon={<ArrowDownOutlined />} onClick={() => onMove(row.key, 1)} aria-label={`Move ${value} down`} />\n          </Space>\n        </div>\n      ),\n    },\n    {\n      title: 'Actions',\n      dataIndex: 'permissions',\n      render: (permissions) => (\n        <div className=\"admin-permission-controls\">\n          {permissions\n            .filter((permission) => isPermissionApplicable(\n              permission.menuName ?? permission.menuKey,\n              permission.permissionKey,\n            ))\n            .map((permission) => (\n            <label className=\"admin-permission-control\" key={permission.key}>\n                <Checkbox\n                  checked={permission.accessValue === 1}\n                  onChange={(event) => onChange(permission.key, event.target.checked ? 1 : 0)}\n                aria-label={`${permission.menuName} ${permission.permissionKey}`}\n              >\n                {permissionActionLabel(permission)}\n              </Checkbox>\n            </label>\n          ))}\n        </div>\n      ),\n    },\n  ];\n\n  return (\n    <section className=\"admin-editor\">\n      <div className=\"admin-section-head\">\n        <div>\n          <Title level={4}>{title}</Title>\n          <Text type=\"secondary\">{selectedName || description}</Text>\n        </div>\n        <Button\n          type=\"primary\"\n          icon={<SaveOutlined />}\n          loading={saving}\n          disabled={!selectedName || rows.length === 0}\n          onClick={onSave}\n        >\n          Save\n        </Button>\n      </div>\n      {loading ? (\n        <div className=\"admin-loading\">\n          <Spin />\n        </div>\n      ) : menuRows.length ? (\n        <Table\n          size=\"small\"\n          rowKey=\"key\"\n          columns={columns}\n          dataSource={menuRows}\n          pagination={false}\n          scroll={{ y: 420 }}\n        />\n      ) : (\n        <Empty description=\"Select a record to customize permissions\" />\n      )}\n    </section>\n  );\n}\n\nfunction AdminDashboard({ onLogout }) {\n  const [userForm] = Form.useForm();\n  const [roleForm] = Form.useForm();\n  const [activeTab, setActiveTab] = useState('users');\n  const [loading, setLoading] = useState(true);\n  const [permissionLoading, setPermissionLoading] = useState(false);\n  const [saving, setSaving] = useState(false);\n  const [users, setUsers] = useState([]);\n  // Server-side paging/search state for the users list. The users collection is\n  // far too large to hold in the browser (6,134 rows here), and the previous\n  // client-side approach could only ever see the first 500 — see listUsers().\n  const [userTotal, setUserTotal] = useState(0);\n  const [userPage, setUserPage] = useState(1);\n  const [userPageSize, setUserPageSize] = useState(10);\n  const [userSearch, setUserSearch] = useState('');\n  const [usersLoading, setUsersLoading] = useState(false);\n  const [userTypes, setUserTypes] = useState([]);\n  const [menus, setMenus] = useState([]);\n  const [permissionActions, setPermissionActions] = useState([]);\n  const [selectedUserTypeId, setSelectedUserTypeId] = useState(null);\n  const [rolePermissionRows, setRolePermissionRows] = useState([]);\n  const [userModalOpen, setUserModalOpen] = useState(false);\n  const [editingUser, setEditingUser] = useState(null);\n  const [userSaving, setUserSaving] = useState(false);\n  const [userDeletingId, setUserDeletingId] = useState(null);\n  const [reportingUsers, setReportingUsers] = useState([]);\n  const [reportingUsersLoading, setReportingUsersLoading] = useState(false);\n  const [roleModalOpen, setRoleModalOpen] = useState(false);\n  const [editingRole, setEditingRole] = useState(null);\n  const [roleSaving, setRoleSaving] = useState(false);\n  const [configTarget, setConfigTarget] = useState(null);\n  const [configType, setConfigType] = useState('listView');\n  const [seedOptions, setSeedOptions] = useState([]);\n  const [seedModules, setSeedModules] = useState([]);\n  const [seedLoading, setSeedLoading] = useState(false);\n  const [seeding, setSeeding] = useState(false);\n  const currentUser = getStoredUser();\n\n  const availableSeedOptions = useMemo(\n    () => seedOptions.filter((option) => !option.disabled),\n    [seedOptions],\n  );\n  const allSeeded = !seedLoading && availableSeedOptions.length === 0;\n\n  const loadSeedState = useCallback(async () => {\n    setSeedLoading(true);\n    try {\n      const [status, collections] = await Promise.all([\n        getFieldConfigSeedStatus(),\n        getAvailableCollections(),\n      ]);\n      const options = buildSeedOptions(status.modules, collections);\n      const allowed = new Set(options.filter((option) => !option.disabled).map((option) => option.value));\n      setSeedOptions(options);\n      setSeedModules((prev) => prev.filter((value) => allowed.has(value)));\n    } catch {\n      message.error('Failed to load seed status');\n    } finally {\n      setSeedLoading(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    loadSeedState();\n  }, [loadSeedState]);\n\n  async function handleSeedFieldConfig() {\n    if (seedModules.length === 0) {\n      message.warning(allSeeded ? 'All modules already seeded.' : 'Select at least one module to seed.');\n      return;\n    }\n\n    setSeeding(true);\n    try {\n      await seedFieldConfig(seedModules);\n      message.success('User type field config seeded');\n      setSeedModules([]);\n      await loadSeedState();\n    } catch (error) {\n      message.error(error?.message || 'Seed failed');\n    } finally {\n      setSeeding(false);\n    }\n  }\n\n  async function loadData() {\n    setLoading(true);\n    try {\n      // Users are NOT loaded here — they have their own paged/searched effect\n      // below, because they are the one list that cannot be held in memory.\n      const [userTypesResult, menusResult, actionsResult] = await Promise.allSettled([\n        listUserTypes(),\n        listMenus(),\n        listMenuPermissions(),\n      ]);\n      const userTypesData = userTypesResult.status === 'fulfilled' ? userTypesResult.value : [];\n\n      if (userTypesResult.status === 'rejected') {\n        message.error(userTypesResult.reason?.message || 'Unable to load user types');\n      }\n\n      setUserTypes(userTypesData ?? []);\n      setMenus(menusResult.status === 'fulfilled' ? menusResult.value ?? [] : []);\n      setPermissionActions(actionsResult.status === 'fulfilled' ? normalizePermissionActions(actionsResult.value) : []);\n      setSelectedUserTypeId((userTypesData ?? [])[0]?.user_type_id ?? null);\n    } catch (error) {\n      message.error(error.message || 'Unable to load admin data');\n    } finally {\n      setLoading(false);\n    }\n  }\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      loadData();\n    });\n  }, []);\n\n  // Fetch ONE page of users, for the current search. Re-runs whenever the page,\n  // page size or search term changes — the search is sent to the server, so it\n  // matches across all 6,134 users rather than the handful already downloaded.\n  const loadUsers = useCallback(async () => {\n    setUsersLoading(true);\n    try {\n      const { users: rows, total } = await listUsers({\n        limit: userPageSize,\n        offset: (userPage - 1) * userPageSize,\n        search: userSearch,\n      });\n      setUsers(rows ?? []);\n      setUserTotal(total ?? 0);\n    } catch (error) {\n      message.error(error?.message || 'Unable to load users');\n      setUsers([]);\n      setUserTotal(0);\n    } finally {\n      setUsersLoading(false);\n    }\n  }, [userPage, userPageSize, userSearch]);\n\n  useEffect(() => { loadUsers(); }, [loadUsers]);\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      if (!selectedUserTypeId) {\n        setRolePermissionRows([]);\n        return;\n      }\n      setPermissionLoading(true);\n      console.log('DEBUG requesting role permissions for selectedUserTypeId=', selectedUserTypeId, 'localStorage scope=', {\n        tenantId: localStorage.getItem('tenantId'),\n        businessId: localStorage.getItem('businessId'),\n        businessUnitId: localStorage.getItem('businessUnitId'),\n      });\n      getRoleMenuPermissions(selectedUserTypeId)\n        .then((groups) => {\n          console.log('DEBUG raw groups from /get-role-details', groups);\n          const savedRows = getPermissionRows(groups ?? []);\n          console.log('DEBUG savedRows (jobs only)', savedRows.filter((r) => permissionMenuIdentity(r) === 'jobs' || permissionMenuIdentity(r) === 'job'));\n          const savedAccess = new Map(savedRows.map((row) => [\n            `${permissionMenuIdentity(row)}:${String(row.permissionKey).toLowerCase()}`,\n            row.accessValue,\n          ]));\n          console.log('DEBUG savedAccess keys', [...savedAccess.keys()]);\n          console.log('DEBUG menus (jobs only)', menus.filter((m) => String(m.menu_key ?? m.menu_name ?? m.menu_id).trim().toLowerCase() === 'jobs'));\n          const rows = menus.flatMap((menu) => permissionActions.map((action) => {\n            const menuIdentity = String(menu.menu_key ?? menu.menu_name ?? menu.menu_id).trim().toLowerCase();\n            const permissionKey = String(action.permissionKey).toLowerCase();\n            return {\n              key: `${menu.menu_key ?? menu.menu_name ?? menu.menu_id}:${action.permissionId ?? action.permissionKey}`,\n              menuId: menu.menu_id,\n              menuName: menu.menu_name,\n              menuKey: menu.menu_key,\n              permissionId: action.permissionId,\n              permissionKey: action.permissionKey,\n              accessValue: savedAccess.get(`${menuIdentity}:${permissionKey}`) ?? 0,\n            };\n          }));\n          console.log('DEBUG final rows (jobs only)', rows.filter((r) => permissionMenuIdentity(r) === 'jobs' || permissionMenuIdentity(r) === 'job'));\n          setRolePermissionRows(rows);\n        })\n        .catch((error) => message.error(error.message || 'Unable to load role permissions'))\n        .finally(() => setPermissionLoading(false));\n    });\n  }, [selectedUserTypeId, menus, permissionActions]);\n\n  const selectedUserType = useMemo(\n    () => userTypes.find((userType) => userType.user_type_id === selectedUserTypeId),\n    [selectedUserTypeId, userTypes],\n  );\n\n  const userTypeNameById = useMemo(() => (\n    userTypes.reduce((lookup, userType) => ({\n      ...lookup,\n      [userType.user_type_id]: userType.user_type_name,\n    }), {})\n  ), [userTypes]);\n\n  // Declared here, beside the other id -> name lookup, because\n  // reportingManagerOptions below reads it. A `const` is in the temporal dead\n  // zone until its own line runs, and a useMemo's dependency array is evaluated\n  // AT the useMemo call — so declaring this after that consumer threw\n  // \"Cannot access 'userNameById' before initialization\" and took the whole\n  // Admin route down with it.\n  const userNameById = useMemo(\n    () => users.reduce((lookup, user) => ({\n      ...lookup,\n      [user.user_id]: getUserDisplayName(user),\n    }), {}),\n    [users],\n  );\n\n  const manageableUserTypes = useMemo(\n    () => userTypes.filter((userType) => !isSuperAdminUserType(userType)),\n    [userTypes],\n  );\n\n  const manageableUsers = useMemo(\n    () => users.filter((user) => !isSuperAdminUserType({\n      user_type_id: user.user_type_id,\n      user_type_name: userTypeNameById[user.user_type_id],\n    })),\n    [userTypeNameById, users],\n  );\n\n  useEffect(() => {\n    if (!userModalOpen) {\n      setReportingUsers([]);\n      return;\n    }\n\n    const roleId = Number(userForm.getFieldValue('user_type_id') ?? 0);\n    if (!roleId) {\n      setReportingUsers([]);\n      return;\n    }\n\n    let cancelled = false;\n    setReportingUsersLoading(true);\n    getUsersFromRole(roleId)\n      .then((usersForRole) => {\n        if (cancelled) return;\n        setReportingUsers(\n          usersForRole.filter((user) => !editingUser || user.user_id !== editingUser.user_id),\n        );\n      })\n      .catch((error) => {\n        if (!cancelled) {\n          message.error(error.message || 'Unable to load reporting users');\n          setReportingUsers([]);\n        }\n      })\n      .finally(() => {\n        if (!cancelled) setReportingUsersLoading(false);\n      });\n\n    return () => {\n      cancelled = true;\n    };\n  }, [editingUser, userForm, userModalOpen]);\n\n  // Options a user may report to, per the role chain (/get-users returns the\n  // roles ABOVE this one, resolved through roles.reportingRoleId).\n  //\n  // The user's CURRENT manager is always included, even when the chain does not\n  // offer them. A Select renders the RAW VALUE when no option matches, so\n  // without this the form showed \"166\" where the list correctly showed\n  // \"PourushRealtek\" — the id was never meant to be user-visible. It happens\n  // whenever the stored manager sits outside the chain: employer logins (whose\n  // roleId is 0, so the chain is empty and the fetch is skipped entirely), and\n  // any user whose role or manager changed after the link was made.\n  //\n  // Showing the stored manager is also the honest thing to do: it is what will\n  // be saved if the field is left alone, so hiding it would misrepresent the\n  // record.\n  const reportingManagerOptions = useMemo(() => {\n    const options = reportingUsers.map((user) => ({\n      label: getUserDisplayName(user),\n      value: user.user_id,\n    }));\n    const currentId = Number(editingUser?.reporting_id ?? editingUser?.reportingId ?? 0);\n    if (!currentId) return options;\n    if (options.some((option) => Number(option.value) === currentId)) return options;\n    // reportingName is resolved server-side and is what the LIST already shows.\n    const label = editingUser?.reportingName\n      ?? editingUser?.reporting_name\n      ?? userNameById[currentId]\n      ?? `User ${currentId}`;\n    return [{ label, value: currentId }, ...options];\n  }, [editingUser, reportingUsers, userNameById]);\n\n  // The same rule for User Type. Employer logins carry roleId 0, which is in no\n  // role list, so the control showed a bare \"0\". Their own userType (\"Employer\")\n  // is the meaningful label until the role itself exists in the data.\n  const userTypeOptions = useMemo(() => {\n    const options = manageableUserTypes.map((userType) => ({\n      label: userType.user_type_name,\n      value: userType.user_type_id,\n    }));\n    if (!editingUser) return options;\n    const currentId = Number(editingUser.user_type_id ?? 0);\n    if (options.some((option) => Number(option.value) === currentId)) return options;\n    const label = userTypeNameById[currentId]\n      ?? editingUser.userType\n      ?? editingUser.roleName\n      ?? (currentId > 0 ? `Type ${currentId}` : 'Unassigned');\n    return [{ label, value: currentId }, ...options];\n  }, [editingUser, manageableUserTypes, userTypeNameById]);\n\n  const metrics = [\n    // The SERVER's count for the whole collection — manageableUsers is now just\n    // the current page, so its length would read as \"10 users\".\n    { label: 'Users', value: userTotal },\n    { label: 'User Types', value: userTypes.length },\n    { label: 'Menus', value: menus.length },\n  ];\n\n  const configurationItems = [\n    {\n      key: 'form-groups',\n      label: <span><AppstoreAddOutlined /> Form Groups</span>,\n      title: 'Form Groups',\n      description: 'Build module add and edit form groups with validations, dropdowns, and custom forms.',\n      component: <FormGroupsSection />,\n    },\n    {\n      key: 'detail-groups',\n      label: <span><BgColorsOutlined /> Detail Groups</span>,\n      title: 'Detail Groups',\n      description: 'Control detail-view labels, rendering, lookups, merged fields, and display defaults.',\n      component: <DetailGroupsSection />,\n    },\n    {\n      key: 'actions',\n      label: <span><ThunderboltOutlined /> Actions</span>,\n      title: 'Actions',\n      description: 'Manage row action buttons and their visibility rules from one workspace.',\n      component: <ActionsSection />,\n    },\n    {\n      key: 'templates',\n      label: <span><MailOutlined /> Templates</span>,\n      title: 'Templates',\n      description: 'Manage reusable email templates and signatures.',\n      component: <TemplatesSection />,\n    },\n    {\n      key: 'ai-services',\n      label: <span><ThunderboltOutlined /> AI Services</span>,\n      title: 'AI Services',\n      description: 'Register the AI and automation services used by admin-configured AI actions.',\n      component: <AiServiceSettingsSection />,\n    },\n    {\n      key: 'bgc-integration',\n      label: <span><SafetyCertificateOutlined /> Integrations</span>,\n      title: 'Integrations',\n      description: 'Manage manual and API integrations used across application workflows.',\n      component: <IntegrationSettingsSection />,\n    },\n    {\n      key: 'automations',\n      label: <span><ApartmentOutlined /> Automations</span>,\n      title: 'Automations',\n      description: 'Reference ids, duplicate checks, cross-module snapshots, reporting-chain hierarchy expansion, board updates, notifications, and cache invalidation — per module, config-driven.',\n      component: <AutomationsSection />,\n    },\n    {\n      key: 'workflows',\n      label: <span><ApartmentOutlined /> Workflows</span>,\n      title: 'Workflows',\n      description: 'Event-driven behavior per module (beforeCreate/afterCreate/…): the metadata the platform Workflow Engine executes — where the jobs, candidates, and submissions create flows live.',\n      component: <WorkflowsSection />,\n    },\n    {\n      key: 'po-msa-settings',\n      label: <span><SafetyCertificateOutlined /> PO/MSA Settings</span>,\n      title: 'PO/MSA Settings',\n      description: 'Configure employer and referral MSA validity and expiry warning days.',\n      component: <POMsaSettingsSection />,\n    },\n    {\n      key: 'masters',\n      label: <span><AppstoreAddOutlined /> Masters</span>,\n      title: 'Masters',\n      description: 'Shared Location and Tax lists used across modules (e.g. the submission form’s W2 employer section).',\n      component: <MastersSection />,\n    },\n  ];\n\n  const adminSidebarItems = [\n    {\n      key: 'users',\n      icon: <UserOutlined />,\n      label: 'Users',\n    },\n    {\n      key: 'roles',\n      icon: <TeamOutlined />,\n      label: 'User Types',\n    },\n    {\n      key: 'menus',\n      icon: <MenuOutlined />,\n      label: 'Menus',\n    },\n    {\n      key: 'configurations',\n      icon: <AppstoreAddOutlined />,\n      label: 'Configurations',\n    },\n    {\n      key: 'integrations',\n      icon: <SafetyCertificateOutlined />,\n      label: 'Integrations',\n    },\n  ];\n\n  function updateRolePermission(key, value) {\n    setRolePermissionRows((rows) => {\n      const matchCount = rows.filter((row) => row.key === key).length;\n      console.log('DEBUG updateRolePermission', { key, value, matchCount });\n      return rows.map((row) => (\n        row.key === key ? { ...row, accessValue: value } : row\n      ));\n    });\n  }\n\n  async function saveRolePermissions() {\n    setSaving(true);\n    try {\n      console.log('DEBUG saveRolePermissions jobs rows', rolePermissionRows.filter((row) => permissionMenuIdentity(row) === 'jobs' || permissionMenuIdentity(row) === 'job'));\n      await saveRoleMenuPermissions(selectedUserTypeId, rolePermissionRows.map((row) => ({\n        menu_id: row.menuId,\n        menu_name: row.menuName,\n        menu_key: row.menuKey,\n        permission_id: row.permissionId,\n        permission_key: row.permissionKey,\n        access_value: row.accessValue,\n        updated_by: currentUser?.userId ?? null,\n      })));\n      message.success('Role permissions updated');\n    } catch (error) {\n      message.error(error.message || 'Unable to save role permissions');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  function handleLogout() {\n    logout();\n    onLogout?.();\n  }\n\n  function openCreateUser() {\n    setEditingUser(null);\n    userForm.resetFields();\n    userForm.setFieldsValue({\n      status: 'ACTIVE',\n      user_type_id: manageableUserTypes[0]?.user_type_id,\n      reporting_id: 0,\n    });\n    setUserModalOpen(true);\n  }\n\n  function openEditUser(user) {\n    setEditingUser(user);\n    userForm.setFieldsValue({\n      first_name: user.first_name,\n      last_name: user.last_name,\n      username: user.username,\n      email: user.email,\n      mobile: user.mobile,\n      user_type_id: user.user_type_id,\n      reporting_id: user.reporting_id ?? user.reportingId ?? 0,\n      profile_image: user.profile_image,\n      status: user.status,\n    });\n    setUserModalOpen(true);\n  }\n\n  async function submitUser(values) {\n    setUserSaving(true);\n    try {\n      const payload = {\n        ...values,\n        // The auth API's UserMaster.status field is a Go string. Ant Select\n        // values or older saved form state may still provide 1/0.\n        status: values.status === 1 || values.status === '1' || values.status === true\n          ? 'ACTIVE'\n          : values.status === 0 || values.status === '0' || values.status === false\n            ? 'INACTIVE'\n            : String(values.status ?? 'ACTIVE').toUpperCase(),\n        updated_by: currentUser?.userId ?? null,\n        created_by: currentUser?.userId ?? null,\n      };\n      if (!payload.password) {\n        delete payload.password;\n      }\n      if (editingUser) {\n        await updateUser(editingUser.user_id, payload);\n        message.success('User updated');\n      } else {\n        await createUser(payload);\n        message.success('User created');\n      }\n      setUserModalOpen(false);\n      setEditingUser(null);\n      await loadUsers();\n    } catch (error) {\n      message.error(error.message || 'Unable to save user');\n    } finally {\n      setUserSaving(false);\n    }\n  }\n\n  async function handleDeleteUser(userId) {\n    setUserDeletingId(userId);\n    try {\n      await deleteUser(userId);\n      message.success('User deleted');\n      await loadUsers();\n    } catch (error) {\n      message.error(error.message || 'Unable to delete user');\n    } finally {\n      setUserDeletingId(null);\n    }\n  }\n\n  function openFieldConfig(kind, record) {\n    setConfigType('listView');\n    setConfigTarget({ kind, record });\n    if (kind === 'role') setSelectedUserTypeId(record.user_type_id);\n  }\n\n  function moveRoleMenu(menuIdentity, direction) {\n    setRolePermissionRows((rows) => {\n      const identities = [...new Set(rows.map(permissionMenuIdentity))];\n      const from = identities.indexOf(menuIdentity);\n      const to = from + direction;\n      if (from < 0 || to < 0 || to >= identities.length) return rows;\n      [identities[from], identities[to]] = [identities[to], identities[from]];\n      const rank = new Map(identities.map((identity, index) => [identity, index]));\n      return [...rows].sort((a, b) => rank.get(permissionMenuIdentity(a)) - rank.get(permissionMenuIdentity(b)));\n    });\n  }\n\n  function openCreateRole() {\n    setEditingRole(null);\n    roleForm.resetFields();\n    roleForm.setFieldsValue({ status: 'ACTIVE' });\n    setRoleModalOpen(true);\n  }\n\n  function openEditRole(role) {\n    setEditingRole(role);\n    setRoleModalOpen(true);\n    roleForm.setFieldsValue(role);\n  }\n\n  async function submitRole(values) {\n    setRoleSaving(true);\n    try {\n      const audit = currentUser?.userId ?? null;\n      const isEditing = Boolean(editingRole);\n      const role = isEditing\n        ? await updateRole(editingRole.user_type_id, { ...values, updated_by: audit })\n        : await createRole({ ...values, created_by: audit, visible_menu_ids: [] });\n      const roleId = role.user_type_id;\n      message.success(isEditing ? 'User type updated' : 'User type created. Customize its menus and permissions.');\n      setRoleModalOpen(false);\n      await loadData();\n      setSelectedUserTypeId(roleId);\n      if (!isEditing) {\n        setConfigType('permissions');\n        setConfigTarget({\n          kind: 'role',\n          record: {\n            ...values,\n            ...role,\n            user_type_id: roleId,\n            user_type_name: role.user_type_name ?? values.user_type_name,\n          },\n        });\n      }\n    } catch (error) {\n      message.error(error.message || 'Unable to save role');\n    } finally {\n      setRoleSaving(false);\n    }\n  }\n\n  async function handleDeleteRole(roleId) {\n    try {\n      await deleteRole(roleId);\n      message.success('Role deleted');\n      await loadData();\n    } catch (error) {\n      message.error(error.message || 'Unable to delete role');\n    }\n  }\n\n  const userFields = [\n    { label: 'Name', value: 'first_name', render: (value, row) => `${value ?? ''} ${row.last_name ?? ''}`.trim() || row.username },\n    { label: 'Email', value: 'email' },\n    {\n      label: 'User Type',\n      value: 'user_type_id',\n      width: 160,\n      // A raw id is never a useful thing to show a human. Provisioned employer\n      // logins carry roleId 0, which matches no role, so this column rendered\n      // literally \"Type 0\" for the 6,000 of them. Fall back to the user's own\n      // userType (\"Employer\") and only then to a dash — the id is meaningless\n      // to the person reading the screen either way.\n      render: (value, row) => userTypeNameById[value]\n        || row?.userType\n        || row?.user_type\n        || (Number(value) > 0 ? `Type ${value}` : '—'),\n    },\n    {\n      label: 'Reporting Manager',\n      value: 'reporting_id',\n      width: 180,\n      // userNameById can only resolve people on the CURRENT page now that users\n      // are server-paged, so an unresolved id shows the id rather than lying\n      // with \"None\" — which would read as \"no manager\" when there is one.\n      render: (value, row) => userNameById[value]\n        || row?.reportingName\n        || row?.reporting_name\n        || (Number(value) > 0 ? `User ${value}` : 'None'),\n    },\n    { label: 'Status', value: 'status', width: 110, sorter: false, render: (value) => <Tag color={value === 'ACTIVE' ? 'green' : 'default'}>{value}</Tag> },\n    {\n      label: 'Actions',\n      value: '_actions',\n      width: 150,\n      sorter: false,\n      render: (_, row) => (\n        <Space size={4}>\n          <Button\n            aria-label=\"Edit user\"\n            icon={<EditOutlined />}\n            size=\"small\"\n            onClick={() => openEditUser(row)}\n          />\n          <Popconfirm\n            title=\"Delete user?\"\n            description=\"This removes the user from the auth database.\"\n            okText=\"Delete\"\n            okButtonProps={{ danger: true }}\n            onConfirm={() => handleDeleteUser(row.user_id)}\n          >\n            <Button\n              danger\n              aria-label=\"Delete user\"\n              icon={<DeleteOutlined />}\n              loading={userDeletingId === row.user_id}\n              size=\"small\"\n            />\n          </Popconfirm>\n        </Space>\n      ),\n    },\n  ];\n\n  const userTypeFields = [\n    { label: 'User Type', value: 'user_type_name' },\n    { label: 'Description', value: 'description' },\n    { label: 'Status', value: 'status', width: 110, sorter: false, render: (value) => <Tag color={value === 'ACTIVE' ? 'green' : 'default'}>{value}</Tag> },\n    {\n      label: 'Actions',\n      value: '_actions',\n      width: 260,\n      sorter: false,\n      render: (_, row) => {\n        const isCustomRole = Number(row.role_type) === 1;\n        return (\n          <Space size={4}>\n          <Button aria-label=\"Configure role\" size=\"small\" onClick={() => openFieldConfig('role', row)}>Config</Button>\n          <Button aria-label=\"Edit role\" disabled={!isCustomRole} icon={<EditOutlined />} size=\"small\" onClick={() => openEditRole(row)} />\n          {isCustomRole && !isSuperAdminUserType(row) && (\n            <Popconfirm title=\"Delete role?\" onConfirm={() => handleDeleteRole(row.user_type_id)}>\n              <Button aria-label=\"Delete role\" danger icon={<DeleteOutlined />} size=\"small\" />\n            </Popconfirm>\n          )}\n        </Space>\n        );\n      },\n    },\n  ];\n\n  return (\n    <Layout className=\"admin-shell\">\n      <Sider width={248} className=\"admin-sider\">\n        {/* <div className=\"admin-brand\">\n          <img src=\"/favicon.svg\" alt=\"\" />\n          <div>\n            <strong>Zinnext</strong>\n            <span>Admin Core</span>\n          </div>\n        </div>\n        <div className=\"admin-profile\">\n          <Text>{currentUser?.username || 'Admin'}</Text>\n          <span>{currentUser?.email}</span>\n        </div> */}\n        <div className=\"admin-sidebar-nav\">\n          <Text className=\"admin-sidebar-title\">Admin Menu</Text>\n          <AntMenu\n            theme=\"dark\"\n            mode=\"inline\"\n            selectedKeys={[activeTab]}\n            onClick={({ key }) => setActiveTab(key)}\n            items={adminSidebarItems}\n          />\n        </div>\n      </Sider>\n      <Layout>\n        {/* <Header className=\"admin-header\">\n          <div>\n            <Title level={3}>Admin</Title>\n            <Text type=\"secondary\">Manage access and CORE-THEME configuration.</Text>\n          </div>\n          <Space>\n            <Button icon={<ReloadOutlined />} onClick={loadData}>Refresh</Button>\n            <Button icon={<LogoutOutlined />} onClick={handleLogout}>Logout</Button>\n          </Space>\n        </Header> */}\n        <Content className=\"admin-content\">\n          <>\n            {/* <div className=\"admin-metrics\">\n              {metrics.map((item) => (\n                <div className=\"admin-metric\" key={item.label}>\n                  <span>{item.label}</span>\n                  <strong>{item.value}</strong>\n                </div>\n              ))}\n            </div> */}\n            <Tabs\n              activeKey={activeTab}\n              onChange={setActiveTab}\n              tabBarStyle={{ display: 'none' }}\n              items={[\n                  {\n                    key: 'users',\n                    label: <span><UserOutlined /> Users</span>,\n                    children: (\n                      <div className=\"admin-stack\">\n                        <section className=\"admin-section\">\n                          <div className=\"admin-section-head\">\n                            <div>\n                              <Title level={4}>Users</Title>\n                              <Text type=\"secondary\">Create and manage users with non-super-admin user types.</Text>\n                            </div>\n                            <Button type=\"primary\" icon={<PlusOutlined />} onClick={openCreateUser}>\n                              Add\n                            </Button>\n                          </div>\n                          <ParamListView\n                            listName=\"Users\"\n                            loading={usersLoading}\n                            fields={userFields}\n                            dataSource={manageableUsers.map((user) => ({ ...user, key: user.user_id }))}\n                            // Server-driven: `total` is the count for the whole\n                            // query, not the rows in hand, and onSearch hands the\n                            // term to the API instead of filtering locally.\n                            total={userTotal}\n                            current={userPage}\n                            pageSize={userPageSize}\n                            onPageChange={setUserPage}\n                            onPageSizeChange={(size) => { setUserPageSize(size); setUserPage(1); }}\n                            onSearch={(term) => { setUserSearch(term ?? ''); setUserPage(1); }}\n                            rowSelection={false}\n                          />\n                        </section>\n                      </div>\n                    ),\n                  },\n                  {\n                    key: 'roles',\n                    label: <span><TeamOutlined /> User Types</span>,\n                    children: (\n                      <div className=\"admin-stack\">\n                        <AppCard\n                          icon={<AppstoreOutlined />}\n                          title=\"Field Config Seed\"\n                          style={{ marginBottom: 12 }}\n                        >\n                          <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>\n                            <div style={{ minWidth: 320, flex: 1 }}>\n                              <Select\n                                mode=\"multiple\"\n                                allowClear\n                                showSearch\n                                value={seedModules}\n                                options={seedOptions}\n                                placeholder={allSeeded ? 'All modules already seeded' : 'Select modules or collections to seed'}\n                                disabled={seedLoading || seeding || allSeeded}\n                                loading={seedLoading}\n                                onChange={setSeedModules}\n                                style={{ width: '100%' }}\n                              />\n                            </div>\n                            <Button\n                              type=\"primary\"\n                              loading={seeding}\n                              disabled={seedLoading || seedModules.length === 0}\n                              onClick={handleSeedFieldConfig}\n                            >\n                              Seed Field Config\n                            </Button>\n                          </div>\n                          <Text type=\"secondary\" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>\n                            {allSeeded\n                              ? 'Seed is disabled because all configured modules already have user type field config data.'\n                              : 'Already seeded modules are disabled. New modules or collections can still be seeded.'}\n                          </Text>\n                        </AppCard>\n                        <section className=\"admin-section\">\n                          <div className=\"admin-section-head\">\n                            <div>\n                              <Title level={4}>User Types</Title>\n                              <Text type=\"secondary\">Role level permissions are inherited by users.</Text>\n                            </div>\n                            <Button type=\"primary\" icon={<PlusOutlined />} onClick={openCreateRole}>Add Role</Button>\n                          </div>\n                          <ParamListView\n                            listName=\"User Types\"\n                            loading={loading}\n                            fields={userTypeFields}\n                            dataSource={userTypes.map((role) => ({\n                              ...role,\n                              key: role.user_type_id,\n                              roleId: role.user_type_id,\n                              roleName: role.user_type_name,\n                            }))}\n                            total={userTypes.length}\n                            rowSelection={false}\n                          />\n                        </section>\n                      </div>\n                    ),\n                  },\n                  {\n                    key: 'menus',\n                    label: <span><MenuOutlined /> Menus</span>,\n                    children: <MenusSection />,\n                  },\n                  {\n                    key: 'configurations',\n                    label: <span><AppstoreAddOutlined /> Configurations</span>,\n                    children: (\n                      <section className=\"admin-section admin-config-workspace\">\n                        <div className=\"admin-section-head\">\n                          <div>\n                            <Title level={4}>Configuration Center</Title>\n                            <Text type=\"secondary\">CORE-THEME admin modules embedded into the admin dashboard.</Text>\n                          </div>\n                          <Tag color=\"blue\">{configurationItems.length} configurations</Tag>\n                        </div>\n                        <Tabs\n                          className=\"admin-config-tabs\"\n                          defaultActiveKey=\"form-groups\"\n                          tabPosition=\"left\"\n                          items={configurationItems.map((item) => ({\n                            key: item.key,\n                            label: item.label,\n                            children: (\n                              <div className=\"admin-config-panel\">\n                                <div className=\"admin-config-panel-head\">\n                                  <div>\n                                    <Title level={4}>{item.title}</Title>\n                                    <Text type=\"secondary\">{item.description}</Text>\n                                  </div>\n                                </div>\n                                <div className=\"admin-config-panel-body\">\n                                  {item.component}\n                                </div>\n                              </div>\n                            ),\n                          }))}\n                        />\n                      </section>\n                    ),\n                  },\n                  {\n                    key: 'integrations',\n                    label: <span><SafetyCertificateOutlined /> Integrations</span>,\n                    children: (\n                      <section className=\"admin-section admin-config-workspace\">\n                        <div className=\"admin-section-head\">\n                          <div>\n                            <Title level={4}>Integrations</Title>\n                            <Text type=\"secondary\">Configure external services used by onboarding and other workflows.</Text>\n                          </div>\n                        </div>\n                        <div className=\"admin-config-panel\">\n                          <div className=\"admin-config-panel-body\">\n                            <IntegrationSettingsSection />\n                          </div>\n                        </div>\n                      </section>\n                    ),\n                  },\n              ]}\n            />\n          </>\n          <Modal\n            className=\"uss-modal\"\n            title={`Configure User Type: ${configTarget?.record?.user_type_name ?? ''}`}\n            open={Boolean(configTarget)}\n            onCancel={() => setConfigTarget(null)}\n            footer={null}\n            destroyOnHidden\n            width={900}\n          >\n            <div className=\"uss-config-toggle\" style={{ marginBottom: 12 }}>\n              {[\n                { key: 'listView', label: 'List View' },\n                { key: 'filter', label: 'Filter' },\n                { key: 'form', label: 'Form' },\n                { key: 'permissions', label: 'Permissions' },\n                { key: 'actions', label: 'Actions' },\n              ].map((item) => (\n                <button\n                  type=\"button\"\n                  key={item.key}\n                  className={`uss-config-btn${configType === item.key ? ' active' : ''}`}\n                  onClick={() => setConfigType(item.key)}\n                >\n                  {item.label}\n                </button>\n              ))}\n            </div>\n            {configTarget && configType === 'permissions' ? (\n              <PermissionEditor\n                title=\"Role Permissions\"\n                description=\"Configure menu permissions for this user type\"\n                selectedName={selectedUserType?.user_type_name}\n                loading={permissionLoading}\n                saving={saving}\n                rows={rolePermissionRows}\n                onChange={updateRolePermission}\n                onMove={moveRoleMenu}\n                onSave={saveRolePermissions}\n              />\n            ) : configTarget && configType === 'actions' ? (\n              <RoleActionsEditor\n                key={`${configTarget.record?.user_type_id}-actions`}\n                role={{\n                  ...configTarget.record,\n                  roleId: configTarget.record.user_type_id,\n                  roleName: configTarget.record.user_type_name,\n                }}\n              />\n            ) : configTarget && configType === 'form' ? (\n              <RoleFormPermissionsEditor\n                key={`${configTarget.record?.user_type_id}-form`}\n                role={{\n                  ...configTarget.record,\n                  roleId: configTarget.record.user_type_id,\n                  roleName: configTarget.record.user_type_name,\n                }}\n              />\n            ) : configTarget ? (\n              <ModuleFieldConfigEditor\n                key={`${configTarget.record?.user_type_id}-${configType}`}\n                role={{\n                  ...configTarget.record,\n                  roleId: configTarget.record.user_type_id,\n                  roleName: configTarget.record.user_type_name,\n                }}\n                configType={configType}\n              />\n            ) : null}\n          </Modal>\n          <Modal\n            className=\"admin-role-modal\"\n            title={editingRole ? 'Edit User Type' : 'Create User Type'}\n            open={roleModalOpen}\n            onCancel={() => setRoleModalOpen(false)}\n            onOk={() => roleForm.submit()}\n            okText={editingRole ? 'Save' : 'Next'}\n            confirmLoading={roleSaving}\n            destroyOnHidden\n            width={900}\n          >\n            <Form form={roleForm} layout=\"vertical\" onFinish={submitRole}>\n              <Form.Item name=\"user_type_name\" label=\"Role name\" rules={[{ required: true, message: 'Role name is required' }]}>\n                <Input placeholder=\"Recruiter\" />\n              </Form.Item>\n              <Form.Item name=\"description\" label=\"Description\"><Input.TextArea rows={3} /></Form.Item>\n              <Form.Item name=\"status\" label=\"Status\">\n                <Select options={[{ value: 'ACTIVE' }, { value: 'INACTIVE' }]} />\n              </Form.Item>\n            </Form>\n          </Modal>\n          <Modal\n            // Presentation hook only — a Modal renders in a PORTAL, outside\n            // .admin-shell, so admin styles cannot reach it without a class.\n            className=\"admin-user-modal\"\n            title={editingUser ? 'Edit User' : 'Add User'}\n            open={userModalOpen}\n            onCancel={() => setUserModalOpen(false)}\n            onOk={() => userForm.submit()}\n            confirmLoading={userSaving}\n            destroyOnHidden\n          >\n            <Form\n              form={userForm}\n              layout=\"vertical\"\n              requiredMark={false}\n              onFinish={submitUser}\n            >\n              <div className=\"admin-form-row\">\n                <Form.Item\n                  label=\"First Name\"\n                  name=\"first_name\"\n                  rules={[{ required: true, message: 'First name is required' }]}\n                >\n                  <Input placeholder=\"John\" />\n                </Form.Item>\n                <Form.Item label=\"Last Name\" name=\"last_name\">\n                  <Input placeholder=\"Doe\" />\n                </Form.Item>\n              </div>\n              <Form.Item\n                label=\"Username\"\n                name=\"username\"\n                rules={[{ required: true, message: 'Username is required' }]}\n              >\n                <Input placeholder=\"john.doe\" />\n              </Form.Item>\n              <Form.Item\n                label=\"Email\"\n                name=\"email\"\n                rules={[\n                  { required: true, message: 'Email is required' },\n                  { type: 'email', message: 'Enter a valid email' },\n                ]}\n              >\n                <Input placeholder=\"john@example.com\" />\n              </Form.Item>\n              <Form.Item\n                label={editingUser ? 'Password' : 'Password'}\n                name=\"password\"\n                rules={editingUser ? [] : [{ required: true, message: 'Password is required' }]}\n              >\n                <Input.Password placeholder={editingUser ? 'Leave empty to keep current password' : 'Password'} />\n              </Form.Item>\n              <div className=\"admin-form-row\">\n                <Form.Item label=\"Mobile\" name=\"mobile\">\n                  <Input placeholder=\"9999999999\" />\n                </Form.Item>\n                <Form.Item\n                  label=\"User Type\"\n                  name=\"user_type_id\"\n                  rules={[{ required: true, message: 'User type is required' }]}\n                >\n                  <Select\n                    placeholder=\"Select user type\"\n                    onChange={() => {\n                      setReportingUsers([]);\n                      queueMicrotask(() => {\n                        const roleId = Number(userForm.getFieldValue('user_type_id') ?? 0);\n                        if (roleId) {\n                          setReportingUsersLoading(true);\n                          getUsersFromRole(roleId)\n                            .then((usersForRole) => {\n                              setReportingUsers(\n                                usersForRole.filter((user) => !editingUser || user.user_id !== editingUser.user_id),\n                              );\n                            })\n                            .catch((error) => {\n                              message.error(error.message || 'Unable to load reporting users');\n                              setReportingUsers([]);\n                            })\n                            .finally(() => {\n                              setReportingUsersLoading(false);\n                            });\n                        }\n                      });\n                    }}\n                    options={userTypeOptions}\n                  />\n                </Form.Item>\n              </div>\n              <Form.Item label=\"Reporting Manager\" name=\"reporting_id\">\n                <Select\n                  allowClear\n                  showSearch\n                  loading={reportingUsersLoading}\n                  placeholder=\"Select reporting manager\"\n                  optionFilterProp=\"label\"\n                  options={[\n                    { label: 'None', value: 0 },\n                    ...reportingManagerOptions,\n                  ]}\n                />\n              </Form.Item>\n              <Form.Item label=\"Profile Image\" name=\"profile_image\">\n                <Input placeholder=\"https://...\" />\n              </Form.Item>\n              <Form.Item label=\"Status\" name=\"status\">\n                <Select\n                  options={[\n                    { label: 'ACTIVE', value: 'ACTIVE' },\n                    { label: 'INACTIVE', value: 'INACTIVE' },\n                  ]}\n                />\n              </Form.Item>\n            </Form>\n          </Modal>\n        </Content>\n      </Layout>\n    </Layout>\n  );\n}\n\nexport default AdminDashboard;\n","import AdminDashboard from '../admin/AdminDashboard';\n\nexport default AdminDashboard;\n","import { BrowserRouter, Navigate, Route, Routes, useNavigate } from 'react-router-dom';\nimport Login from './Login';\nimport AuthGuard from './AuthGuard';\nimport RawAdminPage from '../../pages/Modules/AdminPage';\nimport AppShell from '../layouts/AppShell';\n\nfunction normalizeBasePath(path, fallback) {\n  const value = String(path || fallback).replace(/\\/\\*$/, '').replace(/\\/+$/, '');\n  return value || fallback;\n}\n\nexport function CoreThemeAdminRoutes({\n  loginPath = '/login',\n  adminPath = '/admin',\n  fallbackPath = '/',\n}) {\n  const navigate = useNavigate();\n  const loginBase = normalizeBasePath(loginPath, '/login');\n  const adminBase = normalizeBasePath(adminPath, '/admin');\n  const adminRoutePath = `${adminBase}/*`;\n\n  return (\n    <Routes>\n      <Route\n        path={loginBase}\n        element={(\n          <Login\n            defaultRedirectPath={adminBase}\n            onLogin={() => navigate(adminBase, { replace: true })}\n          />\n        )}\n      />\n      <Route\n        path={adminRoutePath}\n        element={(\n          <AuthGuard loginPath={loginBase}>\n            <AppShell>\n              <RawAdminPage onLogout={() => navigate(loginBase, { replace: true })} />\n            </AppShell>\n          </AuthGuard>\n        )}\n      />\n      <Route path={fallbackPath} element={<Navigate to={adminBase} replace />} />\n      <Route path=\"*\" element={<Navigate to={adminBase} replace />} />\n    </Routes>\n  );\n}\n\nexport default function CoreThemeAdminApp(props) {\n  return (\n    <BrowserRouter>\n      <CoreThemeAdminRoutes {...props} />\n    </BrowserRouter>\n  );\n}\n","export function parseEmails(value) {\n  if (Array.isArray(value)) return value.map(String).map((item) => item.trim()).filter(Boolean);\n  return String(value ?? '').split(',').map((item) => item.trim()).filter(Boolean);\n}\n\nexport function areValidEmails(value) {\n  return parseEmails(value).every((email) => /^[^,\\s@]+@[^,\\s@]+\\.[^\\s@]{2,}$/.test(email));\n}\n","import { useEffect, useRef } from 'react';\nimport { Divider, Input, Select, Typography, message } from 'antd';\nimport { MailOutlined, PaperClipOutlined } from '@ant-design/icons';\nimport TipTapEditor from '../TipTapEditor';\nimport { getRuntimeEmailTemplate } from '../../services/emailTemplateApi';\nimport { getModuleDocuments } from '../../services/documentApi';\nimport { parseEmails } from './mailUtils';\n\nconst { Text } = Typography;\n\nconst DOCUMENT_TYPES = new Set(['file', 'document', 'attachment']);\n\nfunction isDocumentHolder(holder) {\n  return DOCUMENT_TYPES.has(String(holder?.type ?? '').trim().toLowerCase());\n}\n\nfunction normalizeModuleName(value) {\n  return String(value ?? '').trim().toLowerCase().replace(/[^a-z0-9]/g, '');\n}\n\nfunction objectIdValue(value) {\n  if (!value) return '';\n  if (typeof value === 'string') return value;\n  if (typeof value === 'object') return String(value?._id ?? value?.id ?? value?.$oid ?? '');\n  return String(value);\n}\n\nfunction resolveModuleRecordId(record, sourceModule, currentModule) {\n  if (!record) return '';\n  const source = normalizeModuleName(sourceModule);\n  const current = normalizeModuleName(currentModule);\n  if (!source || source === current || source.replace(/s$/, '') === current.replace(/s$/, '')) {\n    return objectIdValue(record?._id ?? record?.id);\n  }\n  const singular = source.replace(/s$/, '');\n  const candidates = [\n    `${singular}Id`, `${source}Id`, singular, source,\n    `${singular}._id`, `${source}._id`,\n  ];\n  for (const path of candidates) {\n    const value = nestedValue(record, path);\n    const id = objectIdValue(value);\n    if (id) return id;\n  }\n  return '';\n}\n\nasync function fetchDocumentFile(doc) {\n  const url = doc?.fileUrl ?? doc?.url ?? doc?.downloadUrl;\n  if (!url) return null;\n  const response = await fetch(url);\n  if (!response.ok) throw new Error(`Unable to load attachment ${doc?.fileName || ''}`.trim());\n  const blob = await response.blob();\n  const name = doc?.fileName ?? doc?.uploadedFileName ?? doc?.uniqueName ?? 'attachment';\n  return new File([blob], name, { type: doc?.contentType || blob.type || 'application/octet-stream' });\n}\n\nasync function resolveTemplateAttachments(template, record, currentModule) {\n  if (!record) return [];\n  const tasks = [];\n  (template?.placeholders ?? []).forEach((group) => {\n    (group?.holders ?? []).filter(isDocumentHolder).forEach((holder) => {\n      const refId = resolveModuleRecordId(record, group?.moduleName, currentModule);\n      if (!refId) return;\n      tasks.push((async () => {\n        const result = await getModuleDocuments(group.moduleName, refId, holder.value);\n        return Promise.all((result?.data ?? []).map(fetchDocumentFile));\n      })());\n    });\n  });\n  const files = (await Promise.all(tasks)).flat().filter(Boolean);\n  const seen = new Set();\n  return files.filter((file) => {\n    const key = `${file.name}:${file.size}:${file.type}`;\n    if (seen.has(key)) return false;\n    seen.add(key);\n    return true;\n  });\n}\n\nfunction mergeEmails(current, incoming) {\n  return [...new Set([...parseEmails(current), ...parseEmails(incoming)])].join(', ');\n}\n\nfunction nestedValue(record, path, arrayMode = '') {\n  const mode = String(arrayMode ?? '').trim().toLowerCase();\n  return String(path ?? '').split('.').reduce((value, key) => {\n    let current = value;\n    // A historical field such as submissions.proposedRate is an array.\n    // arrayMode=last means the newest APPENDED snapshot, exactly as configured\n    // by the template placeholder metadata.\n    if (Array.isArray(current) && mode === 'last') current = current.at(-1);\n    return current?.[key];\n  }, record);\n}\n\nexport function resolveTemplateText(text, placeholders, record) {\n  if (!record) return String(text ?? '');\n  const values = new Map();\n  (placeholders ?? []).forEach((group) => (group.holders ?? []).forEach((holder) => {\n    values.set(holder.key, isDocumentHolder(holder) ? '' : nestedValue(record, holder.value, holder.arrayMode));\n  }));\n  // Support both current {{.field}} and legacy {{field}} syntax.\n  return String(text ?? '').replace(/{{\\.?([\\w.]+)}}/g, (token, key) => {\n    const value = values.get(key);\n    return value === undefined || value === null ? token : String(value);\n  });\n}\n\nexport default function CommonMailComposer({\n  value,\n  onChange,\n  defaultTemplateId = '',\n  ready = true,\n  title = 'Mail',\n  hint,\n  bccHint,\n  afterBcc,\n  beforeFields,\n  className = '',\n  contextRecords = [],\n  moduleName = '',\n}) {\n  const appliedDefault = useRef('');\n\n  const patch = (next) => onChange?.({ ...value, ...next });\n\n  async function applyTemplate(id, quiet = false) {\n    if (!id) return;\n    try {\n      const template = await getRuntimeEmailTemplate(id);\n      const record = contextRecords[0];\n      const attachments = await resolveTemplateAttachments(template, record, moduleName);\n      patch({\n        to: mergeEmails(value.to, (template?.toMail ?? []).map((email) => resolveTemplateText(email, template?.placeholders, record))),\n        cc: mergeEmails(value.cc, (template?.ccMail ?? []).map((email) => resolveTemplateText(email, template?.placeholders, record))),\n        bcc: mergeEmails(value.bcc, (template?.bccMail ?? []).map((email) => resolveTemplateText(email, template?.placeholders, record))),\n        subject: resolveTemplateText(template?.subject, template?.placeholders, record),\n        contents: resolveTemplateText(template?.body, template?.placeholders, record),\n        attachments,\n      });\n      if (!quiet) message.success(`Loaded ${template?.name || 'email template'}`);\n    } catch (error) {\n      if (!quiet) message.error(error?.message || 'Could not load email template');\n    }\n  }\n\n  useEffect(() => {\n    if (!ready || !defaultTemplateId || appliedDefault.current === defaultTemplateId) return;\n    appliedDefault.current = defaultTemplateId;\n    applyTemplate(defaultTemplateId, true);\n    // Apply once after the popup's record defaults have loaded.\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [defaultTemplateId, ready]);\n\n  return (\n    <div className={`common-mail-composer ${className}`.trim()}>\n      <div className=\"mail-popup__header\">\n        <div className=\"mail-popup__header-brand\">\n          <span className=\"dynamic-popup__header-icon-box\">\n            <MailOutlined />\n          </span>\n          <div>\n            <span className=\"dynamic-popup__header-label\">{title}</span>\n            {hint && <Text type=\"secondary\" className=\"mail-popup__header-hint\">{hint}</Text>}\n          </div>\n        </div>\n      </div>\n\n      <div className=\"mail-popup__body\">\n        {beforeFields && <>{beforeFields}<Divider /></>}\n        <div className=\"mail-popup__field-row\">\n          <Text type=\"secondary\" className=\"mail-popup__field-label\">To</Text>\n          <Select mode=\"tags\" open={false} tokenSeparators={[',']} value={parseEmails(value.to)} onChange={(items) => patch({ to: items.join(', ') })} variant=\"borderless\" className=\"mail-popup__recipient-select\" placeholder=\"Add email addresses\" />\n          <div className=\"mail-popup__cc-bcc-actions\">\n            {!value.showCc && <span className=\"mail-popup__cc-bcc-link\" onClick={() => patch({ showCc: true })}>Cc</span>}\n            {!value.showBcc && <span className=\"mail-popup__cc-bcc-link\" onClick={() => patch({ showBcc: true })}>Bcc</span>}\n          </div>\n        </div>\n        <Divider />\n        {value.showCc && <><div className=\"mail-popup__field-row\"><Text type=\"secondary\" className=\"mail-popup__field-label\">Cc</Text><Select mode=\"tags\" open={false} tokenSeparators={[',']} value={parseEmails(value.cc)} onChange={(items) => patch({ cc: items.join(', ') })} variant=\"borderless\" className=\"mail-popup__recipient-select\" /></div><Divider /></>}\n        {value.showBcc && <><div className=\"mail-popup__field-row\"><Text type=\"secondary\" className=\"mail-popup__field-label\">Bcc</Text><Select mode=\"tags\" open={false} tokenSeparators={[',']} value={parseEmails(value.bcc)} onChange={(items) => patch({ bcc: items.join(', ') })} variant=\"borderless\" className=\"mail-popup__recipient-select\" placeholder={bccHint} /></div>{afterBcc}<Divider /></>}\n        <div className=\"mail-popup__field-row\"><Text type=\"secondary\" className=\"mail-popup__field-label\">Subject</Text><Input variant=\"borderless\" value={value.subject} onChange={(event) => patch({ subject: event.target.value })} placeholder=\"Enter subject\" className=\"mail-popup__field-input\" /></div>\n        <Divider />\n        {!!value.attachments?.length && (\n          <>\n            <div className=\"mail-popup__field-row\">\n              <Text type=\"secondary\" className=\"mail-popup__field-label\">Attachments</Text>\n              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, padding: '4px 0' }}>\n                {value.attachments.map((file, index) => (\n                  <span key={`${file.name}:${file.size}:${index}`} style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n                    <PaperClipOutlined />{file.name}\n                  </span>\n                ))}\n              </div>\n            </div>\n            <Divider />\n          </>\n        )}\n        <div className=\"mail-popup__message-section\"><Text type=\"secondary\" className=\"mail-popup__message-label\">Message</Text><TipTapEditor value={value.contents} onChange={(contents) => patch({ contents })}/></div>\n      </div>\n    </div>\n  );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Button, Drawer, Select, Spin, Typography, message } from 'antd';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { formatMailContentForMail, getBulkMailDetails, sendBulkMail } from '../../services/dropdownApi';\nimport { getModuleDataDetail } from '../../services/detailedViewApi';\nimport { getModuleFields } from '../../services/adminApi';\nimport { getModuleDocuments } from '../../services/documentApi';\nimport { searchJobs } from '../../services/popupApi';\nimport CommonMailComposer from './CommonMailComposer';\nimport { areValidEmails, parseEmails } from './mailUtils';\n\nconst { Text } = Typography;\nconst OBJECT_ID_RE = /^[a-fA-F0-9]{24}$/;\nconst DOCUMENT_TYPES = new Set(['file', 'document', 'attachment']);\n\nasync function documentToFile(doc) {\n  const url = doc?.fileUrl ?? doc?.url ?? doc?.downloadUrl;\n  if (!url) return null;\n  const response = await fetch(url);\n  if (!response.ok) throw new Error(`Unable to load attachment ${doc?.fileName || ''}`.trim());\n  const blob = await response.blob();\n  const name = doc?.fileName ?? doc?.uploadedFileName ?? doc?.uniqueName ?? 'attachment';\n  return new File([blob], name, { type: doc?.contentType || blob.type || 'application/octet-stream' });\n}\n\nasync function resolveBodyDocumentPlaceholders(contents, moduleName, records = []) {\n  let cleaned = String(contents ?? '');\n  if (!cleaned || !records.length || !moduleName) return { contents: cleaned, attachments: [] };\n\n  const fields = await getModuleFields(moduleName).catch(() => []);\n  const documentFields = fields.filter((field) => DOCUMENT_TYPES.has(String(field?.type ?? '').trim().toLowerCase()));\n  const used = documentFields.filter((field) => {\n    const key = String(field?.value ?? field?.field ?? field?.fieldKey ?? field?.key ?? field?.name ?? '').replace(/^\\./, '');\n    return key && (cleaned.includes(`{{.${key}}}`) || cleaned.includes(`{{${key}}}`));\n  });\n  if (!used.length) return { contents: cleaned, attachments: [] };\n\n  const files = [];\n  for (const field of used) {\n    const key = String(field?.value ?? field?.field ?? field?.fieldKey ?? field?.key ?? field?.name ?? '').replace(/^\\./, '');\n    cleaned = cleaned.replaceAll(`{{.${key}}}`, '').replaceAll(`{{${key}}}`, '');\n    for (const record of records) {\n      const refId = String(record?._id ?? record?.id ?? '');\n      if (!OBJECT_ID_RE.test(refId)) continue;\n      const result = await getModuleDocuments(moduleName, refId, key).catch(() => ({ data: [] }));\n      const resolved = await Promise.all((result?.data ?? []).map(documentToFile));\n      files.push(...resolved.filter(Boolean));\n    }\n  }\n\n  const seen = new Set();\n  const attachments = files.filter((file) => {\n    const signature = `${file.name}:${file.size}:${file.type}`;\n    if (seen.has(signature)) return false;\n    seen.add(signature);\n    return true;\n  });\n  return { contents: cleaned, attachments };\n}\n\nfunction isEnabled(value) {\n  if (value === true) return true;\n  if (typeof value === 'number') return value === 1;\n  if (typeof value !== 'string') return false;\n  return ['true', '1', 'yes', 'y', 'on'].includes(value.trim().toLowerCase());\n}\n\nfunction isCandidateModule(moduleName) {\n  return ['candidate', 'candidates'].includes(String(moduleName ?? '').trim().toLowerCase());\n}\n\nfunction pickValue(record, ...keys) {\n  for (const key of keys) {\n    const value = String(key).split('.').reduce((current, part) => current?.[part], record);\n    if (value !== undefined && value !== null && String(value).trim() !== '') return value;\n  }\n  return undefined;\n}\n\nfunction optionLabel(job) {\n  const reference = pickValue(job, 'jobReferenceId', 'clientJobId', 'jobCode', 'reqId', 'jobId');\n  const title = pickValue(job, 'jobTitle', 'title', 'name');\n  return [reference, title].filter(Boolean).join(' - ') || String(pickValue(job, '_id', 'id') ?? 'Job');\n}\n\nfunction normalizeJobOption(job) {\n  const value = pickValue(job, '_id', 'id', 'jobId');\n  if (!value) return null;\n  return { value: String(value), label: optionLabel(job), raw: job };\n}\n\nfunction collectRecordEmails(records = [], fields = []) {\n  const fieldList = [\n    ...fields,\n    'email',\n    'candidateEmail',\n    'candidate_email',\n    'emailId',\n    'mailId',\n    'alternateEmail',\n    'altEmail',\n    'basicDetails.email',\n    'basicDetails.alternateEmail',\n    'basicDetails.altEmail',\n    'candidate.email',\n    'candidate.emailId',\n    'submission.email',\n    'submission.candidateEmail',\n  ].filter(Boolean);\n\n  return records.flatMap((record) => fieldList.map((field) => pickValue(record, field)))\n    .flatMap((value) => (Array.isArray(value) ? value : [value]))\n    .flatMap(parseEmails);\n}\n\nfunction unwrapRecord(response) {\n  return response?.data?.record\n    ?? response?.record\n    ?? response?.data\n    ?? response;\n}\n\nfunction pickJobIdFromRecord(record) {\n  const value = pickValue(\n    record,\n    'jobId',\n    'job_id',\n    'job._id',\n    'job.id',\n    'jobs._id',\n    'jobs.id',\n  );\n  if (typeof value === 'object') return pickValue(value, '_id', 'id', '$oid');\n  return value;\n}\n\nfunction normalizeMailDetails(data = {}) {\n  return {\n    subject: data.subject ?? data.Subject ?? '',\n    contents: data.contents ?? data.Contents ?? data.body ?? data.Body ?? '',\n    toMail: data.toMail ?? data.ToMail ?? [],\n    ccMail: data.ccMail ?? data.CcMail ?? [],\n    bccMail: data.bccMail ?? data.BccMail ?? [],\n  };\n}\n\nexport default function MailPopup() {\n  const navigate = useNavigate();\n  const { state = {} } = useLocation();\n  const {\n    selectedIds = [], selectedRecords = [], recipients = [],\n    subject: initialSubject = '', onSend, moduleName = '', popupAction = {},\n  } = state;\n  const requireJobId = isEnabled(popupAction.requireJobId)\n    || isEnabled(state.requireJobId)\n    || isCandidateModule(moduleName);\n  const recipientFields = useMemo(() => [\n    popupAction.recipientField,\n    popupAction.recipientPath,\n    state.recipientField,\n    state.recipientPath,\n  ], [popupAction.recipientField, popupAction.recipientPath, state.recipientField, state.recipientPath]);\n  const selectedIdKey = selectedIds.join('|');\n  const initialRecipients = useMemo(() => [\n    ...recipients,\n    ...collectRecordEmails(selectedRecords, recipientFields),\n  ], [recipients, selectedRecords, recipientFields]);\n  const initialJobId = String(state.jobId ?? pickJobIdFromRecord(selectedRecords[0]) ?? '').trim();\n  const legacyJobId = selectedIds[0] ?? selectedRecords[0]?._id ?? selectedRecords[0]?.id ?? '';\n  const [jobIdInput, setJobIdInput] = useState(initialJobId);\n  const [jobId, setJobId] = useState(requireJobId ? initialJobId : String(initialJobId || legacyJobId || ''));\n  const [mail, setMail] = useState({\n    to: [...new Set(initialRecipients)].join(', '), cc: '', bcc: '', subject: initialSubject,\n    contents: '', attachments: [], showCc: false, showBcc: false,\n  });\n  const [detailsLoaded, setDetailsLoaded] = useState(!jobId);\n  const [loadingJob, setLoadingJob] = useState(false);\n  const [jobOptions, setJobOptions] = useState([]);\n  const [jobSearchLoading, setJobSearchLoading] = useState(false);\n  const [sending, setSending] = useState(false);\n  const recipientEditedRef = useRef(false);\n  const detailRecipientPrefillKeyRef = useRef('');\n  const jobLoadRequestRef = useRef(0);\n\n  useEffect(() => {\n    if (\n      !isCandidateModule(moduleName)\n      || recipientEditedRef.current\n      || parseEmails(mail.to).length > 0\n      || selectedIds.length === 0\n      || detailRecipientPrefillKeyRef.current === selectedIdKey\n    ) return;\n\n    let cancelled = false;\n    detailRecipientPrefillKeyRef.current = selectedIdKey;\n    Promise.all(\n      selectedIds.map((id) => getModuleDataDetail(moduleName, id).catch(() => null)),\n    ).then((responses) => {\n      if (cancelled) return;\n      const detailRecords = responses.map(unwrapRecord).filter(Boolean);\n      const detailEmails = collectRecordEmails(detailRecords, recipientFields);\n      if (!detailEmails.length) return;\n      setMail((current) => (\n        parseEmails(current.to).length > 0\n          ? current\n          : { ...current, to: [...new Set(detailEmails)].join(', ') }\n      ));\n    });\n\n    return () => { cancelled = true; };\n  }, [mail.to, moduleName, recipientFields, selectedIdKey, selectedIds]);\n\n  useEffect(() => {\n    if (!jobId) {\n      setDetailsLoaded(true);\n      return;\n    }\n\n    const requestId = ++jobLoadRequestRef.current;\n    let cancelled = false;\n\n    async function loadAndFormatJobMail() {\n      // Show the loader immediately when a job changes. Clear only the previous\n      // message body so stale content is never displayed while the new job's\n      // template is being fetched and formatted by PyOps.\n      setDetailsLoaded(false);\n      setLoadingJob(true);\n      setMail((current) => ({ ...current, contents: '' }));\n\n      try {\n        const data = await getBulkMailDetails(jobId);\n        const details = normalizeMailDetails(data);\n\n        const resolvedDocuments = await resolveBodyDocumentPlaceholders(\n          details.contents || '',\n          moduleName,\n          selectedRecords,\n        );\n        let formattedContents = resolvedDocuments.contents;\n        if (formattedContents.trim()) {\n          try {\n            formattedContents = await formatMailContentForMail(formattedContents, details.subject || initialSubject);\n          } catch (formatError) {\n            // Do not block mail composition if PyOps is temporarily unavailable.\n            // The original body from get-bulkmail-details remains usable.\n            if (!cancelled && requestId === jobLoadRequestRef.current) {\n              message.warning(formatError?.message || 'Mail content formatting failed. Showing original content.');\n            }\n          }\n        }\n\n        if (cancelled || requestId !== jobLoadRequestRef.current) return;\n\n        setMail((current) => ({\n          ...current,\n          subject: details.subject || current.subject,\n          to: details.toMail?.length ? (Array.isArray(details.toMail) ? details.toMail.join(', ') : String(details.toMail)) : current.to,\n          cc: details.ccMail?.length ? (Array.isArray(details.ccMail) ? details.ccMail.join(', ') : String(details.ccMail)) : current.cc,\n          bcc: details.bccMail?.length ? (Array.isArray(details.bccMail) ? details.bccMail.join(', ') : String(details.bccMail)) : current.bcc,\n          contents: formattedContents || resolvedDocuments.contents || current.contents,\n          attachments: resolvedDocuments.attachments,\n          showCc: current.showCc || !!details.ccMail?.length,\n          showBcc: current.showBcc || !!details.bccMail?.length,\n        }));\n      } catch (error) {\n        if (!cancelled && requestId === jobLoadRequestRef.current && requireJobId) {\n          message.error(error?.message || 'Could not load mail template for this Job ID');\n        }\n      } finally {\n        if (!cancelled && requestId === jobLoadRequestRef.current) {\n          setDetailsLoaded(true);\n          setLoadingJob(false);\n        }\n      }\n    }\n\n    loadAndFormatJobMail();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [jobId, requireJobId]);\n\n  function loadJobDetails(rawJobId = jobIdInput) {\n    const nextJobId = String(rawJobId ?? '').trim();\n    if (!OBJECT_ID_RE.test(nextJobId)) {\n      setJobId('');\n      if (nextJobId) message.warning('Enter a valid 24-character Job ID');\n      return;\n    }\n    if (nextJobId === jobId) {\n      // Allow an explicit reload even when the same job is entered again.\n      setJobId('');\n      queueMicrotask(() => setJobId(nextJobId));\n      return;\n    }\n    setJobId(nextJobId);\n  }\n\n  function handleJobSelect(nextJobId, option) {\n    if (!nextJobId) {\n      setJobId('');\n      setJobIdInput('');\n      return;\n    }\n    const selectedLabel = option?.label ?? '';\n    setJobIdInput(selectedLabel ? String(selectedLabel) : String(nextJobId ?? ''));\n    loadJobDetails(nextJobId);\n  }\n\n  function handleJobSearch(search) {\n    const term = String(search ?? '').trim();\n    setJobIdInput(term);\n    if (term.length < 3) {\n      setJobOptions([]);\n      return;\n    }\n\n    setJobSearchLoading(true);\n    searchJobs(term)\n      .then((jobs) => {\n        const options = (Array.isArray(jobs) ? jobs : [])\n          .map(normalizeJobOption)\n          .filter(Boolean);\n        setJobOptions(options);\n      })\n      .catch((error) => message.error(error?.message || 'Unable to search jobs'))\n      .finally(() => setJobSearchLoading(false));\n  }\n\n  const canSend = detailsLoaded\n    && (!requireJobId || OBJECT_ID_RE.test(jobId))\n    && (parseEmails(mail.to).length + parseEmails(mail.cc).length + parseEmails(mail.bcc).length) > 0\n    && areValidEmails(mail.to) && areValidEmails(mail.cc) && areValidEmails(mail.bcc) && mail.subject.trim() && mail.contents.trim();\n\n  async function handleSend() {\n    if (!canSend || sending) return;\n    setSending(true);\n    try {\n      await sendBulkMail({ jobId, toMail: parseEmails(mail.to), ccMail: parseEmails(mail.cc), bccMail: parseEmails(mail.bcc), subject: mail.subject, contents: mail.contents, attachments: mail.attachments ?? [] });\n      message.success('Mail sent successfully');\n      if (typeof onSend === 'function') onSend({ ...mail, message: mail.contents, selectedIds });\n      navigate(-1);\n    } catch (error) {\n      message.error(error?.message || 'Failed to send mail');\n    } finally { setSending(false); }\n  }\n\n  function handleMailChange(nextMail) {\n    if (nextMail?.to !== mail.to) recipientEditedRef.current = true;\n    setMail(nextMail);\n  }\n\n  return (\n    <Drawer open placement=\"right\" onClose={() => navigate(-1)} closable={false} rootClassName=\"mail-popup\" width={620} maskClosable={false}\n      footer={<div className=\"mail-popup__footer\"><Button onClick={() => navigate(-1)}>Cancel</Button><Button type=\"primary\" loading={sending} disabled={!canSend} onClick={handleSend}>Send</Button></div>}>\n      <Spin spinning={loadingJob} tip=\"Loading mail content...\" size=\"large\">\n        <CommonMailComposer\n          value={mail}\n          onChange={handleMailChange}\n          moduleName={moduleName}\n          defaultTemplateId={requireJobId ? '' : (popupAction.defaultTemplateId ?? state.defaultTemplateId ?? '')}\n          ready={detailsLoaded}\n          contextRecords={selectedRecords}\n          beforeFields={requireJobId ? (\n            <div className=\"mail-popup__job-row\">\n            <Text type=\"secondary\" className=\"mail-popup__field-label\">Job Title / ID</Text>\n            <Select\n              showSearch\n              allowClear\n              filterOption={false}\n              value={jobId || undefined}\n              searchValue={jobIdInput}\n              onSearch={handleJobSearch}\n              onChange={handleJobSelect}\n              onClear={() => {\n                setJobId('');\n                setJobIdInput('');\n                setJobOptions([]);\n              }}\n              placeholder=\"Minimum 3 characters\"\n              notFoundContent={jobSearchLoading || loadingJob ? <Spin size=\"small\" /> : null}\n              options={jobOptions}\n              className=\"mail-popup__job-input\"\n              />\n            </div>\n          ) : null}\n        />\n      </Spin>\n    </Drawer>\n  );\n}\n","import { useMemo, useState } from 'react';\nimport { Typography } from 'antd';\nimport '../../styles/DescriptionBlock.css';\n\nconst { Text } = Typography;\nconst PREVIEW = 2;\n\n/* ───────────────────────────────────────────────────────────\n   Section headings we recognise. Everything is folded into three\n   clean buckets so the output stays tidy: Overview · Key Skills ·\n   Education. A line is only treated as a heading when the WHOLE\n   line equals one of these — never matched inside a sentence.\n─────────────────────────────────────────────────────────── */\nconst HEADINGS = [\n  'overview',\n  'summary',\n  'role summary',\n  'job summary',\n  'role overview',\n  'job description',\n  'description',\n  'about the role',\n  'about the job',\n  'job title',\n  'role',\n  'responsibilities',\n  'roles responsibilities',\n  'roles and responsibilities',\n  'roles & responsibilities',\n  'key responsibilities',\n  'requirements',\n  'required skills',\n  'preferred skills',\n  'technical skills',\n  'key skills',\n  'skills',\n  'competencies',\n  'nice to have',\n  'good to have',\n  'qualifications',\n  'required qualifications',\n  'preferred qualifications',\n  'education',\n  'experience',\n  'benefits',\n];\nconst HEADING_SET = new Set(HEADINGS);\n\nconst EDUCATION_RE = /(education|qualification)/i;\nconst SKILLS_RE = /(skill|competenc)/i;\n\nconst escapeRegex = (text) => text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\nconst titleCase = (text) =>\n  text.replace(/\\w[^\\s/]*/g, (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\nconst dedupe = (items) => [...new Set(items)];\n\n/* ── HTML → clean text, keeping line breaks for block elements ── */\nfunction htmlToText(html) {\n  let text = String(html);\n\n  text = text\n    .replace(/<\\s*(br|\\/p|\\/div|\\/h[1-6]|\\/li|\\/tr)\\s*\\/?>/gi, '\\n')\n    .replace(/<\\s*li[^>]*>/gi, '\\n')\n    .replace(/<[^>]+>/g, ' ');\n\n  text = text\n    .replace(/&nbsp;/gi, ' ')\n    .replace(/&amp;/gi, '&')\n    .replace(/&lt;/gi, '<')\n    .replace(/&gt;/gi, '>')\n    .replace(/&#39;|&apos;/gi, \"'\")\n    .replace(/&quot;/gi, '\"');\n\n  return text\n    .replace(/[ \\t\\f\\v]+/g, ' ')\n    .replace(/\\n{2,}/g, '\\n')\n    .trim();\n}\n\n/* ── Break text into individual lines / bullet items ──\n   Only real line breaks and bullet glyphs split a line. We deliberately do\n   NOT split on \" - \" here: in real data a dash is usually a hyphen or range\n   (\"5-10 Years\", \"Engineering - Software & QA\"), not a bullet separator. */\nfunction splitLines(text) {\n  return text\n    .replace(/•/g, '\\n')\n    .split(/\\n+/)\n    .map((line) => line.trim().replace(/^[-–—•]\\s*/, '').trim())\n    .filter(Boolean);\n}\n\n// For a delimiter-less blob, dashes are the only bullet markers we have.\nfunction splitBlob(text) {\n  return splitLines(text.replace(/(?:^|\\s)[-–—]\\s+/g, '\\n'));\n}\n\n// \"Industry Type: IT Services & Consulting\" → { fieldLabel, value }\nfunction asMeta(line) {\n  const match = line.match(/^([A-Za-z][A-Za-z&/ ]{1,28}?)\\s*:\\s*(\\S.+)$/);\n  if (!match) return null;\n\n  const key = match[1].trim();\n  const value = match[2].trim();\n  // Short, label-like key + short value → it's a field, not a sentence.\n  if (key.split(/\\s+/).length > 3) return null;\n  if (value.length > 60) return null;\n\n  return { fieldKey: key.toLowerCase().replace(/\\s+/g, '-'), fieldLabel: titleCase(key), value };\n}\n\n// Whole-line heading → which bucket it switches us into, or null.\nfunction headingBucket(line) {\n  const normalized = line.toLowerCase().replace(/[\\s:.\\-–—]+$/, '').trim();\n  if (!HEADING_SET.has(normalized)) return null;\n  if (EDUCATION_RE.test(normalized)) return 'education';\n  if (SKILLS_RE.test(normalized)) return 'keySkills';\n  return 'overview';\n}\n\n/* ── Primary parser: classify each line of an already-structured text ── */\nfunction parseFromLines(lines) {\n  const meta = [];\n  const buckets = { overview: [], keySkills: [], education: [] };\n  let current = 'overview';\n\n  lines.forEach((line) => {\n    const bucket = headingBucket(line);\n    if (bucket) {\n      current = bucket;\n      return;\n    }\n    // Only the top region carries meta fields; inside Key Skills / Education a\n    // \"Key: Value\" line (e.g. \"UG: Any Graduate\") is real content, not meta.\n    if (current === 'overview') {\n      const metaItem = asMeta(line);\n      if (metaItem) {\n        meta.push(metaItem);\n        return;\n      }\n    }\n    buckets[current].push(line);\n  });\n\n  return {\n    meta,\n    overview: dedupe(buckets.overview),\n    keySkills: dedupe(buckets.keySkills),\n    education: dedupe(buckets.education),\n  };\n}\n\n/* ── Fallback parser: no line breaks, so split on inline heading keywords ── */\nfunction parseFromBlob(text) {\n  const ordered = [...HEADINGS].sort((a, b) => b.length - a.length);\n  const headingRegex = new RegExp(`\\\\b(${ordered.map(escapeRegex).join('|')})\\\\b\\\\s*:?`, 'gi');\n  const matches = [...text.matchAll(headingRegex)];\n\n  if (!matches.length) {\n    return { meta: [], overview: dedupe(splitBlob(text)), keySkills: [], education: [] };\n  }\n\n  const buckets = { overview: [], keySkills: [], education: [] };\n  const intro = text.slice(0, matches[0].index).trim();\n  if (intro) buckets.overview.push(...splitBlob(intro));\n\n  matches.forEach((match, i) => {\n    const title = match[1].trim().toLowerCase();\n    const start = match.index + match[0].length;\n    const end = i + 1 < matches.length ? matches[i + 1].index : text.length;\n    const items = splitBlob(text.slice(start, end).trim());\n    if (!items.length) return;\n\n    const bucket = EDUCATION_RE.test(title) ? 'education' : SKILLS_RE.test(title) ? 'keySkills' : 'overview';\n    buckets[bucket].push(...items);\n  });\n\n  return {\n    meta: [],\n    overview: dedupe(buckets.overview),\n    keySkills: dedupe(buckets.keySkills),\n    education: dedupe(buckets.education),\n  };\n}\n\nfunction parseDescription(raw) {\n  const text = htmlToText(raw);\n  if (!text) return { meta: [], overview: [], keySkills: [], education: [] };\n\n  const lines = splitLines(text);\n  // Enough discrete lines → trust the source's own structure.\n  return lines.length >= 4 ? parseFromLines(lines) : parseFromBlob(text);\n}\n\nfunction BulletList({ items }) {\n  return (\n    <ul className=\"jdv-ats-bullets\">\n      {items.map((item, i) => (\n        <li key={i} className=\"jdv-ats-bullet-item\">{item}</li>\n      ))}\n    </ul>\n  );\n}\n\n/*\n * Frontend-only job description renderer.\n *\n * Takes a plain/simple HTML (or text) string — different for every job — and\n * turns it into the ATS template (optional meta grid + Overview / Key Skills /\n * Education) entirely in the browser. No API, no editing, nothing hardcoded.\n */\nexport default function DescriptionBlock({ raw = '', meta = [] }) {\n  const [expanded, setExpanded] = useState(false);\n  const parsed = useMemo(() => parseDescription(raw), [raw]);\n\n  const metaRows = meta.length ? meta : parsed.meta;\n\n  const blocks = [];\n  if (parsed.overview.length) blocks.push({ key: 'overview', title: 'Overview', items: parsed.overview });\n  if (parsed.keySkills.length) blocks.push({ key: 'keySkills', title: 'Key Skills', items: parsed.keySkills, card: true, icon: '🛠️' });\n  if (parsed.education.length) blocks.push({ key: 'education', title: 'Education', items: parsed.education, card: true, icon: '🎓' });\n\n  if (!metaRows.length && !blocks.length) {\n    return <Text type=\"secondary\">No description available.</Text>;\n  }\n\n  const visible = expanded ? blocks : blocks.slice(0, PREVIEW);\n  const hiddenCount = blocks.length - PREVIEW;\n\n  return (\n    <div className=\"jdv-ats-desc\">\n      {metaRows.length > 0 && (\n        <div className=\"jdv-ats-meta-grid\">\n          {metaRows.map(({ fieldKey, fieldLabel, value }) => (\n            <div key={fieldKey ?? fieldLabel} className=\"jdv-ats-meta-row\">\n              <span className=\"jdv-ats-meta-key\">{fieldLabel}</span>\n              <span className=\"jdv-ats-meta-val\">{value}</span>\n            </div>\n          ))}\n        </div>\n      )}\n\n      <div className=\"jdv-ats-sections\">\n        {visible.map((block) =>\n          block.card ? (\n            <div key={block.key} className=\"education-block\">\n              <div className=\"education-header\">\n                <span>{block.icon}</span>\n                <span>{block.title}</span>\n              </div>\n              <ul className=\"education-list\">\n                {block.items.map((item, i) => (\n                  <li key={i} className=\"education-list-item\">{item}</li>\n                ))}\n              </ul>\n            </div>\n          ) : (\n            <div key={block.key} className=\"jdv-ats-section\">\n              <div className=\"jdv-ats-section-hd\"><span>{block.title}</span></div>\n              <BulletList items={block.items} />\n            </div>\n          ),\n        )}\n      </div>\n\n      {hiddenCount > 0 && (\n        <span className=\"jdv-desc-toggle\" onClick={() => setExpanded((prev) => !prev)}>\n          {expanded ? 'Show less' : `Show more (${hiddenCount} more section${hiddenCount > 1 ? 's' : ''})`}\n        </span>\n      )}\n    </div>\n  );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { Avatar, Button, Modal, Spin, Tag, Typography } from 'antd';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { getFormGroups } from '../../services/addFormApi';\nimport { getModuleDocuments } from '../../services/documentApi';\nimport DescriptionBlock from '../detail/DescriptionBlock';\nimport DocumentViewer from '../DocumentViewer';\nimport { extractDocuments } from '../detail/renderConfig';\n\nconst { Text } = Typography;\n\nfunction getInitials(name) {\n  if (!name) return '?';\n  return name.trim().split(/\\s+/).slice(0, 2).map((w) => w[0].toUpperCase()).join('');\n}\n\nfunction getRecordName(record) {\n  if (!record) return '';\n  if (record.name) return record.name;\n  if (record.fullName) return record.fullName;\n  if (record.firstName || record.lastName) return [record.firstName, record.lastName].filter(Boolean).join(' ');\n  return record.candidateName ?? record.clientName ?? record.jobTitle ?? '';\n}\n\nfunction getRecordEmail(record) {\n  if (!record) return '';\n  return record.email ?? record.emailId ?? record.emailAddress ?? '';\n}\n\nfunction getRecordStatus(record) {\n  if (!record) return '';\n  if (record.status) return record.status;\n  if (record.stage) return record.stage;\n  if (typeof record.isActive === 'boolean') return record.isActive ? 'Active' : 'Inactive';\n  return '';\n}\n\nfunction formatValue(value) {\n  if (value === null || value === undefined || value === '') return '-';\n  if (typeof value === 'string') return value;\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n  if (Array.isArray(value)) return value.join(', ');\n  if (typeof value === 'object') return value.label ?? value.name ?? Object.values(value).join(' ');\n  return String(value);\n}\n\nconst DESCRIPTION_KEYS = ['jobDescription', 'description', 'rawDescription', 'jobDescriptionText'];\n\nfunction isJobModule(moduleName) {\n  return String(moduleName ?? '').toLowerCase() === 'job';\n}\n\nfunction isDescriptionField(field) {\n  const matchesKey = DESCRIPTION_KEYS.includes(field.field);\n  const matchesLabel = /description/i.test(field.label ?? '');\n  return matchesKey || matchesLabel;\n}\n\nfunction ProfileCard({ record }) {\n  const name = getRecordName(record);\n  const email = getRecordEmail(record);\n  const status = getRecordStatus(record);\n\n  if (!name && !email) return null;\n\n  return (\n    <div className=\"preview-profile-card\">\n      <div className=\"preview-profile-card__info\">\n        <Avatar className=\"preview-profile-card__avatar\">{getInitials(name)}</Avatar>\n        <div className=\"preview-profile-card__text\">\n          {name && <span className=\"preview-profile-card__name\">{name}</span>}\n          {email && <span className=\"preview-profile-card__email\">{email}</span>}\n        </div>\n      </div>\n      {status && <Tag className=\"preview-profile-card__status\">{status}</Tag>}\n    </div>\n  );\n}\n\nfunction FieldsDisplay({ fields, moduleName, centralDocuments = [] }) {\n  const [previewDocuments, setPreviewDocuments] = useState([]);\n  const [previewIndex, setPreviewIndex] = useState(0);\n  const [documentViewerOpen, setDocumentViewerOpen] = useState(false);\n\n  if (!fields?.length) return null;\n\n  function isDocumentField(field) {\n    const type = String(field?.type ?? '').trim().toLowerCase();\n    const identity = `${field?.field ?? ''} ${field?.label ?? ''}`;\n    return ['file', 'document', 'upload'].includes(type)\n      || /resume|cv|document|attachment/i.test(identity);\n  }\n\n  function openDocumentPreview(documents, index) {\n    setPreviewDocuments(documents);\n    setPreviewIndex(index);\n    setDocumentViewerOpen(true);\n  }\n\n  return (\n    <>\n    \n    <div className=\"preview-field-grid\">\n      {fields.map((field) => {\n        const raw = field.value;\n        const isArray = Array.isArray(raw) && raw.length > 0;\n        const showFormattedDescription = isJobModule(moduleName)\n          && isDescriptionField(field)\n          && typeof raw === 'string'\n          && raw.trim();\n        const centralForField = isDocumentField(field)\n          ? centralDocuments\n            .filter((document) => {\n              const documentField = String(\n                document?.fieldName\n                ?? document?.field\n                ?? document?.formField\n                ?? document?.key\n                ?? '',\n              ).trim().toLowerCase();\n              const fieldName = String(field?.field ?? '').trim().toLowerCase();\n              if (documentField && fieldName && documentField === fieldName) return true;\n\n              // Older resume records may not have fieldName populated. Keep the\n              // same resume/CV fallback used by DetailedView's document action.\n              const identity = `${field?.field ?? ''} ${field?.label ?? ''}`;\n              if (!/resume|cv/i.test(identity)) return false;\n              return /resume|cv/i.test(`${documentField} ${document?.fileName ?? ''} ${document?.name ?? ''}`);\n            })\n            .map((document) => ({\n              name: document?.fileName\n                || document?.name\n                || document?.uploadedFileName\n                || document?.originalName\n                || field?.label\n                || 'Document',\n              // IMPORTANT: use the document registry's presigned URL exactly as\n              // DetailedView does. Do not rebuild the private S3 object path.\n              url: document?.fileUrl\n                || document?.downloadUrl\n                || document?.signedUrl\n                || document?.url\n                || '',\n              type: document?.mimeType || document?.contentType || document?.type,\n            }))\n            .filter((document) => document.url)\n          : [];\n\n        const documents = isDocumentField(field)\n          ? (centralForField.length\n            ? centralForField\n            : extractDocuments(raw).filter((document) => document.url))\n          : [];\n\n        if (documents.length) {\n          return (\n            <div\n              key={field.field ?? field.label}\n              className=\"preview-field-card preview-field-card--documents\"\n            >\n              <span className=\"preview-field-card__label\">{field.label}</span>\n              <div className=\"preview-document-list\">\n                {documents.map((document, index) => (\n                  <button\n                    type=\"button\"\n                    key={`${document.url}-${index}`}\n                    className=\"preview-document-link\"\n                    onClick={() => openDocumentPreview(documents, index)}\n                    title={`Preview ${document.name || 'document'}`}\n                  >\n                    <span className=\"preview-document-link__icon\" aria-hidden=\"true\">▣</span>\n                    <span className=\"preview-document-link__name\">\n                      {document.name || `Document ${index + 1}`}\n                    </span>\n                    <span className=\"preview-document-link__action\">Preview</span>\n                  </button>\n                ))}\n              </div>\n            </div>\n          );\n        }\n\n        if (isArray) {\n          return raw.map((item, idx) => (\n            <div key={`${field.field ?? field.label}-${idx}`} className=\"preview-field-card\">\n              <span className=\"preview-field-card__label\">\n                {field.label}{raw.length > 1 ? ` (${idx + 1})` : ''}\n              </span>\n              <span className=\"preview-field-card__value\">{formatValue(item)}</span>\n            </div>\n          ));\n        }\n\n        if (showFormattedDescription) {\n          return (\n            <div key={field.field ?? field.label} className=\"preview-field-card preview-field-card--description\">\n              <span className=\"preview-field-card__label\">{field.label}</span>\n              <div className=\"preview-field-card__description\">\n                <DescriptionBlock raw={raw} />\n              </div>\n            </div>\n          );\n        }\n\n        return (\n          <div key={field.field ?? field.label} className=\"preview-field-card\">\n            <span className=\"preview-field-card__label\">{field.label}</span>\n            <span className=\"preview-field-card__value\">{formatValue(raw)}</span>\n          </div>\n        );\n      })}\n    </div>\n      <DocumentViewer\n        documents={previewDocuments}\n        open={documentViewerOpen}\n        onClose={() => setDocumentViewerOpen(false)}\n        initialIndex={previewIndex}\n      />\n    </>\n  );\n}\n\nexport default function PreviewPopup() {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const { moduleName = '', record = null } = location.state ?? {};\n\n  const id = record?.id ?? record?._id;\n  const [formGroups, setFormGroups] = useState([]);\n  const [loading, setLoading] = useState(Boolean(moduleName && id));\n  const [error, setError] = useState(null);\n  const [centralDocuments, setCentralDocuments] = useState([]);\n  const [activeSectionIndex, setActiveSectionIndex] = useState(0);\n  const bodyRef = useRef(null);\n  const stepperWrapRef = useRef(null);\n  const stepItemRefs = useRef([]);\n  const sectionRefs = useRef([]);\n\n  useEffect(() => {\n    if (!moduleName || !id) return;\n\n    let cancelled = false;\n\n    Promise.all([\n      getFormGroups({ module: moduleName, id }),\n      // Match DetailedViewV1: documents are resolved from the central documents\n      // registry because its fileUrl is presigned for private S3 objects.\n      getModuleDocuments(moduleName, id).catch(() => ({ data: [] })),\n    ])\n      .then(([data, documentsResponse]) => {\n        if (!cancelled) {\n          setFormGroups(Array.isArray(data) ? data : []);\n          setCentralDocuments(\n            Array.isArray(documentsResponse)\n              ? documentsResponse\n              : (documentsResponse?.data ?? []),\n          );\n          setLoading(false);\n        }\n      })\n      .catch((err) => {\n        if (!cancelled) {\n          setError(err.message || 'Failed to load preview');\n          setCentralDocuments([]);\n          setLoading(false);\n        }\n      });\n\n    return () => { cancelled = true; };\n  }, [moduleName, id]);\n\n  function handleClose() { navigate(-1); }\n\n  function getGroupLabel(group, index) {\n    return group?.label ?? group?.name ?? `Section ${index + 1}`;\n  }\n\n  function scrollToSection(index) {\n    const body = bodyRef.current;\n    const section = sectionRefs.current[index];\n    if (!body || !section) return;\n\n    const bodyRect = body.getBoundingClientRect();\n    const sectionRect = section.getBoundingClientRect();\n    const stepper = body.querySelector('.preview-stepper-wrap');\n    const stickyOffset = (stepper?.offsetHeight ?? 0) + 12;\n    const targetTop = body.scrollTop + sectionRect.top - bodyRect.top - stickyOffset;\n\n    setActiveSectionIndex(index);\n    body.scrollTo({ top: Math.max(0, targetTop), behavior: 'smooth' });\n  }\n\n  function handleBodyScroll() {\n    const body = bodyRef.current;\n    if (!body || !sectionRefs.current.length) return;\n\n    const bodyTop = body.getBoundingClientRect().top;\n    const stepper = body.querySelector('.preview-stepper-wrap');\n    const threshold = bodyTop + (stepper?.offsetHeight ?? 0) + 24;\n    let nextActive = 0;\n\n    sectionRefs.current.forEach((section, index) => {\n      if (section && section.getBoundingClientRect().top <= threshold) {\n        nextActive = index;\n      }\n    });\n\n    setActiveSectionIndex((current) => (current === nextActive ? current : nextActive));\n  }\n\n\n  // Keep the active section step visible without exposing a horizontal scrollbar.\n  // This also runs when the active section changes from normal vertical scrolling.\n  useEffect(() => {\n    const wrap = stepperWrapRef.current;\n    const item = stepItemRefs.current[activeSectionIndex];\n    if (!wrap || !item) return;\n\n    const targetLeft = item.offsetLeft - ((wrap.clientWidth - item.offsetWidth) / 2);\n    const maxLeft = Math.max(0, wrap.scrollWidth - wrap.clientWidth);\n    wrap.scrollTo({\n      left: Math.min(Math.max(0, targetLeft), maxLeft),\n      behavior: 'smooth',\n    });\n  }, [activeSectionIndex, formGroups.length]);\n\n  function renderStepper() {\n    if (!formGroups.length) return null;\n\n    return (\n      <div ref={stepperWrapRef} className=\"preview-stepper-wrap\" aria-label=\"Preview sections\">\n        <div className=\"preview-stepper\">\n          {formGroups.map((group, index) => (\n            <div className=\"preview-stepper__segment\" key={group.name ?? group.id ?? index}>\n              <button\n                type=\"button\"\n                className=\"preview-stepper__item\"\n                ref={(node) => { stepItemRefs.current[index] = node; }}\n                onClick={() => scrollToSection(index)}\n                aria-current={activeSectionIndex === index ? 'step' : undefined}\n                title={`Go to ${getGroupLabel(group, index)}`}\n              >\n                <span\n                  className={[\n                    'preview-stepper__circle',\n                    index < activeSectionIndex ? 'preview-stepper__circle--done' : '',\n                    index === activeSectionIndex ? 'preview-stepper__circle--active' : '',\n                  ].filter(Boolean).join(' ')}\n                >\n                  {index + 1}\n                </span>\n                <span\n                  className={[\n                    'preview-stepper__label',\n                    index === activeSectionIndex ? 'preview-stepper__label--active' : '',\n                  ].filter(Boolean).join(' ')}\n                >\n                  {getGroupLabel(group, index)}\n                </span>\n              </button>\n              {index < formGroups.length - 1 && (\n                <span\n                  className={[\n                    'preview-stepper__line',\n                    index < activeSectionIndex ? 'preview-stepper__line--done' : '',\n                  ].filter(Boolean).join(' ')}\n                  aria-hidden=\"true\"\n                />\n              )}\n            </div>\n          ))}\n        </div>\n      </div>\n    );\n  }\n\n  const modalTitle = (\n    <div className=\"preview-modal-header\">\n      <span className=\"preview-modal-module\">{moduleName.toUpperCase()}</span>\n      <span className=\"preview-modal-title\">{moduleName ? ' Details' : 'Preview'}</span>\n    </div>\n  );\n\n  const footer = (\n    <div className=\"wizard-footer preview-scroll-footer\">\n      <div className=\"wizard-footer-nav\">\n        <Button onClick={handleClose}>Close</Button>\n      </div>\n    </div>\n  );\n\n  function renderBody() {\n    if (!moduleName || !id) {\n      return <div className=\"job-preview-content job-preview-status\">Preview id is missing.</div>;\n    }\n    if (loading) {\n      return <div className=\"job-preview-content job-preview-status\"><Spin size=\"small\" /></div>;\n    }\n    if (error) {\n      return <div className=\"job-preview-content job-preview-status job-preview-error\">{error}</div>;\n    }\n    if (!formGroups.length) {\n      return <div className=\"job-preview-content job-preview-status\">No form groups found.</div>;\n    }\n\n    return (\n      <div className=\"preview-section-list\">\n        {formGroups.map((group, index) => (\n          <section\n            key={group.name ?? group.id ?? index}\n            ref={(node) => { sectionRefs.current[index] = node; }}\n            className=\"preview-section-card\"\n            data-section-index={index}\n          >\n            <div className=\"preview-section-card__header\">\n              <span className=\"preview-section-card__number\">{index + 1}</span>\n              <span className=\"preview-section-card__title\">\n                {getGroupLabel(group, index)}\n              </span>\n            </div>\n            <div className=\"preview-section-card__body\">\n              {group.fields?.length > 0 ? (\n                <FieldsDisplay\n                  fields={group.fields}\n                  moduleName={moduleName}\n                  centralDocuments={centralDocuments}\n                />\n              ) : (\n                <Text type=\"secondary\">No fields in this group.</Text>\n              )}\n            </div>\n          </section>\n        ))}\n      </div>\n    );\n  }\n\n  return (\n    <Modal\n      centered\n      className=\"wizard-modal preview-modal preview-scroll-modal\"\n      footer={footer}\n      open\n      title={modalTitle}\n      width=\"min(900px, calc(100vw - 32px))\"\n      onCancel={handleClose}\n      maskClosable={false}\n    >\n      <div\n        ref={bodyRef}\n        className=\"wizard-body preview-scroll-body\"\n        onScroll={handleBodyScroll}\n      >\n        {!loading && !error && formGroups.length > 0 && renderStepper()}\n        {record && <ProfileCard record={record} />}\n        {renderBody()}\n      </div>\n    </Modal>\n  );\n}\n","import { useState } from 'react';\nimport { Button, Col, Form, Input, InputNumber, Modal, Row, Select, Steps, Typography } from 'antd';\nimport { CheckCircleOutlined } from '@ant-design/icons';\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nconst { Text } = Typography;\nconst { TextArea } = Input;\n\nconst DEFAULT_STEPS = [\n  {\n    key: 'basic',\n    title: 'Basic Info',\n    description: 'General details',\n    fields: [\n      { name: 'firstName', label: 'First Name', type: 'input', required: true, placeholder: 'Enter first name', span: 12 },\n      { name: 'lastName', label: 'Last Name', type: 'input', required: true, placeholder: 'Enter last name', span: 12 },\n      { name: 'email', label: 'Email Address', type: 'input', required: true, placeholder: 'Enter email address', rules: [{ type: 'email', message: 'Please enter a valid email' }] },\n      { name: 'phone', label: 'Phone', type: 'input', placeholder: 'Enter phone number' },\n    ],\n  },\n  {\n    key: 'details',\n    title: 'Details',\n    description: 'Additional info',\n    fields: [\n      {\n        name: 'role', label: 'Role', type: 'select', required: true, placeholder: 'Select a role', span: 12,\n        options: [\n          { label: 'Developer', value: 'developer' },\n          { label: 'Designer', value: 'designer' },\n          { label: 'Manager', value: 'manager' },\n          { label: 'Analyst', value: 'analyst' },\n        ],\n      },\n      {\n        name: 'department', label: 'Department', type: 'select', placeholder: 'Select department', span: 12,\n        options: [\n          { label: 'Engineering', value: 'engineering' },\n          { label: 'Product', value: 'product' },\n          { label: 'Operations', value: 'operations' },\n          { label: 'Finance', value: 'finance' },\n        ],\n      },\n      { name: 'notes', label: 'Notes', type: 'textarea', placeholder: 'Any additional notes...' },\n    ],\n  },\n  {\n    key: 'confirm',\n    title: 'Confirm',\n    description: 'Review & submit',\n    isReview: true,\n  },\n];\n\nfunction renderFieldControl(field) {\n  switch (field.type) {\n    case 'select':\n      return <Select placeholder={field.placeholder} options={field.options} style={{ width: '100%' }} />;\n    case 'textarea':\n      return <TextArea rows={3} placeholder={field.placeholder} />;\n    case 'number':\n      return <InputNumber placeholder={field.placeholder} style={{ width: '100%' }} />;\n    default:\n      return <Input type={field.inputType || 'text'} placeholder={field.placeholder} />;\n  }\n}\n\nfunction ReviewStep({ steps, form }) {\n  const values = form.getFieldsValue();\n\n  const dataSteps = steps.filter((s) => !s.isReview);\n\n  const hasAnyValue = dataSteps.some((step) =>\n    (step.fields || []).some((field) => values[field.name] !== undefined && values[field.name] !== ''),\n  );\n\n  if (!hasAnyValue) {\n    return (\n      <div className=\"wizard-review-empty\">\n        <Text type=\"secondary\">No data entered yet.</Text>\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"wizard-review-content\">\n      {dataSteps.map((step) => (\n        <div key={step.key} className=\"wizard-review-section\">\n          <Text className=\"wizard-review-section-title\">{step.title}</Text>\n          <div className=\"wizard-review-grid\">\n            {(step.fields || []).map((field) => {\n              const raw = values[field.name];\n              const displayVal = raw === undefined || raw === '' || raw === null ? '—' : String(raw);\n              return (\n                <div key={field.name} className=\"wizard-review-row\">\n                  <span className=\"wizard-review-label\">{field.label}</span>\n                  <span className=\"wizard-review-separator\">:</span>\n                  <span className=\"wizard-review-value\">{displayVal}</span>\n                </div>\n              );\n            })}\n          </div>\n        </div>\n      ))}\n      <div className=\"wizard-review-confirm-note\">\n        <CheckCircleOutlined className=\"wizard-review-confirm-icon\" />\n        <Text type=\"secondary\">Please review the information above before submitting.</Text>\n      </div>\n    </div>\n  );\n}\n\nexport default function WizardPopup() {\n  const [form] = Form.useForm();\n  const navigate = useNavigate();\n  const location = useLocation();\n  const {\n    title = 'Wizard',\n    moduleName = '',\n    steps = DEFAULT_STEPS,\n    onSubmit,\n  } = location.state ?? {};\n\n  const [current, setCurrent] = useState(0);\n\n  const currentStep = steps[current];\n  const isLastStep = current === steps.length - 1;\n  const isFirstStep = current === 0;\n\n  function handleClose() {\n    navigate(-1);\n  }\n\n  function handleNext() {\n    const stepFieldNames = (currentStep.fields || []).map((f) => f.name);\n    form.validateFields(stepFieldNames.length > 0 ? stepFieldNames : undefined).then(() => {\n      setCurrent((prev) => prev + 1);\n    });\n  }\n\n  function handleBack() {\n    setCurrent((prev) => prev - 1);\n  }\n\n  function handleSubmit() {\n    const allValues = form.getFieldsValue();\n    if (typeof onSubmit === 'function') {\n      onSubmit(allValues);\n    }\n    navigate(-1);\n  }\n\n  const stepsItems = steps.map((step, index) => ({\n    title: step.title,\n    description: step.description,\n    status: index < current ? 'finish' : index === current ? 'process' : 'wait',\n  }));\n\n  const modalTitle = moduleName ? `${title} — ${moduleName}` : title;\n\n  const footer = (\n    <div className=\"wizard-footer\">\n      <Button onClick={handleClose}>Cancel</Button>\n      <div className=\"wizard-footer-nav\">\n        {!isFirstStep && <Button onClick={handleBack}>Back</Button>}\n        {isLastStep ? (\n          <Button type=\"primary\" onClick={handleSubmit}>\n            Submit\n          </Button>\n        ) : (\n          <Button type=\"primary\" onClick={handleNext}>\n            Next\n          </Button>\n        )}\n      </div>\n    </div>\n  );\n\n  return (\n    <Modal\n      open\n      title={modalTitle}\n      footer={footer}\n      onCancel={handleClose}\n      width=\"min(680px, calc(100vw - 32px))\"\n      centered\n      className=\"wizard-modal\"\n    >\n      <div className=\"wizard-steps-container\">\n        <Steps current={current} items={stepsItems} size=\"small\" className=\"wizard-steps\" />\n      </div>\n\n      <div className=\"wizard-body\">\n        <Form form={form} layout=\"vertical\">\n          {steps\n            .filter((s) => !s.isReview)\n            .map((step, index) => (\n              <div\n                key={step.key}\n                style={{ display: index === current ? 'block' : 'none' }}\n              >\n                <Row gutter={16}>\n                  {(step.fields || []).map((field) => (\n                    <Col span={field.span || 24} key={field.name}>\n                      <Form.Item\n                        name={field.name}\n                        label={field.label}\n                        rules={[\n                          ...(field.required ? [{ required: true, message: `${field.label} is required` }] : []),\n                          ...(field.rules || []),\n                        ]}\n                      >\n                        {renderFieldControl(field)}\n                      </Form.Item>\n                    </Col>\n                  ))}\n                </Row>\n              </div>\n            ))}\n\n          {currentStep.isReview && <ReviewStep steps={steps} form={form} />}\n        </Form>\n      </div>\n    </Modal>\n  );\n}\n","import { DeleteOutlined, AppstoreOutlined } from '@ant-design/icons';\n\n/**\n * Renders the popup modal title with a section-style icon box + bold label,\n * matching the AddFormV1.css card header design.\n *\n * @param {Object} props\n * @param {string} [props.titleText]\n * @param {string} [props.titleIcon]  - 'delete' for danger style; omit for default\n */\nexport default function PopupHeader({ titleText, titleIcon }) {\n  const isDelete = titleIcon === 'delete';\n\n  return (\n    <span className=\"dynamic-popup__header\">\n      <span className={`dynamic-popup__header-icon-box${isDelete ? ' dynamic-popup__header-icon-box--danger' : ''}`}>\n        {isDelete ? <DeleteOutlined /> : <AppstoreOutlined />}\n      </span>\n      <span className=\"dynamic-popup__header-label\">{titleText}</span>\n    </span>\n  );\n}\n","import AppTypography from '../../typography/Typography';\n\n/**\n * Renders the informational body content of a DynamicPopup modal.\n * Form fields are rendered separately by PopupFields.\n *\n * @param {Object} props\n * @param {string} [props.note]\n * @param {string} [props.description]\n * @param {boolean} [props.showSelectedCount]\n * @param {number} [props.count]\n * @param {string} [props.itemLabel]\n * @param {string|null} [props.bodyText]\n * @param {string|null} [props.deleteError]\n */\nexport default function PopupBody({\n  note,\n  description,\n  showSelectedCount,\n  count,\n  itemLabel,\n  bodyText,\n  deleteError,\n}) {\n  return (\n    <>\n      {note && (\n        <AppTypography variant=\"body\" color=\"secondary\" className=\"dynamic-popup__note\">\n          {note}\n        </AppTypography>\n      )}\n      {description && (\n        <AppTypography variant=\"body\" className=\"dynamic-popup__description\">\n          {description}\n        </AppTypography>\n      )}\n      {showSelectedCount && count > 0 && (\n        <AppTypography variant=\"body\" className=\"dynamic-popup__selected-count\">\n          Changing status for <strong>{count}</strong> selected {itemLabel}.\n        </AppTypography>\n      )}\n      {bodyText && (\n        <AppTypography variant=\"body\">\n          {bodyText}\n        </AppTypography>\n      )}\n      {deleteError && (\n        <AppTypography variant=\"caption\" color=\"danger\" className=\"dynamic-popup__error\">\n          {deleteError}\n        </AppTypography>\n      )}\n    </>\n  );\n}\n","import AppTypography from '../../typography/Typography';\n\n/**\n * Renders an informational footer note inside the modal body (above the action buttons).\n *\n * @param {Object} props\n * @param {string} [props.footerNote]\n */\nexport default function PopupFooter({ footerNote }) {\n  if (!footerNote) return null;\n  return (\n    <AppTypography variant=\"caption\" color=\"secondary\" className=\"dynamic-popup__footer-note\">\n      {footerNote}\n    </AppTypography>\n  );\n}\n","/**\n * Replaces `{key}` placeholders in a template string with values from an item object.\n * @param {string} template - Template string with `{key}` placeholders.\n * @param {Object} item - Data object used to fill placeholders.\n * @returns {string}\n */\nexport function fillTemplate(template, item) {\n  return template.replace(/\\{(\\w+)\\}/g, (_, key) => item?.[key] ?? '').trim();\n}\n\n/**\n * Cleans up a filled label template whose placeholders resolved to empty\n * strings. `'{applicantRefrenceId} - {firstName} {lastName} - ({lastdate})'`\n * against a candidate with no reference id used to render as\n * `'- Manik Bacha - ()'`; this collapses the orphaned separators and empty\n * brackets so it reads `'Manik Bacha'`.\n * @param {string} label\n * @returns {string}\n */\nexport function tidyTemplateLabel(label) {\n  return String(label)\n    .replace(/\\(\\s*\\)/g, '')          // empty ( ) left by a blank placeholder\n    .replace(/\\s+/g, ' ')             // collapse the gaps those left behind\n    .replace(/(^|\\s)([-–—·|])(?=\\s*\\2)/g, '') // duplicated separators\n    .replace(/^[\\s\\-–—·|]+/, '')      // leading separator\n    .replace(/[\\s\\-–—·|]+$/, '')      // trailing separator\n    .trim();\n}\n\n/**\n * Formats a date as a relative label: Today, Yesterday, or \"N days ago\".\n * @param {string|Date} value\n * @returns {string}\n */\n/**\n * isMeaningfulDate — is this a date a human actually entered, or a placeholder?\n *\n * A record that was never updated does not arrive as null: Go marshals its zero\n * time as \"0001-01-01T00:00:00Z\", which parses perfectly well and is then\n * rendered as \"2025 years ago\". That is not a stale record, it is NO record —\n * and a relative label is the wrong shape for it entirely, because \"N ago\" says\n * \"this happened, a while back\" when nothing happened at all.\n *\n * So anything before the Unix epoch (and anything in the future, which is\n * equally a data fault) is rejected here, and callers show a real date or an\n * explicit \"not set\" instead of arithmetic on a placeholder.\n */\nexport function isMeaningfulDate(value) {\n  if (!value) return false;\n  const date = new Date(value);\n  const time = date.getTime();\n  if (Number.isNaN(time)) return false;\n  // Epoch guards both the Go zero time and a literal 0/\"\" that parsed to 1970.\n  if (time <= 0) return false;\n  // Tomorrow onwards: a \"created\" date in the future is corrupt, not recent.\n  return time <= Date.now() + 86400000;\n}\n\n/**\n * relativeDateLabel — how long ago, in the largest unit that stays honest.\n *\n * Days up to a month, then months, then years. Past ~30 days the exact day\n * count stops being information anyone acts on (\"47 days ago\" and \"52 days\n * ago\" mean the same thing to a recruiter), while \"2 months ago\" is read at a\n * glance. Returns '' for a placeholder date so the caller can decide what to\n * show instead — never a fabricated age.\n */\nexport function relativeDateLabel(value) {\n  if (!isMeaningfulDate(value)) return '';\n  const date = new Date(value);\n\n  const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());\n  const now = new Date();\n  const diffDays = Math.round((startOfDay(now) - startOfDay(date)) / 86400000);\n\n  if (diffDays <= 0) return 'Today';\n  if (diffDays === 1) return 'Yesterday';\n  if (diffDays <= 30) return `${diffDays} days ago`;\n\n  // Calendar months/years, not day arithmetic: \"1 month ago\" should mean the\n  // same date last month regardless of how many days that month had.\n  let months = (now.getFullYear() - date.getFullYear()) * 12 + (now.getMonth() - date.getMonth());\n  if (now.getDate() < date.getDate()) months -= 1;\n  months = Math.max(1, months);\n\n  if (months < 12) return `${months} month${months === 1 ? '' : 's'} ago`;\n\n  const years = Math.floor(months / 12);\n  return `${years} year${years === 1 ? '' : 's'} ago`;\n}\n\n/**\n * Finds the most recent submission date on an item, checking common top-level\n * fields as well as `submissionHistory` entries.\n * @param {Object} item\n * @returns {string|null}\n */\nfunction getLastSubmittedDate(item) {\n  const history = Array.isArray(item?.submissionHistory) ? item.submissionHistory : [];\n  const dates = [\n    item?.lastSubmittedAt,\n    item?.submittedAt,\n    item?.updatedAt,\n    ...history.map((entry) => entry?.submittedAt || entry?.updatedAt),\n  ].filter(Boolean);\n\n  if (!dates.length) return null;\n  return dates.reduce((latest, curr) => (new Date(curr) > new Date(latest) ? curr : latest));\n}\n\n/**\n * The date an item was ACTUALLY submitted, for the already-submitted tick and\n * its tooltip. Deliberately stricter than getLastSubmittedDate above, which\n * falls back to `updatedAt` — a candidate that was merely edited yesterday and\n * never submitted must not report a submission date. Only fields that mean\n * \"a submission happened\" are consulted.\n * @param {Object} item\n * @returns {string|number|null}\n */\nexport function getSubmittedAt(item) {\n  const history = Array.isArray(item?.submissionHistory) ? item.submissionHistory : [];\n  const dates = [\n    item?.lastSubmittedAt,\n    item?.submittedAt,\n    ...history.map((entry) => entry?.submittedAt),\n  ].filter(Boolean);\n\n  if (!dates.length) return null;\n  return dates.reduce((latest, curr) => (new Date(curr) > new Date(latest) ? curr : latest));\n}\n\n/**\n * Normalizes a raw API item into a `{ label, value, _raw }` option object.\n * Supports plain strings, pre-normalized objects, and raw API response shapes.\n * @param {*} item\n * @param {Object} [field] - Field config with optional `labelKey`, `valueKey`, `labelTemplate`.\n * @returns {{ label: string, value: string, _raw?: * }}\n */\nexport function normalizeOption(item, field) {\n  if (typeof item === 'string') return { label: item, value: item };\n  if (item?.label !== undefined && item?.value !== undefined && !field?.labelTemplate && !field?.valueKey) return item;\n\n  const { labelKey, valueKey, labelTemplate } = field ?? {};\n\n  const templateItem =\n    labelTemplate?.includes('{lastdate}')\n      ? { ...item, lastdate: relativeDateLabel(getLastSubmittedDate(item)) }\n      : item;\n\n  const label =\n    (labelTemplate ? tidyTemplateLabel(fillTemplate(labelTemplate, templateItem)) : null) ||\n    (labelKey ? item?.[labelKey] : null) ||\n    item?.name ||\n    item?.fullName ||\n    item?.candidateName ||\n    item?.title ||\n    item?.displayName ||\n    item?.text ||\n    item?.applicantReferenceId ||\n    item?.applicantRefrenceId ||\n    String(Object.values(item || {})[0] ?? '');\n\n  const value =\n    (valueKey ? item?.[valueKey] : null) ??\n    item?.id ??\n    item?._id ??\n    item?.applicantReferenceId ??\n    item?.applicantRefrenceId ??\n    String(Object.values(item || {})[0] ?? '');\n\n  // A fetcher (or the API itself — both /quicksubmit/list and /joblist carry a\n  // `disable` + `message` pair) can mark a row unselectable. `disabled` has to\n  // survive normalization for Ant Design to honour it per option, and\n  // `optionNote` explains WHY: it is appended to the label (which a\n  // labelTemplate would otherwise have already finalised) and used as the\n  // hover title. Deliberately not named `title` — that key is a label fallback\n  // above.\n  const disabled = item?.disabled === true || item?.disable === true;\n  const note = String(item?.optionNote ?? '').trim();\n  const option = {\n    label: note ? `${String(label)} — ${note}` : String(label),\n    value: String(value),\n    _raw: item,\n  };\n  if (disabled) option.disabled = true;\n  if (note) option.title = note;\n\n  // Lift the already-submitted marking to the TOP of the option. Options built\n  // by hand (the job branch of quick-submit/api.js) already carry these keys;\n  // hoisting them here means the dropdown renderer reads one shape for both,\n  // instead of knowing which branch produced the row.\n  //\n  // Keyed on isSubmitted/alreadySubmitted ONLY — deliberately NOT on\n  // isFromSubmission. Those mean different things: isSubmitted is \"already\n  // submitted to THIS job\" (blocks), while isFromSubmission is \"has a\n  // submission to ANY job\" (a prefill source, and the common case for a working\n  // candidate). Treating isFromSubmission as a block here disabled every\n  // candidate who had ever been submitted anywhere.\n  if (item?.isSubmitted === true || item?.alreadySubmitted === true) {\n    option.alreadySubmitted = true;\n    option.existingSubmissionId = String(\n      item?.existingSubmissionId ?? item?.jobSubmissionId ?? item?.submissionId ?? '',\n    );\n    // `submittedAt` is THIS job's submission date; getSubmittedAt is the\n    // fallback for callers that only send a history. Preferring the explicit\n    // field matters now that a row can also carry `lastSubmittedAt` from a\n    // NEWER submission to a different job — the badge tooltip must report when\n    // they were submitted to THIS job, not their latest activity anywhere.\n    const submittedAt = item?.submittedAt || getSubmittedAt(item);\n    if (submittedAt) option.submittedAt = submittedAt;\n  }\n\n  // The prior-submission prefill source, carried through untouched so the\n  // popup's submit() can hand it to AddFormV1's prefillFromUrl.\n  if (item?.isFromSubmission === true && item?.submissionId) {\n    option.isFromSubmission = true;\n    option.priorSubmissionId = String(item.submissionId);\n    // When that prior submission happened, for the dropdown's history tick\n    // tooltip. Deliberately NOT `submittedAt` — that one is pinned to THIS\n    // job above, and on a row that is only submitted elsewhere it is absent.\n    const priorAt = item?.lastSubmittedAt || getSubmittedAt(item);\n    if (priorAt) option.priorSubmittedAt = priorAt;\n  }\n  return option;\n}\n\n/**\n * Resolves static options for a field from context or field defaults.\n * @param {Object} field\n * @param {Object} context\n * @returns {{ label: string, value: string }[]}\n */\nexport function resolveOptions(field, context) {\n  const raw = context?.[field.optionsKey] ?? field.defaultOptions ?? [];\n  return raw.map((opt) => normalizeOption(opt, field));\n}\n\n/**\n * Applies default values to a context object so consumers can rely on these keys always being present.\n * @param {Object} [context={}]\n * @returns {{ selectedIds: string[], selectedRecords: Object[], moduleName: string, removedIds: string[] }}\n */\nexport function getDefaultContext(context = {}) {\n  return {\n    selectedIds: [],\n    selectedRecords: [],\n    moduleName: '',\n    removedIds: [],\n    ...context,\n  };\n}\n","import { Fragment } from 'react';\nimport { Tooltip } from 'antd';\nimport { CheckCircleFilled } from '@ant-design/icons';\nimport dayjs from 'dayjs';\nimport { fillTemplate, isMeaningfulDate, relativeDateLabel, tidyTemplateLabel } from './utils/popupUtils';\n\n// ── Rich dropdown rows ───────────────────────────────────────────────────────\n// A search-select can render each dropdown row as a multi-line card instead of\n// a single label string, driven entirely by a declarative `field.optionLayout`\n// so popup DEFINITIONS (plain .js config files) stay JSX-free:\n//\n//   optionLayout: {\n//     id:       '{applicantRefrenceId}',            // small mono chip, optional\n//     title:    '{firstName} {lastName}',           // primary line\n//     subtitle: '{designation}',                    // secondary line, optional\n//     meta: [                                       // footer key/value pairs\n//       { label: 'Created', key: 'createdAt', type: 'date' },\n//       { label: 'Updated', key: 'updatedAt', type: 'relative' },\n//     ],\n//   }\n//\n// Every string is a `{placeholder}` template resolved against the raw API row.\n// The already-submitted tick is NOT part of the layout config — it is derived\n// from the option's own `alreadySubmitted` / `submittedAt` (see\n// popupUtils.normalizeOption), so it works for any module that flags rows.\n\nconst ABSOLUTE_DATE_FORMAT = 'DD MMM YYYY';\nconst FULL_DATE_FORMAT = 'DD MMM YYYY, h:mm A';\n\nfunction formatOptionDate(value, type) {\n  if (value === undefined || value === null || value === '') return '';\n  const date = dayjs(value);\n  if (!date.isValid()) return String(value);\n  if (type !== 'relative') {\n    // A placeholder date is not a date. Printing \"01 Jan 0001\" is worse than\n    // saying nothing, because it reads as a real value someone entered.\n    return isMeaningfulDate(value) ? date.format(ABSOLUTE_DATE_FORMAT) : '';\n  }\n  // `relative` uses the popup's own Today / Yesterday / N days / N months /\n  // N years labels — dayjs's fromNow() needs the relativeTime plugin, which\n  // this package does not register.\n  const ago = relativeDateLabel(value);\n  if (ago) return ago;\n  // No usable age. A record whose stored \"updated\" is the zero time was never\n  // updated, and saying so is the honest answer — the alternative was\n  // \"2025 years ago\", which looked like a bug because it was one.\n  return isMeaningfulDate(value) ? date.format(ABSOLUTE_DATE_FORMAT) : 'Not updated';\n}\n\n/** Resolves one `optionLayout` slot: a `{template}` string, or a plain key.\n *  Runs through tidyTemplateLabel so a slot like '{designation} · {email}' does\n *  not render a dangling '·' when the candidate has no designation. */\nfunction resolveSlot(template, row) {\n  if (!template) return '';\n  if (!String(template).includes('{')) return String(row?.[template] ?? template).trim();\n  return tidyTemplateLabel(fillTemplate(template, row));\n}\n\n/** The already-submitted marker: a LEADING tick, no text.\n *\n *  This was a right-rail \"Submitted\" badge in a reserved 100px column. The\n *  column had to be reserved so the dates could not shift between a flagged\n *  and an unflagged row — which meant every selectable row carried 100px of\n *  blank space to the right of its dates. Moving the marker to a 16px gutter\n *  before the name keeps every title aligned at a fraction of the cost, and\n *  reads naturally: the tick qualifies the person, so it belongs beside them.\n *  The word \"Submitted\" is redundant next to a green tick — the date it stood\n *  for is richer, and now lives in the tooltip.\n */\n/** The tick marks SUBMISSION HISTORY, in two flavours.\n *\n *  isFromSubmission — the candidate has a submission to some OTHER job. That\n *    never blocks: they are a perfectly valid pick, and the prior submission is\n *    what the form prefills from. A green tick reads as \"we know this person\".\n *\n *  alreadySubmitted — a submission to THIS job. Cannot be picked again.\n *    The tick goes muted, because a green tick on an unpickable row reads as\n *    approval; the reason itself is carried by the rail (see OptionDates).\n *\n *  Both are history, so both get the tick — what differs is its tone and what\n *  the tooltip says. */\nfunction tickState(option) {\n  if (option?.alreadySubmitted) {\n    const when = option?.submittedAt ? dayjs(option.submittedAt) : null;\n    return {\n      tone: 'blocked',\n      tooltip: when?.isValid()\n        ? `Already submitted to this job on ${when.format(FULL_DATE_FORMAT)}`\n        : 'Already submitted to this job — a candidate can only be submitted once per job',\n    };\n  }\n  if (option?.isFromSubmission) {\n    const when = option?.priorSubmittedAt ? dayjs(option.priorSubmittedAt) : null;\n    return {\n      tone: 'history',\n      tooltip: when?.isValid()\n        ? `Previously submitted on ${when.format(FULL_DATE_FORMAT)} — this form will prefill from it`\n        : 'Submitted to another job before — this form will prefill from it',\n    };\n  }\n  return null;\n}\n\n/** Why a row is unselectable for a reason OTHER than being already submitted\n *  (e.g. a fulfilled job). Rendered inline after the title rather than in a\n *  rail, so it costs nothing on the rows that do not have one. */\nfunction blockedNote(option, row) {\n  if (option?.alreadySubmitted || !option?.disabled) return '';\n  return String(row?.message ?? option?.title ?? '').trim();\n}\n\n/** The dates rail.\n *\n *  A two-column GRID, with the label and the value as direct grid children —\n *  not one right-aligned span per date. When each date was a single span, the\n *  labels floated: \"Created 28 Jul 2026\" and \"Updated Today\" are different\n *  widths, so \"Created\" and \"Updated\" landed at different x positions and the\n *  pair never read as a column. As a grid the labels share column 1 and the\n *  values share a right-aligned column 2, so both align down the row AND\n *  across every row in the list (the label column is `max-content`, identical\n *  for identical labels). */\nfunction OptionDates({ meta }) {\n  return (\n    <div className=\"dynamic-popup__option-dates\">\n      {meta.map((entry) => (\n        <Fragment key={entry.label}>\n          <span className=\"dynamic-popup__option-date-label\">{entry.label}</span>\n          <span className=\"dynamic-popup__option-date-value\">{entry.text}</span>\n        </Fragment>\n      ))}\n    </div>\n  );\n}\n\nfunction RichSelectOption({ option, layout }) {\n  const row = option?._raw ?? option ?? {};\n  const id = resolveSlot(layout.id, row);\n  const title = resolveSlot(layout.title, row) || String(option?.label ?? '');\n  const subtitle = resolveSlot(layout.subtitle, row);\n  const emphasisText = resolveSlot(layout.titleAccent?.key, row);\n  const emphasisTone = resolveSlot(layout.titleAccent?.toneKey, row);\n  const emphasisPrefix = layout.titleAccent?.prefix ?? '';\n  const meta = (layout.meta ?? [])\n    .map((entry) => ({ label: entry.label, text: formatOptionDate(row?.[entry.key], entry.type) }))\n    .filter((entry) => entry.text);\n  const note = blockedNote(option, row);\n  const tick = tickState(option);\n\n  // Two columns: the leading tick gutter + identity (grows), then the dates\n  // rail. The gutter is always reserved — 16px — so titles line up whether or\n  // not a row is flagged, without the 100px of dead space the old right-hand\n  // status column cost every unflagged row.\n  return (\n    <div className=\"dynamic-popup__option\">\n      <span className={`dynamic-popup__option-tick${tick ? ` dynamic-popup__option-tick--${tick.tone}` : ''}`}>\n        {tick && (\n          <Tooltip title={tick.tooltip} placement=\"topLeft\">\n            <CheckCircleFilled aria-label={tick.tooltip} />\n          </Tooltip>\n        )}\n      </span>\n      <div className=\"dynamic-popup__option-main\">\n        <div className=\"dynamic-popup__option-head\">\n          {id && <span className=\"dynamic-popup__option-id\">{id}</span>}\n          <span className=\"dynamic-popup__option-title\">\n            <span className=\"dynamic-popup__option-title-text\">{title}</span>\n            {emphasisText && (\n              <span className={`dynamic-popup__option-title-accent${emphasisTone ? ` dynamic-popup__option-title-accent--${emphasisTone}` : ''}`}>\n                {`${emphasisPrefix}${emphasisText}`}\n              </span>\n            )}\n          </span>\n          {note && <span className=\"dynamic-popup__option-flag\">{note}</span>}\n        </div>\n        {subtitle && <div className=\"dynamic-popup__option-sub\">{subtitle}</div>}\n      </div>\n      {option?.alreadySubmitted\n        ? <span className=\"dynamic-popup__option-onjob\">On this job</span>\n        : meta.length > 0 && <OptionDates meta={meta} />}\n    </div>\n  );\n}\n\nexport default RichSelectOption;\n","import { useEffect } from 'react';\nimport { Checkbox, DatePicker, Input, InputNumber, Mentions, Modal, Radio, Select, Space, Switch, Typography } from 'antd';\nimport { CrownOutlined } from '@ant-design/icons';\nimport RichSelectOption from './richSelectOption.jsx';\n\nconst { Text } = Typography;\n\nconst { TextArea } = Input;\n\nconst CURRENCY_OPTIONS = [\n  { label: '$', value: '$' },\n  { label: 'EUR', value: 'EUR' },\n  { label: 'GBP', value: 'GBP' },\n  { label: 'INR', value: 'INR' },\n];\n\nconst PERIOD_OPTIONS = [\n  { label: 'Hourly', value: 'Hourly' },\n  { label: 'Daily', value: 'Daily' },\n  { label: 'Weekly', value: 'Weekly' },\n  { label: 'Monthly', value: 'Monthly' },\n  { label: 'Yearly', value: 'Yearly' },\n];\n\nexport function normalizeSelectOptions(options = []) {\n  return options.map((option) => {\n    if (!option || typeof option !== 'object') return option;\n\n    const rawValue = [\n      option.value,\n      option.user_id,\n      option.userId,\n      option.USER_ID,\n      option.legacyUserId,\n      option.id,\n      option._id,\n    ].find((candidate) => (\n      candidate !== undefined\n      && candidate !== null\n      && String(candidate).trim() !== ''\n    ));\n    const value = rawValue === undefined || rawValue === null ? '' : String(rawValue).trim();\n\n    return { ...option, value };\n  }).filter((option) => (\n    option === undefined\n    || option === null\n    || typeof option !== 'object'\n    || String(option.value ?? '').trim() !== ''\n  ));\n}\n\nfunction InputField({ field, value, onChange }) {\n  return (\n    <Input\n      value={value}\n      onChange={onChange}\n      placeholder={field.placeholder}\n      maxLength={field.maxLength}\n      prefix={<CrownOutlined />}\n    />\n  );\n}\n\nfunction TextareaField({ field, value, onChange }) {\n  return (\n    <TextArea\n      value={value}\n      onChange={onChange}\n      rows={field.rows ?? 5}\n      placeholder={field.placeholder}\n    />\n  );\n}\n\nfunction SelectField({ field, options, value, onChange }) {\n  const normalizedOptions = normalizeSelectOptions(options);\n  return (\n    <Select\n      showSearch\n      value={value}\n      onChange={onChange}\n      options={normalizedOptions}\n      placeholder={field.placeholder}\n      className=\"dynamic-popup__field-select\"\n      optionFilterProp=\"label\"\n      prefix={<CrownOutlined />}\n    />\n  );\n}\n\nfunction MultiSelectField({ field, options, value, onChange }) {\n  const normalizedOptions = normalizeSelectOptions(options);\n  return (\n    <Select\n      mode=\"multiple\"\n      showSearch\n      value={value}\n      onChange={onChange}\n      options={normalizedOptions}\n      placeholder={field.placeholder}\n      className=\"dynamic-popup__field-select\"\n      optionFilterProp=\"label\"\n      prefix={<CrownOutlined />}\n    />\n  );\n}\n\nfunction SearchSelectField({ field, options, onSearch, value, onChange, popupContext }) {\n  const normalizedOptions = normalizeSelectOptions(options);\n  const layout = field.optionLayout;\n  const optionsByValue = new Map(normalizedOptions.map((option) => [String(option?.value ?? ''), option]));\n\n  async function handleChange(nextValue, option) {\n    if (field.multiple) {\n      onChange?.(Array.isArray(nextValue) ? nextValue : []);\n      return;\n    }\n    const selectedOption = option ?? optionsByValue.get(String(nextValue ?? ''));\n    if (typeof field.onSelectGuard === 'function') {\n      const result = await field.onSelectGuard({\n        value: nextValue,\n        option: selectedOption,\n        field,\n        popupContext,\n        confirm: Modal.confirm,\n      });\n      if (result === false) return;\n    }\n    onChange?.(nextValue);\n  }\n\n  return (\n    <Select\n      mode={field.multiple ? 'multiple' : undefined}\n      showSearch\n      filterOption={false}\n      notFoundContent={field.notFoundContent ?? null}\n      value={value}\n      onChange={handleChange}\n      options={normalizedOptions}\n      placeholder={field.placeholder}\n      onSearch={onSearch}\n      className={`dynamic-popup__field-select${layout ? ' dynamic-popup__field-select--rich' : ''}`}\n      popupClassName={layout ? 'dynamic-popup__option-dropdown' : undefined}\n      listHeight={layout ? 340 : undefined}\n      optionLabelProp=\"label\"\n      // Rich rows apply to the DROPDOWN only ??? the closed select keeps the plain\n      // one-line `label`, so a selected value never blows up the field height.\n      optionRender={layout ? (option) => <RichSelectOption option={option?.data ?? option} layout={layout} /> : undefined}\n      prefix={<CrownOutlined />}\n    />\n  );\n}\n\nfunction MentionField({ field, mentionOpts, onMentionSearch, value, onChange }) {\n  // maxLength is admin config on the popup field. Enforced in TWO places on\n  // purpose: the browser stops the typing here, and securityValidationRule\n  // re-checks the same `field.maxLength` at submit — because a value can also\n  // arrive by paste, autofill or a prefill, none of which the input cap sees.\n  const limit = Number(field.maxLength) > 0 ? Number(field.maxLength) : undefined;\n  const used = String(value ?? '').length;\n  return (\n    <>\n      <Mentions\n        value={value}\n        onChange={onChange}\n        rows={field.rows ?? 5}\n        placeholder={field.placeholder}\n        prefix=\"@\"\n        options={mentionOpts}\n        onSearch={onMentionSearch}\n        maxLength={limit}\n        className=\"dynamic-popup__mention-textarea\"\n      />\n      {limit ? (\n        // Shown always, not only once exceeded: a limit the user discovers by\n        // hitting it is a limit that has already cost them their sentence.\n        <div\n          className=\"dynamic-popup__char-count\"\n          style={{ textAlign: 'right', fontSize: 12, marginTop: 4, color: used > limit * 0.9 ? '#b45309' : '#8c8c8c' }}\n        >\n          {used} / {limit}\n        </div>\n      ) : null}\n    </>\n  );\n}\n\n/**\n * Composite rate input: single amount or range, with currency and period selectors.\n * Receives `value`/`onChange` from Ant Design Form.Item (controlled component protocol).\n */\nfunction CandidateRateField({ field = {}, value = {}, onChange }) {\n  const period = value.period ?? 'Hourly';\n  const isRange = value.isRange ?? false;\n\n  function update(patch) {\n    onChange?.({ ...value, ...patch });\n  }\n\n  // Seed the sensible defaults ($ / Hourly) into the actual form value the FIRST\n  // time the field renders, so they're submitted even if the user never touches\n  // the currency/period selects.\n  useEffect(() => {\n    const seed = {};\n    if (value.currency == null) seed.currency = '$';\n    if (value.period == null) seed.period = 'Hourly';\n    if (Object.keys(seed).length) onChange?.({ ...value, ...seed });\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  // Inline hints for the two rate rules (the Form.Item validator also blocks\n  // submit — see the others-assign candidateRate validator): To > From, and the\n  // rate must not exceed the job's client rate (field.rateCeiling, injected from\n  // the job's jobPayDetails).\n  const entered = isRange ? Number(value.maxAmount) : Number(value.amount);\n  const rangeInvalid = isRange && value.minAmount != null && value.maxAmount != null\n    && Number(value.maxAmount) <= Number(value.minAmount);\n  const overCeiling = field.rateCeiling != null && Number.isFinite(entered)\n    && entered > Number(field.rateCeiling);\n\n  return (\n    <div>\n      <Space.Compact style={{ width: '100%' }}>\n        {isRange ? (\n          <>\n            <InputNumber\n              controls={false}\n              placeholder=\"From\"\n              value={value.minAmount}\n              onChange={(v) => update({ minAmount: v })}\n              style={{ flex: 1 }}\n            />\n            <InputNumber\n              controls={false}\n              placeholder=\"To\"\n              value={value.maxAmount}\n              onChange={(v) => update({ maxAmount: v })}\n              style={{ flex: 1 }}\n            />\n          </>\n        ) : (\n          <InputNumber\n            controls={false}\n            placeholder=\"0\"\n            value={value.amount}\n            onChange={(v) => update({ amount: v })}\n            style={{ flex: 2 }}\n          />\n        )}\n        <Select\n          value={value.currency ?? '$'}\n          options={CURRENCY_OPTIONS}\n          onChange={(v) => update({ currency: v })}\n          style={{ width: 80 }}\n        />\n        <Select\n          value={period}\n          options={PERIOD_OPTIONS}\n          onChange={(v) => update({ period: v })}\n          style={{ width: 110 }}\n        />\n      </Space.Compact>\n      {(rangeInvalid || overCeiling) && (\n        <div style={{ marginTop: 4 }}>\n          {rangeInvalid && <Text type=\"danger\" style={{ fontSize: 12, display: 'block' }}>To rate must be greater than From rate.</Text>}\n          {overCeiling && <Text type=\"danger\" style={{ fontSize: 12, display: 'block' }}>Rate must not exceed the client rate ({field.rateCeiling}).</Text>}\n        </div>\n      )}\n      <Space size=\"small\" style={{ marginTop: 8 }}>\n        <Switch checked={isRange} onChange={(v) => update({ isRange: v })} />\n        <span>Range</span>\n      </Space>\n    </div>\n  );\n}\n\nfunction DatePickerField({ field, value, onChange }) {\n  return (\n    <DatePicker\n      value={value}\n      onChange={onChange}\n      placeholder={field.placeholder ?? 'Select date'}\n      style={{ width: '100%' }}\n      format=\"YYYY-MM-DD\"\n    />\n  );\n}\n\nfunction PriorityCheckboxField({ field, checked, onChange }) {\n  return <Checkbox checked={checked} onChange={onChange}>{field.checkboxLabel}</Checkbox>;\n}\n\nfunction NumberField({ field, value, onChange }) {\n  return (\n    <InputNumber\n      value={value}\n      onChange={onChange}\n      min={field.min}\n      max={field.max}\n      placeholder={field.placeholder}\n      style={{ width: '100%' }}\n    />\n  );\n}\n\nfunction RadioGroupField({ options, value, onChange }) {\n  return <Radio.Group value={value} onChange={onChange} options={options} />;\n}\n\n/**\n * Maps field `type` strings to their React components.\n *\n * Each component receives the standard field props injected by PopupFields:\n *   `{ field, options, onSearch, mentionOpts, onMentionSearch }`\n * plus `value`/`onChange` (or `checked`/`onChange` for priority-checkbox)\n * injected by Ant Design Form.Item.\n *\n * To add a new field type: add a component here and register it.\n */\nexport const FIELD_REGISTRY = {\n  input: InputField,\n  text: InputField,\n  textarea: TextareaField,\n  select: SelectField,\n  'multi-select': MultiSelectField,\n  'search-select': SearchSelectField,\n  'mention-textarea': MentionField,\n  'candidate-rate': CandidateRateField,\n  'priority-checkbox': PriorityCheckboxField,\n  'date-picker': DatePickerField,\n  'number': NumberField,\n  'radio': RadioGroupField,\n};\n\n/**\n * Returns extra Form.Item props needed for a given field type.\n * @param {string} fieldType\n * @returns {Object}\n */\nexport function getFieldFormItemProps(fieldType) {\n  if (fieldType === 'priority-checkbox') return { valuePropName: 'checked' };\n  return {};\n}\n","import { Divider, Form, Tag } from 'antd';\nimport AppTypography from '../../typography/Typography';\nimport { FIELD_REGISTRY, getFieldFormItemProps } from './fieldRegistry.jsx';\nimport { resolveOptions } from './utils/popupUtils';\nimport { securityValidationRule } from '../../form/inputSecurity';\n\n// Popup field types that accept free text — these get the same central\n// input-security rule (script/HTML/SQL/command-injection blocking) the\n// AddFormV1/EditFormV1 engines apply to every form field. New popup\n// definitions inherit it automatically.\nconst TEXT_LIKE_POPUP_TYPES = new Set(['input', 'text', 'textarea', 'mention-textarea']);\n\n/**\n * Renders the form section of DynamicPopup, including:\n *   - The \"Already Assigned People\" tag list (for others-assign)\n *   - All form fields via FIELD_REGISTRY\n *\n * @param {Object} props\n * @param {Object} props.form - Ant Design form instance\n * @param {Array} props.fields\n * @param {Object} props.initialValues\n * @param {Object} props.dynamicOptions\n * @param {Object} props.popupContext\n * @param {*} props.extraData\n * @param {string[]} props.removedIds\n * @param {Function} props.setRemovedIds\n * @param {boolean} [props.showAlreadyAssigned]\n * @param {Function} props.onValuesChange\n * @param {Function} props.getSearchHandler\n * @param {Function} props.getMentionSearchHandler\n * @param {Object} props.mentionOptions\n */\nexport default function PopupFields({\n  form,\n  fields,\n  initialValues,\n  dynamicOptions,\n  popupContext,\n  extraData,\n  removedIds,\n  setRemovedIds,\n  showAlreadyAssigned,\n  onValuesChange,\n  getSearchHandler,\n  getMentionSearchHandler,\n  mentionOptions,\n}) {\n  const assignedPeople = (extraData?.recruitersData ?? []).filter((recruiter) => {\n    const id = String(\n      recruiter?.user_id ?? recruiter?.id ?? recruiter?.userId ?? '',\n    );\n    return id && !removedIds.includes(id);\n  });\n  const showAssignedSection = showAlreadyAssigned && extraData;\n\n  // Someone already on the job must not be offered for assignment again —\n  // picking them was a no-op at best, and the popup looked broken because the\n  // same person sat in \"Already Assigned\" AND in the dropdown.\n  //\n  // Derived from `assignedPeople`, which is already \"assigned AND not pending\n  // removal\". That is what makes the reverse work for free: un-assign someone\n  // with the tag's x and they become selectable again immediately, which is\n  // exactly what a user who removed them by mistake expects.\n  const assignedOptionIds = new Set(\n    showAlreadyAssigned\n      ? assignedPeople\n        .map((r) => String(r?.user_id ?? r?.id ?? r?.userId ?? '').trim())\n        .filter(Boolean)\n      : [],\n  );\n  const withoutAssigned = (options) => (\n    assignedOptionIds.size === 0 || !Array.isArray(options)\n      ? options\n      : options.filter((opt) => !assignedOptionIds.has(\n        String((opt && typeof opt === 'object' ? (opt.value ?? opt.id) : opt) ?? '').trim(),\n      ))\n  );\n\n  if (!fields.length && !showAssignedSection) return null;\n\n  return (\n    <>\n      {showAssignedSection && (\n        <>\n          <div className=\"dynamic-popup__already-assigned\">\n            <AppTypography variant=\"caption\" color=\"secondary\">Already Assigned People</AppTypography>\n            <div style={{ marginTop: 6, display: 'flex', flexWrap: 'wrap', gap: 6 }}>\n              {assignedPeople.length === 0 ? (\n                <AppTypography variant=\"caption\" color=\"secondary\">\n                  No one is currently assigned to this job.\n                </AppTypography>\n              ) : assignedPeople.map((recruiter) => {\n                  const id = String(\n                    recruiter?.user_id ?? recruiter?.id ?? recruiter?.userId ?? '',\n                  );\n                  const name =\n                    recruiter?.name ??\n                    recruiter?.user_name ??\n                    recruiter?.userName ??\n                    recruiter?.email ??\n                    'Assigned user';\n                  return (\n                    <Tag\n                      key={id || name}\n                      closable\n                      onClose={() => {\n                        if (!id) return;\n                        setRemovedIds((prev) => Array.from(new Set([...prev, id])));\n                      }}\n                    >\n                      {name}\n                    </Tag>\n                  );\n                })}\n            </div>\n          </div>\n          <Divider style={{ margin: '12px 0' }} />\n        </>\n      )}\n\n      {fields.length > 0 && (\n        <Form\n          form={form}\n          layout=\"vertical\"\n          initialValues={initialValues}\n          onValuesChange={(_, allValues) => onValuesChange(allValues)}\n        >\n          {groupFieldsIntoRows(fields).map((rowFields) => renderRow(rowFields, (field) => {\n            const options = withoutAssigned(dynamicOptions[field.name] ?? resolveOptions(field, popupContext));\n            const onSearch = getSearchHandler(field);\n            const onMentionSearch = getMentionSearchHandler(field);\n            const currentMentionOpts = mentionOptions[field.name] ?? [];\n            const formItemProps = getFieldFormItemProps(field.type);\n            const Control = FIELD_REGISTRY[field.type];\n\n            const rules = [];\n            if (field.required) {\n              rules.push({ required: true, message: `${field.label || 'This field'} is required` });\n            }\n            if (typeof field.validator === 'function') {\n              rules.push({\n                validator: (_, value) => {\n                  const errorMessage = field.validator(value, popupContext);\n                  return errorMessage ? Promise.reject(new Error(errorMessage)) : Promise.resolve();\n                },\n              });\n            }\n            if (TEXT_LIKE_POPUP_TYPES.has(field.type)) {\n              rules.push(securityValidationRule({ label: field.label, field: field.name, type: field.type }));\n            }\n\n            return (\n              <Form.Item\n                key={field.name}\n                name={field.name}\n                label={field.label}\n                rules={rules}\n                {...formItemProps}\n              >\n                {Control ? (\n                  <Control\n                    field={field}\n                    options={options}\n                    onSearch={onSearch}\n                    mentionOpts={currentMentionOpts}\n                    onMentionSearch={onMentionSearch}\n                    popupContext={popupContext}\n                  />\n                ) : null}\n              </Form.Item>\n            );\n          }))}\n        </Form>\n      )}\n    </>\n  );\n}\n\n// ── Inline rows ───────────────────────────────────────────────────────────────\n// Consecutive fields sharing the same `inlineRow` key render side-by-side on\n// one line (e.g. the Approve Rate popup's Proposed Rate + Currency + Unit).\n// Fields without inlineRow keep the default one-per-line layout, so every\n// existing popup is unaffected. Generic — any popup definition can opt in.\nfunction groupFieldsIntoRows(fields) {\n  const rows = [];\n  for (const field of fields) {\n    const previous = rows[rows.length - 1];\n    if (field.inlineRow && previous?.inlineRow === field.inlineRow) {\n      previous.fields.push(field);\n    } else {\n      rows.push({ inlineRow: field.inlineRow, fields: [field] });\n    }\n  }\n  return rows.map((row) => row.fields);\n}\n\nfunction renderRow(rowFields, renderField) {\n  if (rowFields.length === 1) return renderField(rowFields[0]);\n  return (\n    <div\n      key={`row-${rowFields.map((f) => f.name).join('-')}`}\n      style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}\n    >\n      {rowFields.map((field, index) => (\n        <div key={field.name} style={{ flex: index === 0 ? 2 : 1, minWidth: 0 }}>\n          {renderField(field)}\n        </div>\n      ))}\n    </div>\n  );\n}\n","import { useEffect, useState } from 'react';\nimport { AUTH_URL, APP_ID } from '../../../../services/apiConfig';\nimport { fetchJsonWithAuth } from '../../../../services/authApi';\nimport { normalizeOption } from '../utils/popupUtils';\n\nfunction fieldSupportsMasterOptions(field) {\n  return ['select', 'multi-select', 'search-select', 'radio'].includes(field?.type)\n    && field?.dataSource === 'master'\n    && field?.masterName;\n}\n\nfunction unwrapMasterRows(json) {\n  const payload = json?.data ?? json;\n  if (Array.isArray(payload)) return payload;\n  if (Array.isArray(payload?.data)) return payload.data;\n  if (Array.isArray(payload?.items)) return payload.items;\n  if (Array.isArray(payload?.rows)) return payload.rows;\n  if (Array.isArray(payload?.records)) return payload.records;\n  return [];\n}\n\nfunction isClientSubmissionStatusMaster(field) {\n  const masterName = String(field?.masterName ?? '').trim().toLowerCase();\n  return masterName === 'clientsubmissions' || masterName === 'clientsubmissionstatus';\n}\n\nfunction normalizeClientSubmissionStatusOption(item) {\n  if (item === null || item === undefined) return null;\n\n  // clientSubmissionStatus can be returned by different backend versions as:\n  //   { id, name, type, ...transitionFields }\n  //   { uniqueId, name, type, ...transitionFields }\n  //   { label, value, ...transitionFields }\n  // Do not pass this master through the generic normalizer because its\n  // label/value aliases have changed over time. Build one stable option shape.\n  if (typeof item === 'string') {\n    const text = item.trim();\n    return text ? { label: text, value: text, _raw: { name: text } } : null;\n  }\n\n  const name = String(\n    item?.name\n      ?? item?.clientSubmissionStatusText\n      ?? item?.label\n      ?? item?.text\n      ?? '',\n  ).trim();\n  if (!name) return null;\n\n  const id = Number(\n    item?.id\n      ?? item?.uniqueId\n      ?? item?.clientSubmissionStatusId\n      ?? item?.value\n      ?? 0,\n  ) || 0;\n\n  return {\n    label: name,\n    // The popup form keeps the human-readable status as its value. The submit\n    // handler reads the numeric id/type from _raw and sends the full object.\n    value: name,\n    _raw: {\n      ...item,\n      ...(id > 0 ? { id, uniqueId: id } : {}),\n      name,\n      type: String(item?.type ?? item?.clientSubmissionStatusType ?? '').trim(),\n      isInitialStatus: item?.isInitialStatus === true,\n      isTerminalStatus: item?.isTerminalStatus === true,\n      allowedNextStatusIds: Array.isArray(item?.allowedNextStatusIds)\n        ? item.allowedNextStatusIds.map(Number).filter((nextId) => Number.isInteger(nextId) && nextId > 0)\n        : [],\n    },\n  };\n}\n\nfunction normalizeMasterOption(item, field) {\n  if (isClientSubmissionStatusMaster(field)) {\n    return normalizeClientSubmissionStatusOption(item);\n  }\n  return normalizeOption(item, field);\n}\n\nfunction currentClientSubmissionStatus(record) {\n  const status = record?.clientSubmissionStatus;\n\n  const id = Number(\n    (status && typeof status === 'object'\n      ? (\n        status?.clientSubmissionStatusId\n        ?? status?.id\n        ?? status?.uniqueId\n      )\n      : undefined)\n      ?? record?.clientSubmissionStatusId\n      ?? record?.clientStatusId\n      ?? record?.['clientSubmissionStatus.clientSubmissionStatusId']\n      ?? 0,\n  ) || 0;\n\n  const statusObjectText = status && typeof status === 'object'\n    ? (\n      status?.clientSubmissionStatusText\n      ?? status?.name\n      ?? status?.text\n      ?? status?.label\n    )\n    : status;\n\n  const text = String(\n    statusObjectText\n      ?? record?.clientSubmissionStatusText\n      ?? record?.clientStatus\n      ?? record?.clientStatusText\n      ?? record?.['clientSubmissionStatus.clientSubmissionStatusText']\n      ?? '',\n  ).trim();\n\n  return { id, text };\n}\n\nfunction isUnsubmittedClientStatus(status) {\n  const id = Number(status?.id ?? 0) || 0;\n  const text = String(status?.text ?? '').trim();\n\n  // A list row may contain only the displayed client status text and omit the\n  // numeric status id. Likewise, detail data can sometimes contain the id but\n  // not the projected text. Either one is enough to identify an existing\n  // client-submission status. Only treat the record as unsubmitted when BOTH\n  // are missing, or when it explicitly says \"Not Submitted\".\n  if (text && text.toLowerCase() === 'not submitted') return true;\n  return id <= 0 && !text;\n}\n\nfunction optionStatusId(option) {\n  return Number(option?._raw?.id ?? option?._raw?.uniqueId ?? 0) || 0;\n}\n\nfunction optionAllowedNextIds(option) {\n  const ids = option?._raw?.allowedNextStatusIds;\n  return Array.isArray(ids) ? ids.map(Number).filter((id) => Number.isInteger(id) && id > 0) : [];\n}\n\n\nfunction unwrapDetailRecord(json) {\n  const payload = json?.data ?? json;\n  if (!payload) return null;\n  if (Array.isArray(payload)) return payload[0] ?? null;\n  if (payload?.record && typeof payload.record === 'object') return payload.record;\n  if (payload?.data && typeof payload.data === 'object' && !Array.isArray(payload.data)) return payload.data;\n  return typeof payload === 'object' ? payload : null;\n}\n\nfunction contextHasCurrentClientStatus(popupContext) {\n  const selectedRecords = Array.isArray(popupContext?.selectedRecords)\n    ? popupContext.selectedRecords.filter(Boolean)\n    : [];\n\n  if (selectedRecords.some((record) => !isUnsubmittedClientStatus(currentClientSubmissionStatus(record)))) {\n    return true;\n  }\n\n  return !isUnsubmittedClientStatus(currentClientSubmissionStatus(popupContext ?? {}));\n}\n\nasync function enrichPopupContextWithCurrentSubmissionStatus(popupContext, appId) {\n  if (contextHasCurrentClientStatus(popupContext)) return popupContext;\n\n  const selectedId = popupContext?.selectedIds?.[0]\n    ?? popupContext?.selectedRecords?.[0]?._id\n    ?? popupContext?.selectedRecords?.[0]?.id;\n  if (!selectedId) return popupContext;\n\n  const moduleName = String(popupContext?.moduleName ?? 'submissions').trim() || 'submissions';\n  const params = new URLSearchParams({\n    module: moduleName,\n    id: String(selectedId),\n  });\n  if (appId) params.set('app_id', appId);\n\n  try {\n    const detailJson = await fetchJsonWithAuth(\n      AUTH_URL,\n      `/module-data-detail?${params.toString()}`,\n      { headers: appId ? { 'X-App-Id': appId } : undefined },\n    );\n    const detailRecord = unwrapDetailRecord(detailJson);\n    if (!detailRecord) return popupContext;\n\n    const existingRecords = Array.isArray(popupContext?.selectedRecords)\n      ? popupContext.selectedRecords\n      : [];\n\n    return {\n      ...popupContext,\n      selectedRecords: existingRecords.length\n        ? existingRecords.map((record, index) => (\n          index === 0 ? { ...record, ...detailRecord } : record\n        ))\n        : [detailRecord],\n    };\n  } catch (error) {\n    console.warn(\n      '[DynamicPopup] Could not load selected submission detail for client status transition:',\n      error,\n    );\n    return popupContext;\n  }\n}\n\nfunction filterClientSubmissionStatusOptions(options, popupContext) {\n  if (!Array.isArray(options) || !options.length) return [];\n\n  const hasTransitionConfiguration = options.some((option) => (\n    option?._raw?.isInitialStatus === true\n    || option?._raw?.isTerminalStatus === true\n    || Array.isArray(option?._raw?.allowedNextStatusIds)\n  ));\n  if (!hasTransitionConfiguration) return options;\n\n  const selectedRecords = Array.isArray(popupContext?.selectedRecords)\n    ? popupContext.selectedRecords.filter(Boolean)\n    : [];\n\n  const contextStatus = {\n    clientSubmissionStatus: popupContext?.clientSubmissionStatus,\n    clientSubmissionStatusId: popupContext?.clientSubmissionStatusId,\n    clientSubmissionStatusText: popupContext?.clientSubmissionStatusText,\n    clientStatus: popupContext?.clientStatus,\n    clientStatusId: popupContext?.clientStatusId,\n    clientStatusText: popupContext?.clientStatusText,\n    'clientSubmissionStatus.clientSubmissionStatusId':\n      popupContext?.['clientSubmissionStatus.clientSubmissionStatusId'],\n    'clientSubmissionStatus.clientSubmissionStatusText':\n      popupContext?.['clientSubmissionStatus.clientSubmissionStatusText'],\n  };\n\n  const records = selectedRecords.length ? selectedRecords : [contextStatus];\n\n  return options.filter((candidateOption) => records.every((record) => {\n    let currentStatus = currentClientSubmissionStatus(record);\n\n    // Some list configurations only project the visible status text into\n    // popupContext rather than keeping the complete nested status object.\n    // Use the popup context as a secondary source before considering the\n    // submission \"not submitted\".\n    if (isUnsubmittedClientStatus(currentStatus)) {\n      const fallbackStatus = currentClientSubmissionStatus(contextStatus);\n      if (!isUnsubmittedClientStatus(fallbackStatus)) {\n        currentStatus = fallbackStatus;\n      }\n    }\n    if (isUnsubmittedClientStatus(currentStatus)) {\n      return candidateOption?._raw?.isInitialStatus === true;\n    }\n\n    const currentOption = options.find((option) => {\n      const id = optionStatusId(option);\n      const text = String(option?.label ?? '').trim();\n      return (currentStatus.id > 0 && id === currentStatus.id)\n        || (currentStatus.text && text.toLowerCase() === currentStatus.text.toLowerCase());\n    });\n    if (!currentOption || currentOption?._raw?.isTerminalStatus === true) return false;\n\n    const allowedIds = optionAllowedNextIds(currentOption);\n    return allowedIds.includes(optionStatusId(candidateOption));\n  }));\n}\n\n/**\n * Manages dynamic option fetching and extra-data loading for DynamicPopup.\n *\n * Uses AbortController (latest-request-wins) so that state is never updated\n * from a response that arrived after the popup closed or the deps changed.\n *\n * @param {Object} params\n * @param {boolean} params.open\n * @param {Object|null} params.config\n * @param {Object} params.api - { getOptions?, loadExtraData? }\n * @param {Array} params.fields\n * @param {Object} params.popupContext\n * @param {Object} params.formValues\n * @returns {{ dynamicOptions: Object, setDynamicOptions: Function, extraData: * }}\n */\nexport function usePopupOptions({ open, config, api, fields, popupContext, formValues }) {\n  const [dynamicOptions, setDynamicOptions] = useState({});\n  const [extraData, setExtraData] = useState(null);\n\n  // Clear stale data when the popup closes so the next open starts fresh\n  useEffect(() => {\n    if (!open) {\n      setDynamicOptions({});\n      setExtraData(null);\n    }\n  }, [open]);\n\n  // Fetch options that have no form-value dependency (runs once on open)\n  useEffect(() => {\n    if (!open || !config || !api.getOptions) return;\n\n    const controller = new AbortController();\n\n    fields.forEach((field) => {\n      if (!field.fetchOptionsKey || field.fetchOptionsParamKey) return;\n\n      Promise.resolve(api.getOptions(field, undefined, popupContext))\n        .then((items) => {\n          if (controller.signal.aborted) return;\n          setDynamicOptions((prev) => ({ ...prev, [field.name]: items }));\n        })\n        .catch((err) => {\n          if (controller.signal.aborted) return;\n          console.error(`[DynamicPopup] Failed to load options for field \"${field.name}\":`, err);\n        });\n    });\n\n    return () => controller.abort();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, api, config, fields, popupContext]);\n\n  // Fetch master-backed dropdown options declared directly on popup fields.\n  useEffect(() => {\n    if (!open || !config) return;\n\n    const masterFields = fields.filter(fieldSupportsMasterOptions);\n    if (!masterFields.length) return;\n\n    const controller = new AbortController();\n\n    masterFields.forEach((field) => {\n      const params = new URLSearchParams({\n        masterName: field.masterName,\n        offset: '0',\n        limit: String(field.limit ?? 50),\n      });\n      const appId = String(APP_ID ?? '').trim();\n      if (appId) params.set('app_id', appId);\n\n      fetchJsonWithAuth(AUTH_URL, `/masters/dropdown?${params.toString()}`, {\n        headers: appId ? { 'X-App-Id': appId } : undefined,\n      })\n        .then(async (json) => {\n          if (controller.signal.aborted) return;\n          const normalizedOptions = unwrapMasterRows(json)\n            .map((item) => normalizeMasterOption(item, field))\n            .filter(Boolean);\n\n          let optionContext = popupContext;\n          if (isClientSubmissionStatusMaster(field)) {\n            optionContext = await enrichPopupContextWithCurrentSubmissionStatus(\n              popupContext,\n              appId,\n            );\n          }\n          if (controller.signal.aborted) return;\n\n          const options = isClientSubmissionStatusMaster(field)\n            ? filterClientSubmissionStatusOptions(normalizedOptions, optionContext)\n            : normalizedOptions;\n          setDynamicOptions((prev) => ({ ...prev, [field.name]: options }));\n        })\n        .catch((err) => {\n          if (controller.signal.aborted) return;\n          console.error(`[DynamicPopup] Failed to load master options for field \"${field.name}\":`, err);\n        });\n    });\n\n    return () => controller.abort();\n  }, [open, config, fields, popupContext]);\n\n  // Fetch options that depend on another form field value (re-runs when that value changes)\n  useEffect(() => {\n    if (!open || !config || !api.getOptions) return;\n\n    const paramFields = fields.filter((f) => f.fetchOptionsKey && f.fetchOptionsParamKey);\n    if (!paramFields.length) return;\n\n    const controller = new AbortController();\n\n    paramFields.forEach((field) => {\n      const paramValue =\n        formValues[field.fetchOptionsParamKey] ?? popupContext[field.fetchOptionsParamKey];\n      const fetchParams = { [field.fetchOptionsParamKey]: paramValue };\n\n      Promise.resolve(api.getOptions(field, fetchParams, popupContext))\n        .then((items) => {\n          if (controller.signal.aborted) return;\n          setDynamicOptions((prev) => ({ ...prev, [field.name]: items }));\n        })\n        .catch((err) => {\n          if (controller.signal.aborted) return;\n          console.error(\n            `[DynamicPopup] Failed to load param-dependent options for \"${field.name}\":`,\n            err,\n          );\n        });\n    });\n\n    return () => controller.abort();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, api, config, fields, formValues, popupContext]);\n\n  // Load extra data (e.g. existing recruiters for the others-assign popup)\n  useEffect(() => {\n    if (!open || !config || !api.loadExtraData) return;\n\n    const controller = new AbortController();\n\n    Promise.resolve(api.loadExtraData(popupContext))\n      .then((data) => {\n        if (controller.signal.aborted) return;\n        setExtraData(data);\n      })\n      .catch((err) => {\n        if (controller.signal.aborted) return;\n        console.error('[DynamicPopup] Failed to load extra data:', err);\n        setExtraData(null);\n      });\n\n    return () => controller.abort();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, api, config, popupContext]);\n\n  return { dynamicOptions, setDynamicOptions, extraData };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { normalizeOption } from '../utils/popupUtils';\n\nconst SEARCH_DEBOUNCE_MS = 500;\nconst SEARCH_MIN_LENGTH = 3;\n\n/**\n * Provides debounced search handlers for search-select and mention-textarea fields.\n *\n * Each handler uses AbortController (latest-request-wins): when a new search fires\n * before the previous one resolves, the stale response is discarded.\n *\n * A search-select field also gets a PRELOAD: the moment the popup opens, its\n * fetcher is called once with an empty term so the dropdown already lists the\n * most recent records instead of being blank until 3 characters are typed. The\n * fetcher decides what \"empty term\" means (the Quick Submit endpoints return the\n * 10 most recent jobs / candidates). Opt out per field with\n * `preloadOptions: false`.\n *\n * @param {Object} params\n * @param {Object} params.api - { searchOptions?, getMentionOptions? }\n * @param {boolean} params.open\n * @param {Array} [params.fields] - Resolved fields, used to decide what to preload.\n * @param {Object} params.popupContext\n * @param {Function} params.setDynamicOptions - Setter from usePopupOptions\n * @returns {{ mentionOptions: Object, getSearchHandler: Function, getMentionSearchHandler: Function }}\n */\nexport function usePopupSearch({ api, open, fields = [], popupContext, setDynamicOptions }) {\n  const [mentionOptions, setMentionOptions] = useState({});\n  const searchTimerRef = useRef({});\n  const searchAbortRef = useRef({});\n  const mentionAbortRef = useRef({});\n\n  /** The one place a search-select's options are fetched and stored, shared by\n   *  the open-time preload and the debounced onSearch handler. Returns the\n   *  AbortController driving this call so a caller can cancel it directly. */\n  const runSearch = useCallback((field, search) => {\n    const searchFn = api.searchOptions ?? api.searchFetcher;\n    if (typeof searchFn !== 'function') return undefined;\n\n    // Cancel the previous in-flight request for this field\n    searchAbortRef.current[field.name]?.abort();\n    const controller = new AbortController();\n    searchAbortRef.current[field.name] = controller;\n\n    Promise.resolve(searchFn(field, search, popupContext))\n      .then((data) => {\n        if (controller.signal.aborted) return;\n        const raw = Array.isArray(data) ? data : (data?.items ?? data?.list ?? []);\n        setDynamicOptions((prev) => ({\n          ...prev,\n          [field.name]: raw.map((item) => normalizeOption(item, field)),\n        }));\n      })\n      .catch((err) => {\n        if (controller.signal.aborted) return;\n        console.error(`[DynamicPopup] Search failed for field \"${field.name}\":`, err);\n      });\n    return controller;\n  }, [api, popupContext, setDynamicOptions]);\n\n  // ── Open-time preload ───────────────────────────────────────────────────────\n  // The fields to preload, and the latest closure that can fetch them, are held\n  // in refs rather than passed as effect dependencies. DynamicPopupRoute builds\n  // its `api` prop as a fresh object literal on EVERY render, so `runSearch`'s\n  // identity changes every render; depending on it here would mean\n  // effect → setDynamicOptions → re-render → effect, an endless fetch loop.\n  // The effect therefore keys only on [open, preloadKey] — the popup opening,\n  // or the set of preloadable field names actually changing.\n  const preloadFields = fields.filter(\n    (field) => (field.searchFetchKey || field.searchFetcher) && field.preloadOptions !== false,\n  );\n  const preloadKey = preloadFields.map((field) => field.name).join('|');\n\n  const preloadRef = useRef({ runSearch, preloadFields });\n  // Kept fresh in an effect, not during render (refs must not be written while\n  // rendering). Effects run in declaration order, so this one has always\n  // updated the ref by the time the preload effect below reads it.\n  useEffect(() => {\n    preloadRef.current = { runSearch, preloadFields };\n  });\n\n  useEffect(() => {\n    if (!open || !preloadKey) return undefined;\n\n    const { runSearch: run, preloadFields: fieldsToLoad } = preloadRef.current;\n    const controllers = fieldsToLoad.map((field) => run(field, '')).filter(Boolean);\n\n    return () => controllers.forEach((controller) => controller.abort());\n  }, [open, preloadKey]);\n\n  /**\n   * Returns a debounced `onSearch` handler for a search-select field,\n   * or `undefined` if the field has no search fetch key.\n   * @param {Object} field\n   * @returns {Function|undefined}\n   */\n  function getSearchHandler(field) {\n    if (!field.searchFetchKey && !field.searchFetcher) return undefined;\n\n    const searchFn = api.searchOptions ?? api.searchFetcher;\n    if (typeof searchFn !== 'function') return undefined;\n\n    const minLength = field.searchMinLength ?? SEARCH_MIN_LENGTH;\n\n    return (search) => {\n      clearTimeout(searchTimerRef.current[field.name]);\n\n      // Below the minimum (including a cleared box) the field falls BACK to the\n      // recent list rather than blanking the dropdown, so there is always\n      // something to pick. Passing '' is what tells the fetcher \"recent, not\n      // filtered\" — the same call the preload above makes.\n      const term = search.length < minLength ? '' : search;\n\n      searchTimerRef.current[field.name] = setTimeout(() => {\n        runSearch(field, term);\n      }, SEARCH_DEBOUNCE_MS);\n    };\n  }\n\n  /**\n   * Returns an `onSearch` handler for a mention-textarea field,\n   * or `undefined` if no mention fetcher is configured.\n   * @param {Object} field\n   * @returns {Function|undefined}\n   */\n  function getMentionSearchHandler(field) {\n    const mentionFn = api.getMentionOptions ?? api.mentionFetcher;\n    if (typeof mentionFn !== 'function') return undefined;\n\n    return (search) => {\n      // Cancel the previous in-flight mention request for this field\n      mentionAbortRef.current[field.name]?.abort();\n      const controller = new AbortController();\n      mentionAbortRef.current[field.name] = controller;\n\n      Promise.resolve(mentionFn(field, search, popupContext))\n        .then((data) => {\n          if (controller.signal.aborted) return;\n          const raw = Array.isArray(data) ? data : (data?.items ?? data?.list ?? []);\n          setMentionOptions((prev) => ({\n            ...prev,\n            [field.name]: raw.map((item) => ({\n              value: item.user_name ?? item.userName ?? item.username ?? String(item),\n              label: item.user_name ?? item.userName ?? item.username ?? String(item),\n            })),\n          }));\n        })\n        .catch((err) => {\n          if (controller.signal.aborted) return;\n          console.error(`[DynamicPopup] Mention search failed for field \"${field.name}\":`, err);\n        });\n    };\n  }\n\n  return { mentionOptions, getSearchHandler, getMentionSearchHandler };\n}\n","import { useState } from 'react';\nimport { message } from 'antd';\n\n/**\n * Manages form submission, delete, and confirm-only flows for DynamicPopup.\n *\n * @param {Object} params\n * @param {Object} params.form - Ant Design form instance\n * @param {Object|null} params.config - Popup config\n * @param {Object} params.api - { submit?, deleteItems?, onOk? }\n * @param {Object} params.popupContext\n * @param {string[]} params.resolvedIds\n * @param {Object} params.dynamicOptions\n * @param {*} params.extraData\n * @param {string[]} params.removedIds\n * @param {boolean} [params.removalOnlySubmit] - the only change is a removal, so\n *   the required-field validation is skipped (see DynamicPopup)\n * @param {Array} params.fields\n * @param {Function} params.onClose\n * @param {Function} [params.onSubmit] - Fallback submit handler\n * @returns {{ handleOk: Function, confirming: boolean, deleteError: string|null, resetSubmitState: Function }}\n */\nexport function usePopupSubmit({\n  form,\n  config,\n  api,\n  popupContext,\n  resolvedIds,\n  dynamicOptions,\n  extraData,\n  removedIds,\n  removalOnlySubmit = false,\n  fields,\n  onClose,\n  onSubmit,\n}) {\n  const [confirming, setConfirming] = useState(false);\n  const [deleteError, setDeleteError] = useState(null);\n\n  async function runSubmit(values) {\n    const submitPayload = { resolvedIds, dynamicOptions, extraData, removedIds };\n    if (typeof api.submit === 'function') {\n      return api.submit(values, popupContext, submitPayload);\n    }\n    if (typeof onSubmit === 'function') {\n      return onSubmit(values, popupContext, submitPayload);\n    }\n  }\n\n  function handleOk() {\n    if (!config) return;\n\n    // No fields → delete mode, onOk shortcut, or plain close\n    if (!fields.length) {\n      if (config.mode === 'delete' && typeof api.deleteItems === 'function') {\n        setConfirming(true);\n        setDeleteError(null);\n        Promise.resolve(api.deleteItems(resolvedIds, popupContext))\n          .then(() => {\n            message.success(config.successMessage || 'Deleted successfully');\n            onClose({ success: true });\n          })\n          .catch((err) => {\n            const msg = err?.message || 'Delete failed. Please try again.';\n            setDeleteError(msg);\n            setConfirming(false);\n            message.error(msg);\n          });\n        return;\n      }\n\n      if (typeof api.onOk === 'function') {\n        setConfirming(true);\n        Promise.resolve(api.onOk(popupContext))\n          .then(() => onClose({ success: true }))\n          .catch((err) => {\n            const msg = err?.message || 'Failed. Please try again.';\n            message.error(msg);\n            setConfirming(false);\n          });\n        return;\n      }\n\n      if (typeof api.submit === 'function') {\n        setConfirming(true);\n        Promise.resolve(runSubmit({}))\n          .then((result) => {\n            if (result?.cancelled) return;\n            if (result?.navigated) return;\n            message.success(config.successMessage || 'Saved successfully');\n            onClose({ success: true });\n          })\n          .catch((err) => {\n            message.error(err?.message || 'Failed. Please try again.');\n          })\n          .finally(() => setConfirming(false));\n        return;\n      }\n\n      onClose();\n      return;\n    }\n\n    // Removal-only submit: the user took an already-assigned person OFF and\n    // added nobody, so the \"Assign to\" field is legitimately empty. Running\n    // validateFields here would reject on that required field and the removal\n    // could never be saved — the original bug. Opt-in per popup via\n    // config.allowRemovalOnlySubmit; every other popup still validates.\n    if (removalOnlySubmit) {\n      setConfirming(true);\n      Promise.resolve(runSubmit(form.getFieldsValue()))\n        .then((result) => {\n          if (result?.cancelled) return;\n          if (result?.navigated) return;\n          message.success(config.successMessage || 'Saved successfully');\n          onClose({ success: true });\n        })\n        .catch((err) => {\n          message.error(err?.message || 'Failed. Please try again.');\n        })\n        .finally(() => setConfirming(false));\n      return;\n    }\n\n    // Fields present → validate then submit\n    form\n      .validateFields()\n      .then(async (values) => {\n        setConfirming(true);\n        try {\n          const result = await runSubmit(values);\n          if (result?.cancelled) return;\n          if (result?.navigated) return;\n          message.success(config.successMessage || 'Saved successfully');\n          onClose({ success: true });\n        } catch (err) {\n          message.error(err?.message || 'Failed. Please try again.');\n        } finally {\n          setConfirming(false);\n        }\n      })\n      .catch(() => {\n        // validateFields rejects when validation fails — Ant Design displays inline field errors\n      });\n  }\n\n  /** Resets submit state; call this when the popup opens to clear any previous error. */\n  function resetSubmitState() {\n    setConfirming(false);\n    setDeleteError(null);\n  }\n\n  return { handleOk, confirming, deleteError, resetSubmitState };\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { Form, Modal } from 'antd';\nimport dayjs from 'dayjs';\nimport PopupHeader from './PopupHeader';\nimport PopupBody from './PopupBody';\nimport PopupFooter from './PopupFooter';\nimport PopupFields from './PopupFields';\nimport { usePopupOptions } from './hooks/usePopupOptions';\nimport { usePopupSearch } from './hooks/usePopupSearch';\nimport { usePopupSubmit } from './hooks/usePopupSubmit';\nimport { getDefaultContext } from './utils/popupUtils';\n\n/**\n * Config-driven modal popup for ATS/CRM/ERP bulk and single-record actions.\n *\n * @param {Object} props\n * @param {boolean} [props.open=true]\n * @param {Object} props.config - Popup configuration object (from popupConfigs.js or project-specific).\n * @param {Object} [props.context={}] - Runtime context: selectedIds, selectedRecords, moduleName, etc.\n * @param {Function} props.onClose - Called when the popup should close (navigate away / hide).\n * @param {Function} [props.onSubmit] - Fallback submit handler used when api.submit is absent.\n * @param {Object} [props.api={}] - API handlers: getOptions, searchOptions, getMentionOptions,\n *                                  loadExtraData, submit, deleteItems, onOk.\n */\nexport default function DynamicPopup({\n  open = true,\n  config,\n  context = {},\n  onClose,\n  onSubmit,\n  api = {},\n}) {\n  const [form] = Form.useForm();\n  const [formValues, setFormValues] = useState({});\n  const [removedIds, setRemovedIds] = useState([]);\n  // Use Ant Design's actual form store as the source of truth for required\n  // field/button state. onValuesChange is still retained for dependent option\n  // loading, but custom controls must not leave the confirm button dependent\n  // on a second, potentially stale state object.\n  const watchedFormValues = Form.useWatch([], form, { preserve: true }) ?? {};\n\n  const popupContext = useMemo(() => getDefaultContext(context), [context]);\n  const { selectedIds = [], selectedRecords = [], moduleName = '' } = popupContext;\n\n  const resolvedIds = useMemo(\n    () =>\n      selectedIds.map((id, i) => {\n        const record = selectedRecords[i];\n        return record?.id ?? record?._id ?? id;\n      }),\n    [selectedIds, selectedRecords],\n  );\n\n  const fields = useMemo(() => {\n    if (!config) return [];\n    return typeof config.getFields === 'function'\n      ? config.getFields(popupContext)\n      : (config.fields ?? []);\n  }, [config, popupContext]);\n\n  const initialValues = useMemo(() => {\n    const values = {};\n    fields.forEach((field) => {\n      const raw = popupContext[field.initialValueKey];\n      if (!field.initialValueKey || raw === undefined) return;\n      // A dayjs instance can't survive router navigation state (browsers\n      // structurally clone history state, stripping any custom prototype),\n      // so date-picker fields carry a plain ISO string through context and\n      // get converted back to dayjs here, right before the form uses it.\n      values[field.name] = field.type === 'date-picker' ? dayjs(raw) : raw;\n    });\n    return values;\n  }, [fields, popupContext]);\n\n  const { dynamicOptions, setDynamicOptions, extraData } = usePopupOptions({\n    open,\n    config,\n    api,\n    fields,\n    popupContext,\n    formValues,\n  });\n\n  const { mentionOptions, getSearchHandler, getMentionSearchHandler } = usePopupSearch({\n    api,\n    open,\n    // Needed for the open-time preload: every search-select is fetched once with\n    // an empty term so its dropdown opens on the most recent records.\n    fields,\n    popupContext,\n    setDynamicOptions,\n  });\n\n  // `result` is only ever a real value when usePopupSubmit calls this after a\n  // successful mutation ({ success: true }) — antd's Modal onCancel passes a\n  // DOM/React event as its first arg, which must never be forwarded as if it\n  // were a result, so the Cancel/X wiring below calls this with no argument.\n  function handleClose(result) {\n    if (typeof onClose === 'function') onClose(result);\n  }\n\n  const requiredFields = fields.filter((f) => f.required);\n  const allRequiredFilled = requiredFields.every((f) => {\n    const v = watchedFormValues[f.name];\n    if (v === undefined || v === null || v === '') return false;\n    if (Array.isArray(v) && v.length === 0) return false;\n    if (typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length === 0) return false;\n    return true;\n  });\n  // A pending REMOVAL is a change in its own right. `disabledUntilFilled` asks\n  // only \"are the required fields filled\", so on the Assign popup — whose one\n  // required field is \"Assign to\" — taking somebody OFF the job left the OK\n  // button disabled: there was no way to save a removal without also assigning\n  // a new person, and the removal was lost when the modal closed.\n  const seededRemovals = (popupContext.removedIds ?? []).length;\n  const hasPendingRemoval = removedIds.length > seededRemovals;\n  // \"Removed somebody and added nobody.\" Only then may the required fields be\n  // skipped — if the user DID start filling the add field it still has to\n  // validate, so a half-entered assignment can never be saved silently.\n  const anyRequiredFilled = requiredFields.some((f) => {\n    const v = watchedFormValues[f.name];\n    return !(v === undefined || v === null || v === '' || (Array.isArray(v) && v.length === 0));\n  });\n  const removalOnlySubmit = Boolean(config?.allowRemovalOnlySubmit)\n    && hasPendingRemoval && !anyRequiredFilled;\n\n  const { handleOk, confirming, deleteError, resetSubmitState } = usePopupSubmit({\n    form,\n    config,\n    api,\n    popupContext,\n    resolvedIds,\n    dynamicOptions,\n    extraData,\n    removedIds,\n    removalOnlySubmit,\n    fields,\n    onClose: handleClose,\n    onSubmit,\n  });\n\n  // Reset all local state each time the popup opens to avoid stale values.\n  // Seed formValues from initialValues (not {}) — antd's Form onValuesChange\n  // only fires on user interaction, so a field pre-filled via initialValueKey\n  // (e.g. \"Shortlisted\" locking hiringStage) would otherwise never count\n  // toward disabledUntilFilled/allRequiredFilled until the user touched it.\n  useEffect(() => {\n    if (!open) return;\n    form.resetFields();\n    setFormValues(initialValues ?? {});\n    setRemovedIds(popupContext.removedIds ?? []);\n    resetSubmitState();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, initialValues]);\n\n  // Some popups (Source Candidates' \"Shortlisted\"/\"Quick Submit\") already know\n  // everything they need from context (jobId, locked hiringStage) and resolve\n  // to zero fields — config.autoSubmitWhenNoFields skips the confirm dialog\n  // entirely and runs the action the instant the popup would have opened.\n  const shouldAutoSubmit = Boolean(config?.autoSubmitWhenNoFields) && fields.length === 0;\n  useEffect(() => {\n    if (!open || !shouldAutoSubmit) return;\n    handleOk();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [open, shouldAutoSubmit]);\n\n  const count = selectedIds.length;\n  const singularLabel = String(moduleName).replace(/s$/i, '');\n  const itemLabel = count === 1 ? singularLabel : moduleName;\n  const firstRecord = selectedRecords[0] ?? {};\n\n  const titleText = config?.getTitleText\n    ? config.getTitleText(count, itemLabel, firstRecord, popupContext)\n    : config?.title;\n\n  const itemTitle =\n    count === 1\n      ? firstRecord.jobTitle ??\n        firstRecord.title ??\n        firstRecord.name ??\n        firstRecord.fullName ??\n        firstRecord.candidateName ??\n        null\n      : null;\n\n  const bodyText = config?.getBodyText\n    ? config.getBodyText(count, singularLabel, itemLabel, itemTitle, popupContext)\n    : config?.bodyText ?? null;\n\n  const note =\n    typeof config?.getNote === 'function' ? config.getNote(popupContext) : config?.note;\n\n  const okDisabled = config?.disabledUntilFilled && !allRequiredFilled && !hasPendingRemoval;\n\n  if (!config || !open || shouldAutoSubmit) return null;\n\n  // Custom-body escape hatch: a popup definition can render a full React\n  // component instead of the field-form + OK/Cancel footer (e.g. the Manager\n  // Approve finance panel, which owns its own Approve/Reject actions). The\n  // component receives the resolved context + a close callback and is\n  // responsible for its own submit; the modal shows no default footer.\n  const CustomBody = config.component;\n  if (CustomBody) {\n    return (\n      <Modal\n        open={open}\n        title={config.title || config.getTitleText ? <PopupHeader titleText={titleText} titleIcon={config.titleIcon} /> : null}\n        footer={null}\n        width={config.width ?? 760}\n        centered\n        maskClosable={false}\n        onCancel={() => handleClose()}\n        className={`dynamic-popup${config.className ? ` ${config.className}` : ''}`}\n      >\n        <CustomBody\n          context={popupContext}\n          selectedIds={resolvedIds}\n          selectedRecords={selectedRecords}\n          moduleName={moduleName}\n          onClose={handleClose}\n        />\n      </Modal>\n    );\n  }\n\n  return (\n    <Modal\n      open={open}\n      title={<PopupHeader titleText={titleText} titleIcon={config.titleIcon} />}\n      okText={config.okText || 'OK'}\n      cancelText={config.cancelText ?? 'Cancel'}\n      onOk={handleOk}\n      onCancel={() => handleClose()}\n      okButtonProps={{ danger: config.okButtonDanger, disabled: okDisabled, loading: confirming }}\n      cancelButtonProps={{ disabled: confirming }}\n      closable={!confirming}\n      maskClosable={false}\n      width={config.width ?? 480}\n      centered\n      className={`dynamic-popup${config.className ? ` ${config.className}` : ''}`}\n    >\n      <PopupBody\n        note={note}\n        description={config.description}\n        showSelectedCount={config.showSelectedCount}\n        count={count}\n        itemLabel={itemLabel}\n        bodyText={bodyText}\n        deleteError={deleteError}\n      />\n      <PopupFooter footerNote={config.footerNote} />\n      <PopupFields\n        form={form}\n        fields={fields}\n        initialValues={initialValues}\n        dynamicOptions={dynamicOptions}\n        popupContext={popupContext}\n        extraData={extraData}\n        removedIds={removedIds}\n        setRemovedIds={setRemovedIds}\n        showAlreadyAssigned={config.showAlreadyAssigned}\n        onValuesChange={setFormValues}\n        getSearchHandler={getSearchHandler}\n        getMentionSearchHandler={getMentionSearchHandler}\n        mentionOptions={mentionOptions}\n      />\n    </Modal>\n  );\n}\n","export const config = {\n  mode: 'delete',\n  getTitleText: (count, itemLabel) => `Delete ${count > 0 ? `${count} ` : ''}${itemLabel}`,\n  titleIcon: 'delete',\n  okText: 'Delete',\n  okButtonDanger: true,\n  width: 420,\n  getBodyText: (count, singularLabel, itemLabel, itemTitle) =>\n    itemTitle\n      ? `Are you sure you want to delete the ${itemTitle} ${singularLabel}?`\n      : count > 1\n        ? `Are you sure you want to delete ${count} selected ${itemLabel}?`\n        : `Are you sure you want to delete this ${singularLabel}?`,\n  footerNote: 'This action cannot be undone.',\n  fields: [],\n};\n","import { deleteModuleRecords } from '../../../../services/popupApi';\n\nexport const api = {\n  deleteItems: async (ids, context) => {\n    await deleteModuleRecords(context.moduleName, ids);\n  },\n};\n","import { getFormGroups } from '../../services/addFormApi';\nimport { getDefaults } from '../../services/detailDefaults';\nimport { groupInProgressConfig, inProgressVerdict } from './educationRules';\n\n// =============================================================================\n// The in-progress gate, asked from OUTSIDE a form\n// -----------------------------------------------------------------------------\n// A region rule that only lives inside the submission form is a rule you meet\n// too late. Quick Submit picks a candidate, hands them to the submission form,\n// and the form prefills their education straight off the candidate record — so\n// a candidate the rule refuses gets all the way to a form that will not submit,\n// with nothing on screen explaining why and no way back except cancelling.\n//\n// This asks the same question at the point of selection. Deliberately using the\n// SAME resolver the form uses (educationRules.inProgressVerdict) against the\n// SAME config (the submission module's groups): a second implementation of\n// \"does this candidate have an unfinished qualification\" would drift, and the\n// drift shows up as a popup that lets someone through to a refusal.\n//\n// Nothing here names a module, a field or a region.\n// =============================================================================\n\n// The target module's groups are config, not data — identical for every\n// candidate checked in a session. Fetching them once per module keeps a\n// dropdown that checks each selection from making a config call per keystroke.\nconst groupsCache = new Map();\n\n/** Drops the cached config. Call after an admin saves Form Groups. */\nexport function clearInProgressGateCache() {\n  groupsCache.clear();\n}\n\nasync function targetGroups(module) {\n  if (!module) return [];\n  if (!groupsCache.has(module)) {\n    // The PROMISE is cached, not the result, so several selections racing at\n    // once share one request instead of firing several identical ones.\n    groupsCache.set(module, getFormGroups({ module }).catch((err) => {\n      // A config read that fails must not block a submit. Losing the gate is\n      // recoverable — the form still refuses at submit time — whereas refusing\n      // every candidate because a request timed out is not.\n      groupsCache.delete(module);\n      console.warn(`[in-progress gate] could not read ${module} form groups:`, err);\n      return [];\n    }));\n  }\n  return groupsCache.get(module);\n}\n\n/**\n * gateNeedsRecord — does this module restrict anything at all?\n *\n * Answered BEFORE the record is fetched, so a tenant whose region allows\n * everything (which is most of them) pays nothing: no candidate lookup, no\n * added latency on a dropdown.\n */\nexport function gateNeedsRecord(groups = [], region) {\n  return groups.some((group) => {\n    const cfg = groupInProgressConfig(group, region);\n    return cfg && cfg.severity !== 'allow';\n  });\n}\n\n/**\n * checkInProgress — may this record be put forward into `targetModule`?\n *\n *   targetModule  the module being submitted INTO (submissions), whose rules\n *                 decide. Never the source module — a candidate's own rules\n *                 are what allowed the row to exist in the first place.\n *   sourceModule  the module the record belongs to (candidates)\n *   recordId      that record's id\n *\n * Returns { severity: 'allow' | 'warn' | 'block', message, group }.\n * Always resolves — a failure anywhere returns 'allow', because the submission\n * form enforces this again and a gate that fails closed would make an outage\n * look like a policy.\n */\nexport async function checkInProgress({ targetModule, sourceModule, recordId, region } = {}) {\n  const allow = { severity: 'allow', message: '', group: null };\n  if (!targetModule || !sourceModule || !recordId) return allow;\n\n  const activeRegion = region ?? getDefaults().region;\n  try {\n    const groups = await targetGroups(targetModule);\n    if (!gateNeedsRecord(groups, activeRegion)) return allow;\n\n    // Only now is the record worth fetching. getFormGroups with an id embeds\n    // each repeatable group's stored rows, which is exactly what the verdict\n    // needs — and it is the same read the edit form uses, so the rows judged\n    // here are the rows that would be prefilled.\n    const sourceGroups = await getFormGroups({ module: sourceModule, id: recordId });\n    const record = {};\n    for (const group of sourceGroups) {\n      const key = group?.payloadKey || group?.name;\n      if (key && Array.isArray(group?.rows)) record[key] = group.rows;\n    }\n    return inProgressVerdict(groups, activeRegion, record);\n  } catch (err) {\n    console.warn('[in-progress gate] check skipped:', err);\n    return allow;\n  }\n}\n","import { getQuickSubmitCandidates } from '../../../../services/candidatesApi';\nimport { getJobList } from '../../../../services/dropdownApi';\nimport {\n  checkSubmissionExists,\n  checkSubmissionsExistBulk,\n  searchQuickSubmitJobs,\n  searchQuickSubmitCandidates,\n} from '../../../../services/popupApi';\nimport { relativeDateLabel } from '../../dynamic/utils/popupUtils';\nimport { matchRelevantSkills } from '../../../../services/skillMatchApi';\nimport { stashPendingPromise } from '../../../../services/pendingHandoff';\nimport { checkInProgress } from '../../../form/inProgressGate';\nimport { getModuleAutomations } from '../../../../services/adminApi';\n\nconst ALREADY_SUBMITTED_LABEL = 'Already submitted';\n\n// The two modules this popup moves a record BETWEEN. The gate below asks the\n// TARGET module's rules about the SOURCE module's record — a candidate's own\n// rules are what allowed the unfinished qualification to be recorded in the\n// first place, so asking them here would always say yes.\nconst GATE_TARGET_MODULE = 'submissions';\nconst GATE_SOURCE_MODULE = 'candidates';\nconst MS_PER_DAY = 24 * 60 * 60 * 1000;\nconst STALE_CANDIDATE_DAYS = 90;\nconst STALE_CANDIDATE_MESSAGE = 'This candidate was created or last updated more than 90 days ago. Only candidates created or updated within the last 90 days can be selected. Please update this candidate first.';\nconst CANDIDATE_CREATED_DATE_KEYS = ['createdAt', 'createdDate', 'dateCreated', 'created_on', 'createdOn'];\nconst CANDIDATE_UPDATED_DATE_KEYS = ['updatedAt', 'updatedDate', 'lastUpdatedAt', 'lastUpdatedDate', 'modifiedAt', 'modifiedDate'];\n\nfunction getCandidateDate(row, keys) {\n  for (const key of keys) {\n    const value = row?.[key];\n    if (!value) continue;\n    const parsed = new Date(value);\n    if (!Number.isNaN(parsed.getTime())) return parsed;\n  }\n  return null;\n}\n\nfunction getCandidateCreatedAt(row) {\n  return getCandidateDate(row, CANDIDATE_CREATED_DATE_KEYS);\n}\n\nfunction getCandidateUpdatedAt(row) {\n  return getCandidateDate(row, CANDIDATE_UPDATED_DATE_KEYS);\n}\n\nfunction fullDaysAgo(value) {\n  if (!(value instanceof Date) || Number.isNaN(value.getTime())) return null;\n  const startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n  return Math.max(0, Math.floor((startOfDay(new Date()) - startOfDay(value)) / MS_PER_DAY));\n}\n\nfunction getCreatedAgoTone(daysAgo) {\n  if (daysAgo === null) return '';\n  if (daysAgo <= 14) return 'green';\n  if (daysAgo <= 89) return 'yellow';\n  return 'red';\n}\n\nexport function isCandidateStale(row, days = STALE_CANDIDATE_DAYS) {\n  if (!row) return false;\n  const cutoff = Date.now() - days * MS_PER_DAY;\n  const createdAt = getCandidateCreatedAt(row);\n  const updatedAt = getCandidateUpdatedAt(row);\n  const createdFresh = createdAt && createdAt.getTime() >= cutoff;\n  const updatedFresh = updatedAt && updatedAt.getTime() >= cutoff;\n  return !createdFresh && !updatedFresh;\n}\n\nfunction getCreatedAgoParts(row) {\n  // The chip after the candidate's name is how OLD THE RECORD IS, so it reads\n  // from createdAt. It used to read updatedAt, which is why a candidate that\n  // had never been edited showed \"2025 years ago\" beside their name: the stored\n  // zero time was being aged like a real date. Freshness for SELECTION still\n  // considers both dates — see isCandidateStale, which is unchanged.\n  const createdAt = getCandidateCreatedAt(row);\n  if (!createdAt) return { createdAgo: '', createdAgoTone: '' };\n\n  // One shared ladder (days -> months -> years, placeholder-safe) so this chip\n  // and the Created/Updated meta lines can never word the same age differently.\n  const createdAgo = relativeDateLabel(createdAt);\n  if (!createdAgo) return { createdAgo: '', createdAgoTone: '' };\n\n  return { createdAgo, createdAgoTone: getCreatedAgoTone(fullDaysAgo(createdAt)) };\n}\n\nfunction withCreatedAgo(row) {\n  return {\n    ...row,\n    ...getCreatedAgoParts(row),\n    isStaleCandidate: isCandidateStale(row),\n  };\n}\n\nfunction candidateIdOf(row) {\n  return String(row?.applicantId ?? row?._id ?? row?.id ?? '');\n}\n\n// The edit route is CONFIG, never guessed. There is no derivable rule: this app\n// routes candidates at \"/candidate/edit/:id\" (SINGULAR) and clients at\n// \"/clients/edit/:id\" (plural). This function used to build the plural form,\n// which matches no route — so the catch-all redirected to the dashboard and the\n// candidate the user asked to update simply vanished.\n//\n// It reads the same modules.strategies.duplicateCheck.editRoute the Add form's\n// duplicate dialog uses, so there is ONE configured answer for \"where do I edit\n// a candidate\" rather than two that can disagree. Cached: it is config, and the\n// value is identical for every row in the list.\nlet candidateEditRoutePromise = null;\n\nasync function getCandidateEditRoute() {\n  if (!candidateEditRoutePromise) {\n    candidateEditRoutePromise = getModuleAutomations(GATE_SOURCE_MODULE)\n      .then((cfg) => cfg?.strategies?.duplicateCheck?.editRoute ?? '')\n      .catch(() => '');\n  }\n  return candidateEditRoutePromise;\n}\n\nasync function getCandidateEditPath(row) {\n  const candidateId = candidateIdOf(row);\n  if (!candidateId) return '';\n  const template = await getCandidateEditRoute();\n  if (!template) return '';\n  return template.replace(/:(_?id)\\b/g, encodeURIComponent(candidateId));\n}\n\nexport async function guardQuickSubmitCandidateSelection({ option, popupContext, confirm }) {\n  const row = option?._raw ?? option ?? {};\n  const candidateIdForGate = candidateIdOf(row);\n\n  // Region gate first, and reported HERE rather than only on submit: the user\n  // has just picked a person, and telling them now — while the list is still\n  // open and they can pick someone else — is the difference between a dead end\n  // and a choice. submit() checks again, because a guard is a courtesy and the\n  // popup can be driven without one.\n  if (candidateIdForGate) {\n    const gate = await checkInProgress({\n      targetModule: GATE_TARGET_MODULE,\n      sourceModule: GATE_SOURCE_MODULE,\n      recordId: candidateIdForGate,\n    });\n    if (gate.severity === 'block') {\n      return new Promise((resolve) => {\n        confirm({\n          title: 'This candidate cannot be submitted',\n          content: gate.message,\n          okText: 'Pick someone else',\n          cancelText: 'Close',\n          onOk: () => resolve(false),\n          onCancel: () => resolve(false),\n        });\n      });\n    }\n  }\n\n  if (!isCandidateStale(row)) return true;\n\n  const navigate = popupContext?.navigate;\n  const candidateId = candidateIdForGate;\n  if (!navigate || !candidateId) return false;\n\n  return new Promise((resolve) => {\n    confirm({\n      title: 'Candidate update required',\n      content: STALE_CANDIDATE_MESSAGE,\n      okText: 'OK',\n      cancelText: 'Cancel',\n      onOk: async () => {\n        // No configured route means we do NOT navigate. Closing the dialog and\n        // leaving the user where they are is recoverable; throwing them at a\n        // URL that matches nothing is not.\n        const path = await getCandidateEditPath(row);\n        if (path) navigate(path);\n        resolve(false);\n      },\n      onCancel: () => resolve(false),\n    });\n  });\n}\n\nfunction markSubmitted(option, submissionId, submittedAt) {\n  return {\n    ...option,\n    label: `${option.label} - ${ALREADY_SUBMITTED_LABEL}`,\n    disabled: true,\n    title: `${ALREADY_SUBMITTED_LABEL}${submissionId ? ` (submission ${submissionId})` : ''}`,\n    alreadySubmitted: true,\n    existingSubmissionId: submissionId || '',\n    ...(submittedAt ? { submittedAt } : {}),\n  };\n}\n\nexport const api = {\n  searchOptions: async (field, search, context) => {\n    if (field.searchFetchKey === 'quickSubmitJobList') {\n      const record = context.selectedRecords?.[0] ?? {};\n      const candidateId = record.id ?? record._id ?? context.selectedIds?.[0];\n\n      let list;\n      let flaggedByGateway = true;\n      try {\n        list = await searchQuickSubmitJobs({ searchQuery: search, candidateId });\n      } catch {\n        flaggedByGateway = false;\n        const response = await getJobList({ searchQuery: search, candidateId });\n        list = Array.isArray(response?.data) ? response.data : [];\n      }\n\n      const options = list.map((item) => ({\n        label:\n          [item.jobReferenceId ?? item.clientJobReferenceId, item.jobTitle].filter(Boolean).join(' - ')\n          || String(item._id ?? ''),\n        value: item._id ?? '',\n        _raw: item,\n      }));\n\n      if (flaggedByGateway) {\n        return options.map((opt) => {\n          if (opt._raw?.isSubmitted || opt._raw?.alreadySubmitted) {\n            return markSubmitted(\n              opt,\n              opt._raw?.jobSubmissionId || '',\n              opt._raw?.submittedAt || '',\n            );\n          }\n          if (opt._raw?.disable) {\n            const note = String(opt._raw?.message ?? '').trim();\n            return { ...opt, disabled: true, label: note ? `${opt.label} - ${note}` : opt.label, title: note };\n          }\n          return opt;\n        });\n      }\n\n      const submitted = await checkSubmissionsExistBulk({\n        applicantId: candidateId,\n        jobIds: options.map((opt) => opt.value),\n      }).catch(() => new Map());\n\n      return options.map((opt) => {\n        const hit = submitted.get(String(opt.value));\n        return hit ? markSubmitted(opt, hit.submissionId, hit.submittedAt) : opt;\n      });\n    }\n\n    if (field.searchFetchKey === 'quickSubmitCandidates') {\n      const record = context.selectedRecords?.[0] ?? {};\n      const jobId =\n        context.jobId ?? record.jobId ?? record.id ?? record._id ?? context.selectedIds?.[0];\n\n      let list;\n      let submitted = new Map();\n      try {\n        list = await searchQuickSubmitCandidates({ search, jobId });\n      } catch {\n        const rows = await getQuickSubmitCandidates({\n          isFromSubmission: context.isFromSubmission,\n          jobId,\n          submissionId: context.submissionId,\n          search,\n        });\n        list = Array.isArray(rows) ? rows : [];\n\n        submitted = await checkSubmissionsExistBulk({\n          jobId,\n          applicantIds: list.map(candidateIdOf),\n        }).catch(() => new Map());\n      }\n\n      return list\n        .map((row) => withCreatedAgo(row))\n        .map((row) => {\n          const hit = submitted.get(candidateIdOf(row));\n          const isSubmittedHere = Boolean(hit) || row?.isSubmitted === true || row?.alreadySubmitted === true;\n          if (!isSubmittedHere) return row;\n\n          const blockingId = hit?.submissionId || row?.jobSubmissionId || '';\n          const submittedAt = hit?.submittedAt || row?.submittedAt || '';\n          return {\n            ...row,\n            disabled: true,\n            optionNote: ALREADY_SUBMITTED_LABEL,\n            isSubmitted: true,\n            alreadySubmitted: true,\n            existingSubmissionId: blockingId,\n            ...(submittedAt ? { submittedAt } : {}),\n          };\n        });\n    }\n    return [];\n  },\n\n  submit: async (values, context, submitPayload) => {\n    const { navigate, selectedRecords = [], selectedIds = [], moduleName } = context;\n    const record = selectedRecords[0] ?? {};\n\n    let jobId;\n    let candidateId;\n    if (context.jobId) {\n      jobId = context.jobId;\n      candidateId = record.id ?? record._id ?? selectedIds[0] ?? '';\n    } else if (moduleName === 'candidate') {\n      jobId = values.jobId ?? '';\n      candidateId = record.id ?? record._id ?? selectedIds[0] ?? '';\n    } else {\n      jobId = record.jobId ?? record.id ?? record._id ?? selectedIds[0] ?? '';\n      candidateId = values.candidate ?? '';\n    }\n\n    const candidateOption = submitPayload?.dynamicOptions?.candidate\n      ?.find((opt) => candidateIdOf(opt?._raw) === String(candidateId));\n    const jobOption = submitPayload?.dynamicOptions?.jobId\n      ?.find((opt) => String(opt?.value) === String(jobId));\n    const preMarked = candidateOption?._raw?.isSubmitted\n      || candidateOption?._raw?.alreadySubmitted\n      || jobOption?.alreadySubmitted\n      || jobOption?._raw?.isSubmitted\n      || jobOption?._raw?.alreadySubmitted;\n\n    if (!jobId || !candidateId) {\n      throw new Error('Select both a job and a candidate to quick submit.');\n    }\n\n    if (isCandidateStale(candidateOption?._raw)) {\n      throw new Error(STALE_CANDIDATE_MESSAGE);\n    }\n\n    // The authoritative region gate. Every route into Quick Submit converges\n    // here — picking a job from a candidate, picking a candidate from a job,\n    // and the autoSubmitWhenNoFields path that opens no dialog at all — so this\n    // is the only place that can cover all three.\n    //\n    // Without it the flow was: the popup accepts the candidate, the submission\n    // form opens, prefills their education off the candidate record, and then\n    // refuses to submit. The user is left on a form that will not go through,\n    // for a reason nothing on screen explains.\n    const gate = await checkInProgress({\n      targetModule: GATE_TARGET_MODULE,\n      sourceModule: GATE_SOURCE_MODULE,\n      recordId: candidateId,\n    });\n    if (gate.severity === 'block') {\n      throw new Error(gate.message);\n    }\n\n    let exists = preMarked;\n    let blockingSubmissionId = candidateOption?._raw?.existingSubmissionId\n      || candidateOption?._raw?.jobSubmissionId\n      || jobOption?.existingSubmissionId\n      || jobOption?._raw?.jobSubmissionId\n      || '';\n    try {\n      const check = await checkSubmissionExists({ jobId, applicantId: candidateId });\n      exists = exists || !!check?.exists;\n      blockingSubmissionId = check?.submissionId || blockingSubmissionId;\n    } catch (err) {\n      throw new Error(\n        `Could not verify existing submissions (${err?.message ?? 'request failed'}). Please try again.`,\n        { cause: err },\n      );\n    }\n\n    if (exists) {\n      throw new Error(\n        `This candidate is already submitted for this job${blockingSubmissionId ? ` (submission ${blockingSubmissionId})` : ''}.`,\n      );\n    }\n\n    const params = new URLSearchParams();\n    if (candidateId) params.set('candidateId', candidateId);\n\n    const priorSubmissionId = candidateOption?.priorSubmissionId\n      || candidateOption?._raw?.submissionId\n      || jobOption?.priorSubmissionId\n      || jobOption?._raw?.submissionId\n      || '';\n\n    if (priorSubmissionId) {\n      params.set('submissionId', String(priorSubmissionId));\n      params.set('isFromSubmission', 'true');\n    } else {\n      params.set('isFromSubmission', 'false');\n    }\n\n    // Kick the relevant-skill match off HERE, at submit, and navigate without\n    // waiting for it. Both ids are known and validated at this point, so the\n    // request overlaps the form's own mount + prefill instead of adding its\n    // latency on top. The form receives the token and fills the rows when the\n    // promise settles; it never blocks on it, and matchRelevantSkills resolves\n    // to [] on any failure, so a slow or down AI service just means the\n    // recruiter fills Relevant Skills by hand exactly as today.\n    //\n    // The promise itself CANNOT ride in navigate's `state` — react-router\n    // writes it via history.pushState, which requires structured-cloneable\n    // data, and a Promise is not cloneable (this used to throw\n    // \"#<Promise> could not be cloned\" and abort the navigation outright).\n    // stashPendingPromise hands back a plain string token instead.\n    const relevantSkillsToken = stashPendingPromise(\n      matchRelevantSkills({ jobId, applicantId: candidateId }).catch(() => []),\n    );\n\n    navigate(`/submission-create/${jobId}?${params.toString()}`, {\n      state: { relevantSkillsToken },\n    });\n    return { navigated: true };\n  },\n};\n","import { guardQuickSubmitCandidateSelection } from './api';\n\nexport const config = {\n  title: 'Submit',\n  okText: 'Submit',\n  // Each dropdown row is two lines across three columns: identity, a dates\n  // rail (Created / Updated) and the status badge. 560 squeezed the identity\n  // column once the dates rail earned its own space; 640 lets a full name +\n  // designation + email sit beside both dates without truncating.\n  width: 640,\n  disabledUntilFilled: true,\n  // Source Candidates' \"Quick Submit\" row action already knows both the job\n  // (via popupState.jobId) and the candidate (the selected row) - nothing\n  // left to ask, so redirect straight to QuickSubmitForm instead of showing\n  // an empty confirm dialog (see quick-submit/api.js's submit()).\n  autoSubmitWhenNoFields: true,\n  getNote: (context) =>\n    context.moduleName === 'candidate'\n      ? 'Note: Select a job to submit this candidate.'\n      : 'Note: Select a candidate to submit for this job',\n  getFields: (context) =>\n    // Caller already knows the job (e.g. Source Candidates' row action passes\n    // { jobId } via searchActionContext) AND the candidate is the selected\n    // row - nothing left to ask.\n    context.jobId\n      ? []\n      : context.moduleName === 'candidate'\n      ? [\n          {\n            name: 'jobId',\n            label: 'Job list',\n            type: 'search-select',\n            required: true,\n            placeholder: 'Search Job ID / job name - or pick a recent job',\n            searchFetchKey: 'quickSubmitJobList',\n            optionLayout: {\n              id: '{jobReferenceId}',\n              title: '{jobTitle}',\n              subtitle: '{clientJobReferenceId}',\n              meta: [\n                { label: 'Created', key: 'createdAt', type: 'date' },\n                { label: 'Updated', key: 'updatedAt', type: 'relative' },\n              ],\n            },\n          },\n        ]\n      : [\n          {\n            name: 'candidate',\n            label: 'Candidate',\n            type: 'search-select',\n            required: true,\n            placeholder: 'Search candidate name / email - or pick a recent candidate',\n            optionsKey: 'candidateOptions',\n            searchFetchKey: 'quickSubmitCandidates',\n            labelTemplate: '{applicantRefrenceId} - {firstName} {lastName} - {createdAgo}',\n            valueKey: 'applicantId',\n            optionLayout: {\n              id: '{applicantRefrenceId}',\n              title: '{firstName} {lastName}',\n              titleAccent: {\n                key: 'createdAgo',\n                toneKey: 'createdAgoTone',\n                prefix: ' - ',\n              },\n              subtitle: '{designation} - {email}',\n              meta: [\n                { label: 'Created', key: 'createdAt', type: 'date' },\n                { label: 'Updated', key: 'updatedAt', type: 'relative' },\n              ],\n            },\n            onSelectGuard: guardQuickSubmitCandidateSelection,\n          },\n        ],\n};\n","export const config = {\n  title: 'Add Notes & Share',\n  okText: 'Save & Share',\n  width: 480,\n  fields: [\n    {\n      name: 'notes',\n      label: 'Notes',\n      type: 'mention-textarea',\n      required: true,\n      rows: 5,\n      // Enforced by the browser AND re-checked at submit (see MentionField and\n      // securityValidationRule, which reads this same key) so a pasted value\n      // cannot slip past the input cap. Script/HTML/SQL content is rejected by\n      // that shared rule too — one engine, same rules as every form field.\n      maxLength: 2000,\n      placeholder: \"Add your notes on the job. Use '@' to mention someone.\",\n      mentionFetchKey: 'mentionUsers',\n    },\n  ],\n};\n","import { fetchJsonWithAuth } from './dropdownApi';\nimport { AUTH_URL } from './apiConfig';\n\n/* Activity + Notes for the detail view's right-rail card. Both hit the\n   authapi/v1 service and unwrap the { status, data } envelope. */\n\nconst unwrap = (json) => json?.data ?? json;\n\n// GET /module-activity?module={module}&id={id} → a record's activity entries,\n// newest first. One common endpoint for every module (jobs/candidates/…).\nexport async function getActivity(module, id) {\n  if (!module || !id) return [];\n  const params = new URLSearchParams({ module, id: String(id) });\n  const json = await fetchJsonWithAuth(AUTH_URL, `/module-activity?${params.toString()}`);\n  const data = unwrap(json);\n  return Array.isArray(data) ? data : [];\n}\n\n// GET /notes?relatedId={id} → notes attached to a record, newest first.\nexport async function getNotes(relatedId) {\n  if (!relatedId) return [];\n  const json = await fetchJsonWithAuth(AUTH_URL, `/notes?relatedId=${encodeURIComponent(relatedId)}`);\n  const data = unwrap(json);\n  return Array.isArray(data) ? data : [];\n}\n\n// POST /notes → add a note against a related record. `notesFor` is the module\n// (e.g. \"job\") — it tags the note and lets the backend log the matching\n// activity entry on the right record.\nexport async function createNote({ relatedId, notes, title, notesFor }) {\n  const json = await fetchJsonWithAuth(AUTH_URL, '/notes', {\n    method: 'POST',\n    body: JSON.stringify({ relatedId, notes, title, notesFor }),\n  });\n  return unwrap(json);\n}\n","import { getMentionUsers } from '../../../../services/popupApi';\nimport { createNote } from '../../../../services/notesApi';\n\nexport const api = {\n  getMentionOptions: async (_field, search) => getMentionUsers(search),\n  submit: async (values, context) => {\n    const relatedId = Array.isArray(context.selectedIds)\n      ? context.selectedIds[0]\n      : context.selectedIds;\n\n    if (!relatedId) throw new Error('Please select a record before adding a note.');\n\n    await createNote({\n      relatedId: String(relatedId),\n      notes: values.notes,\n      notesFor: context.moduleName,\n    });\n  },\n};\n","const JOB_FIELD = {\n  name: 'jobId',\n  label: 'Job Title / ID',\n  type: 'search-select',\n  multiple: true,\n  required: true,\n  placeholder: 'Minimum 3 characters',\n  searchFetchKey: 'tagToJobJobList',\n  valueKey: '_id',\n  labelTemplate: '{jobReferenceId} - {jobTitle}',\n};\n\nconst HIRING_STAGE_FIELD = {\n  name: 'hiringStage',\n  label: 'Hiring stage',\n  type: 'select',\n  required: true,\n  // Options come from the admin-configured action's Popup Context JSON\n  // (e.g. {\"hiringStageOptions\": [{\"label\":\"Shortlisted\",\"value\":\"goodfited\"},\n  // {\"label\":\"Pipeline\",\"value\":\"pipeline\"}]} — see RowActionsSection.jsx),\n  // via the same generic optionsKey/defaultOptions mechanism every other\n  // static-options popup field already uses (resolveOptions in popupUtils.js).\n  // defaultOptions is the fallback when no action has configured its own.\n  optionsKey: 'hiringStageOptions',\n  defaultOptions: [\n    { label: 'Shortlisted', value: 'shortlisted' },\n    { label: 'Pipeline', value: 'pipeline' },\n  ],\n  // Lets an admin-configured action (e.g. \"Shortlisted\") reuse this same\n  // popup pre-filled via its Popup Context JSON — e.g. {\"hiringStage\":\n  // \"goodfited\"} — instead of duplicating the Tag to Job flow.\n  initialValueKey: 'hiringStage',\n};\n\nexport const config = {\n  title: 'Tag to Job',\n  okText: 'Tag',\n  width: 480,\n  disabledUntilFilled: true,\n  // When the caller already knows both the job AND the hiring stage (e.g.\n  // Source Candidates' \"Shortlisted\" action, which locks hiringStage via\n  // popupState), there's nothing left to ask — auto-submit instead of\n  // showing an empty confirm dialog. \"Tag to Jobs\" only locks jobId, so it\n  // still shows the (now single-field) hiring-stage picker.\n  autoSubmitWhenNoFields: true,\n  // The job field is only shown when the caller doesn't already know the\n  // job — e.g. Source Candidates' \"Shortlisted\"/\"Tag to Jobs\" actions pass\n  // the currently open job via popupState.jobId (see ListView's\n  // action.popupState -> location.state.popupContext -> here), so the admin\n  // never has to re-search a job they're already looking at candidates for.\n  getFields: (context) => {\n    if (context.jobId && context.hiringStage) return [];\n    return context.jobId ? [HIRING_STAGE_FIELD] : [JOB_FIELD, HIRING_STAGE_FIELD];\n  },\n};\n","import { fetchJsonWithAuth } from \"./authApi\";\nimport { AUTH_URL, JOBS_URL } from \"./apiConfig\";\n\nconst unwrap = (json) => json?.data ?? json;\n\n/**\n * Converts a backend \"KV array\" candidate — [{Key, Value}, {Key, Value}, ...] —\n * into a normal flat object { Key: Value, ... }.\n */\nfunction flattenKvItem(item) {\n  if (Array.isArray(item) && item.every(p => p && typeof p === 'object' && 'Key' in p)) {\n    return item.reduce((acc, { Key, Value }) => {\n      acc[Key] = Value;\n      return acc;\n    }, {});\n  }\n  return item;\n}\n\nexport function extractStageCandidates(stage) {\n  if (!stage) return [];\n  if (Array.isArray(stage.data)) return stage.data.map(flattenKvItem);\n  if (stage.stage && Array.isArray(stage.stage.data)) return stage.stage.data.map(flattenKvItem);\n  if (Array.isArray(stage)) return stage.map(flattenKvItem);\n  return [];\n}\n\nexport async function getWorkflowByEntity(entityId) {\n  try {\n    const json = await fetchJsonWithAuth(\n      AUTH_URL,\n      `/workflow/entity/${entityId}?workflowType=HiringPipeline`\n    );\n    const data = unwrap(json);\n    return data ?? null;\n  } catch (error) {\n    if (error?.status === 404 || error?.message?.includes('404')) {\n      return null;\n    }\n    throw error;\n  }\n}\n\n/**\n * GET /workflow/list/all — workflows across ALL modules for the logged-in\n * user (no module param; tenant/business scoping comes from the JWT).\n * Server-paginated: page starts at 1, limit max 100.\n * Returns { items, total, page, limit } — items is the slim workflow list\n * (_id, module, workflowType, entityType, entityId, currentStage, totalCount,\n * stages [stageId/stageName/sequence/count], timestamps).\n */\nexport async function getAllWorkflows(page = 1, limit = 10) {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    `/workflow/list/all?page=${page}&limit=${limit}`\n  );\n  const data = unwrap(json);\n  const items = Array.isArray(data) ? data : data?.data ?? [];\n  const total = Number(json?.total ?? data?.total) || items.length;\n  return { items, total, page, limit };\n}\n\n/**\n * GET /workflow/list?module=Jobs&page=1&limit=10 — ONE server-paginated page\n * of workflows for a single module (page starts at 1, limit max 100; the\n * module name must match the workflow documents exactly, e.g. \"Jobs\" not\n * \"job\"). This is the primary (driver) source for the server-paginated\n * merged Jobs list — never fetch the full set for that path.\n * Returns { items, total, page, limit }.\n */\nexport async function getWorkflowsByModule(module, page = 1, limit = 10) {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    `/workflow/list?module=${encodeURIComponent(module)}&page=${page}&limit=${limit}`\n  );\n  const data = unwrap(json);\n  const items = Array.isArray(data) ? data : data?.data ?? [];\n  const total = Number(json?.total ?? data?.total) || items.length;\n  return { items, total, page, limit };\n}\n\n/**\n * Fetches every page of /workflow/list/all and returns the full set —\n * the shape the merge engine needs for its primary (driver) source.\n * DEPRECATED for list rendering: use getWorkflowsByModule (server-paginated)\n * via createAllWorkflowsListFetcher instead of fetching the whole collection.\n */\nexport async function getAllWorkflowsComplete(config = 10) {\n  const normalizedConfig = typeof config === 'number'\n    ? { limit: config }\n    : (config && typeof config === 'object' ? config : {});\n\n  const page = Math.max(1, Number(normalizedConfig.page) || 1);\n  const limit = Math.max(1, Number(normalizedConfig.limit ?? normalizedConfig.pageSize) || 10);\n\n  return getAllWorkflows(page, limit);\n}\n\nexport async function getWorkflowById(workflowId) {\n  const json = await fetchJsonWithAuth(AUTH_URL, `/workflow/${workflowId}`);\n  return unwrap(json);\n}\n\nexport async function getWorkflowStage(workflowId, stageName) {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    `/workflow/${workflowId}/stage/${stageName}`\n  );\n  let result = unwrap(json);\n  if (Array.isArray(result)) {\n    return { data: result };\n  }\n  return result;\n}\n\n/**\n * Get a single module record by id via the /module-data-list gateway\n * (same endpoint used to list Jobs), filtered down to one id.\n * Used as the per-id fallback in the merged-list fetchers.\n *\n * The id is sent through the `filters` mechanism (an `_id in [id]`\n * FilterCondition) — the backend does not read a bare `id` query param, so\n * the old `&id=` form silently returned the module's first record.\n * scope=allJobs widens the job scope so records outside \"My Jobs\" still\n * resolve; non-job modules ignore the scope param entirely.\n */\nexport async function getModuleRecordById(moduleName, id) {\n  if (!moduleName || !id) return null;\n\n  try {\n    const params = new URLSearchParams({\n      module: moduleName,\n      limit: '1',\n      offset: '0',\n      scope: 'allJobs',\n      filters: JSON.stringify([{ field: '_id', op: 'in', values: [String(id)], operator: 'and' }]),\n    });\n    const json = await fetchJsonWithAuth(AUTH_URL, `/module-data-list?${params}`);\n    const data = unwrap(json);\n\n    if (Array.isArray(data)) return data[0] ?? null;\n    if (data?.data && Array.isArray(data.data)) return data.data[0] ?? null;\n    const items = data?.rows ?? data?.records ?? data?.items ?? data?.list;\n    if (Array.isArray(items)) return items[0] ?? null;\n    return data ?? null;\n  } catch (err) {\n    console.error(`[getModuleRecordById] failed: ${moduleName}/${id}`, err);\n    return null;\n  }\n}\n\n/**\n * Get a single candidate's full profile by reference ID.\n */\nexport async function getCandidateByReferenceId(referenceId) {\n  return getModuleRecordById(\"candidate\", referenceId);\n}\n\n/**\n * Get a single submission's full record by submission ID.\n * Submission-level fields (pay rate, job, internal/client status, submitted by)\n * live on the submissions collection — NOT on the candidate record — so this\n * is a separate call from getCandidateByReferenceId.\n */\nexport async function getSubmissionById(submissionId) {\n  return getModuleRecordById(\"submissions\", submissionId);\n}\n\nexport async function createWorkflow(payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, \"/workflow/create\", {\n    method: \"POST\",\n    body: JSON.stringify(payload),\n  });\n  return unwrap(json);\n}\n\nexport async function createWorkflowInstance(payload) {\n  const json = await fetchJsonWithAuth(JOBS_URL, \"/source/workflow-instance\", {\n    method: \"POST\",\n    body: JSON.stringify(payload),\n  });\n  return unwrap(json);\n}\n\nexport async function updateWorkflowStage(workflowId, payload) {\n  const json = await fetchJsonWithAuth(AUTH_URL, `/workflow/${workflowId}/stage`, {\n    method: \"PUT\",\n    body: JSON.stringify(payload),\n  });\n  return unwrap(json);\n}\n\nexport async function getWorkflowDashboard(module) {\n  const json = await fetchJsonWithAuth(\n    AUTH_URL,\n    `/workflow/dashboard?module=${module}&workflowType=HiringPipeline`\n  );\n  return unwrap(json);\n}\n\n// The admin-configurable list of hiring-pipeline stage names (Pipeline,\n// Shortlisted, Submitted, …), aggregated live across every job's workflow —\n// the DB source of truth for stage values shown in Tag to Jobs / resolved by\n// the Shortlist action, instead of a hardcoded options list.\nexport async function getHiringStageOptions() {\n  const dashboard = await getWorkflowDashboard('job');\n  const stages = dashboard?.stages ?? dashboard?.Stages ?? [];\n  return stages\n    .map((stage) => stage?.stageName ?? stage?.StageName)\n    .filter(Boolean)\n    .map((stageName) => ({ label: stageName, value: stageName }));\n}\n\n// Resolves the DB-configured stage option matching \"shortlisted\" (case\n// insensitive) — never hardcode the raw string where this value is consumed.\nexport async function getShortlistedStageValue() {\n  const options = await getHiringStageOptions();\n  const match = options.find((option) => option.value.trim().toLowerCase() === 'shortlisted');\n  return match?.value ?? null;\n}\n\nexport async function deleteWorkflow(workflowId) {\n  const json = await fetchJsonWithAuth(AUTH_URL, `/workflow/${workflowId}`, {\n    method: \"DELETE\",\n  });\n  return unwrap(json);\n}\n","import {\n  checkSubmissionsExistBulk,\n  searchJobs,\n  searchQuickSubmitJobs,\n  tagCandidatesToJob,\n} from '../../../../services/popupApi';\nimport { openFormDecision, openFormNotice } from '../../../form/formDecisionDialog';\nimport { createWorkflowInstance } from '../../../../services/workflowApi';\n\nconst STAGE_ID_BY_KEY = {\n  pipeline: 'pipeline',\n  goodfited: 'goodfited',\n  contacted: 'contacted',\n  submitted: 'submitted',\n  shortlisted: 'shortlisted',\n  interviewinprogress: 'interviewInprogress',\n  selected: 'selected',\n};\nconst ALREADY_SUBMITTED_LABEL = 'Already submitted';\n\nfunction pickValue(record, ...paths) {\n  for (const path of paths) {\n    const value = String(path).split('.').reduce((current, part) => current?.[part], record);\n    if (value !== undefined && value !== null && value !== '') return value;\n  }\n  return undefined;\n}\n\nfunction normalizeStageId(stage) {\n  const raw = String(stage ?? '').trim();\n  if (!raw) return '';\n  return STAGE_ID_BY_KEY[raw.toLowerCase()] ?? raw;\n}\n\nfunction candidateIdOf(record, fallbackCandidateId = '') {\n  return String(\n    pickValue(\n      record,\n      'candidateId',\n      'candidate_id',\n      'applicantId',\n      'applicantID',\n      'applicantReferenceId',\n      'applicantRefrenceId',\n      '_id',\n      'id',\n    ) ?? fallbackCandidateId ?? '',\n  );\n}\n\nfunction workflowCandidateIdOf(record) {\n  return String(\n    pickValue(\n      record,\n      '_id',\n      'id',\n      'candidateId',\n      'candidate_id',\n      'applicantId',\n      'applicantID',\n    ) ?? '',\n  );\n}\n\nfunction markSubmitted(option, submissionId, submittedAt) {\n  const jobTitle = String(option.jobTitle ?? '').trim();\n  return {\n    ...option,\n    jobTitle: jobTitle ? `${jobTitle} (${ALREADY_SUBMITTED_LABEL})` : `(${ALREADY_SUBMITTED_LABEL})`,\n    disabled: true,\n    title: ALREADY_SUBMITTED_LABEL,\n    alreadySubmitted: true,\n    existingSubmissionId: submissionId || '',\n    ...(submittedAt ? { submittedAt } : {}),\n  };\n}\n\nfunction formatBlockedLabel(label, note) {\n  const status = String(note ?? '').trim();\n  if (!status) return label;\n  if (/already submitted/i.test(status)) return `${label} (${ALREADY_SUBMITTED_LABEL})`;\n  if (/fulfilled/i.test(status)) return `${label} (Fullfilled)`;\n  return `${label} (${status})`;\n}\n\nfunction normalizeJobRow(item) {\n  const jobReferenceId = String(item.jobReferenceId ?? item.clientJobReferenceId ?? '').trim();\n  const jobTitle = String(item.jobTitle ?? '').trim();\n  return {\n    ...item,\n    jobReferenceId,\n    jobTitle,\n  };\n}\n\nfunction selectedCandidateIds(context) {\n  return selectedCandidates(context).map((candidate) => candidate.id);\n}\n\nfunction candidateNameOf(record, fallbackCandidateId = '') {\n  return (\n    pickValue(record, 'candidateName', 'candidate_name', 'fullName', 'name')\n    ?? [pickValue(record, 'firstName', 'first_name'), pickValue(record, 'lastName', 'last_name')]\n      .filter(Boolean)\n      .join(' ')\n    ?? fallbackCandidateId\n  ) || 'Unknown candidate';\n}\n\nfunction selectedCandidates(context) {\n  const selectedIds = Array.isArray(context?.selectedIds) ? context.selectedIds : [];\n  const selectedRecords = Array.isArray(context?.selectedRecords) ? context.selectedRecords : [];\n  const candidates = [];\n  const seen = new Set();\n  const total = Math.max(selectedIds.length, selectedRecords.length);\n\n  for (let index = 0; index < total; index += 1) {\n    const record = selectedRecords[index] ?? {};\n    const fallbackCandidateId = selectedIds[index] ? String(selectedIds[index]) : '';\n    const candidateId = candidateIdOf(record, fallbackCandidateId);\n    if (!candidateId || seen.has(candidateId)) continue;\n    seen.add(candidateId);\n    candidates.push({\n      id: candidateId,\n      name: candidateNameOf(record, fallbackCandidateId),\n      record,\n      selectedId: fallbackCandidateId || candidateId,\n    });\n  }\n\n  return candidates;\n}\n\nfunction selectedJobIdsOf(values, context) {\n  if (Array.isArray(values?.jobId)) return values.jobId.map(String).filter(Boolean);\n  if (values?.jobId) return [String(values.jobId)];\n  if (Array.isArray(context?.jobId)) return context.jobId.map(String).filter(Boolean);\n  if (context?.jobId) return [String(context.jobId)];\n  return [];\n}\n\nfunction extractJobTitle(job, fallbackJobId = '') {\n  const directTitle = String(\n    job?.jobTitle\n    ?? job?._raw?.jobTitle\n    ?? '',\n  ).trim();\n  if (directTitle) return directTitle;\n\n  const label = String(job?.label ?? job?._raw?.label ?? '').trim();\n  if (label.includes(' - ')) return label.split(' - ').slice(1).join(' - ').trim();\n  return label || String(fallbackJobId ?? '');\n}\n\nfunction jobLabelOf(job, fallbackJobId = '') {\n  return extractJobTitle(job, fallbackJobId);\n}\n\nfunction selectedJobs(values, context, submitPayload) {\n  const selectedJobIds = [...new Set(selectedJobIdsOf(values, context))];\n  const jobOptions = Array.isArray(submitPayload?.dynamicOptions?.jobId) ? submitPayload.dynamicOptions.jobId : [];\n  const optionsById = new Map(jobOptions.map((option) => [String(option?._id ?? option?.value ?? ''), option]));\n\n  return selectedJobIds.map((jobId) => {\n    const job = optionsById.get(String(jobId)) ?? {};\n    return {\n      id: String(jobId),\n      label: jobLabelOf(job, jobId),\n      record: job,\n    };\n  });\n}\n\nfunction summarizeBlockedJobs(plans) {\n  return plans\n    .filter((plan) => plan.blockedCandidates.length > 0)\n    .map((plan) => `${plan.job.label} - ${plan.blockedCandidates.map((candidate) => candidate.name).join(', ')}`)\n    .join(' | ');\n}\n\nfunction summarizeAllowedJobs(plans) {\n  return plans\n    .filter((plan) => plan.allowedCandidates.length > 0)\n    .map((plan) => `${plan.job.label} - ${plan.allowedCandidates.map((candidate) => candidate.name).join(', ')}`)\n    .join(' | ');\n}\n\nfunction buildCandidateDetails(record, fallbackCandidateId) {\n  const candidateId = workflowCandidateIdOf(record);\n\n  if (!candidateId) return null;\n\n  const candidateName = candidateNameOf(record, fallbackCandidateId) || undefined;\n\n  const candidateDetails = {\n    candidateId: String(candidateId),\n    candidateName,\n    phone: pickValue(record, 'phone', 'phoneNumber', 'phone_number', 'mobile', 'mobileNumber', 'mobile_number'),\n    source: pickValue(record, 'source', 'sourceType', 'candidateSource', 'profileSource'),\n    submittedAt: pickValue(record, 'submittedAt', 'lastSubmittedAt', 'updatedAt'),\n    remarks: pickValue(record, 'remarks', 'comment', 'comments', 'notes'),\n    assignedRecruiter: pickValue(record, 'assignedRecruiter', 'recruiterName', 'ownerName', 'assignedToName'),\n    screeningStatus: pickValue(record, 'screeningStatus', 'screening.status', 'screeningResult'),\n    screeningScore: pickValue(record, 'screeningScore', 'screening.score', 'score'),\n    assignedDate: pickValue(record, 'assignedDate', 'assignedAt', 'createdAt'),\n  };\n\n  return Object.fromEntries(Object.entries(candidateDetails).filter(([, value]) => value !== undefined && value !== null && value !== ''));\n}\n\nexport const api = {\n  searchOptions: async (field, search, context) => {\n    if (field.searchFetchKey === 'tagToJobJobList') {\n      const candidateIds = selectedCandidateIds(context);\n      const candidateId = candidateIds.length === 1 ? candidateIds[0] : '';\n\n      let list;\n      let flaggedByGateway = false;\n      if (candidateId) {\n        try {\n          list = await searchQuickSubmitJobs({ searchQuery: search, candidateId });\n          flaggedByGateway = true;\n        } catch {\n          flaggedByGateway = false;\n        }\n      }\n\n      if (!Array.isArray(list)) list = await searchJobs(search);\n\n      const options = list.map(normalizeJobRow);\n      if (flaggedByGateway) {\n        return options.map((opt) => {\n          if (opt?.isSubmitted || opt?.alreadySubmitted) {\n            return markSubmitted(\n              opt,\n              opt?.jobSubmissionId || opt?.submissionId || '',\n              opt?.submittedAt || '',\n            );\n          }\n          if (opt?.disable) {\n            const note = String(opt?.message ?? '').trim();\n            return {\n              ...opt,\n              jobTitle: opt.jobTitle ? formatBlockedLabel(opt.jobTitle, note) : `(${note})`,\n              disabled: true,\n              optionNote: note,\n              title: note,\n            };\n          }\n          return opt;\n        });\n      }\n\n      if (!candidateId) return options;\n\n      const submitted = await checkSubmissionsExistBulk({\n        applicantId: candidateId,\n        jobIds: options.map((opt) => opt._id).filter(Boolean),\n      }).catch(() => new Map());\n\n      return options.map((opt) => {\n        const hit = submitted.get(String(opt._id));\n        return hit ? markSubmitted(opt, hit.submissionId, hit.submittedAt) : opt;\n      });\n    }\n    return [];\n  },\n  submit: async (values, context, submitPayload) => {\n    const selectedHiringStage = normalizeStageId(values.hiringStage ?? context.hiringStage);\n    const candidates = selectedCandidates(context);\n    const jobs = selectedJobs(values, context, submitPayload);\n    if (!jobs.length || !candidates.length) return { cancelled: true };\n\n    const plans = [];\n    for (const job of jobs) {\n      const duplicateMap = await checkSubmissionsExistBulk({\n        jobId: job.id,\n        applicantIds: candidates.map((candidate) => candidate.id),\n      }).catch(() => new Map());\n\n      plans.push({\n        job,\n        blockedCandidates: candidates.filter((candidate) => duplicateMap.has(String(candidate.id))),\n        allowedCandidates: candidates.filter((candidate) => !duplicateMap.has(String(candidate.id))),\n      });\n    }\n\n    const blockedSummary = summarizeBlockedJobs(plans);\n    const allowedSummary = summarizeAllowedJobs(plans);\n    const executablePlans = plans.filter((plan) => plan.allowedCandidates.length > 0);\n\n    if (!executablePlans.length) {\n      await openFormNotice({\n        tone: 'duplicate',\n        title: 'Selected candidates are already submitted',\n        body: 'Every selected candidate is already submitted to the selected jobs. Choose different jobs to continue.',\n        facts: [\n          { label: 'Blocked combinations', value: blockedSummary },\n        ],\n        okText: 'Close',\n      });\n      return { cancelled: true };\n    }\n\n    if (plans.some((plan) => plan.blockedCandidates.length > 0)) {\n      const proceed = await openFormDecision({\n        tone: 'duplicate',\n        title: 'Some candidate-job combinations are already submitted',\n        body: 'Those combinations will be skipped. Continue tagging the remaining valid combinations?',\n        facts: [\n          { label: 'Will be skipped', value: blockedSummary },\n          { label: 'Will be tagged', value: allowedSummary },\n        ],\n        okText: 'Tag remaining',\n        cancelText: 'Cancel',\n        footnote: 'Already submitted combinations will be left unchanged.',\n      });\n      if (!proceed) return { cancelled: true };\n    }\n\n    for (const plan of executablePlans) {\n      for (const candidate of plan.allowedCandidates) {\n        const candidateDetails = buildCandidateDetails(candidate.record ?? {}, candidate.selectedId);\n        await createWorkflowInstance({\n          jobId: plan.job.id,\n          module: 'jobs',\n          currentStage: selectedHiringStage,\n          ...(candidateDetails ? { candidateDetails } : {}),\n        });\n      }\n\n      await tagCandidatesToJob({\n        jobId: plan.job.id,\n        candidateIds: plan.allowedCandidates.map((candidate) => candidate.selectedId || candidate.id),\n        hiringStage: selectedHiringStage,\n      });\n    }\n  },\n};\n","export const config = {\n  title: 'Change Status',\n  okText: 'Apply',\n  width: 420,\n  showSelectedCount: true,\n  fields: [\n    {\n      name: 'status',\n      label: 'New Status',\n      type: 'select',\n      required: true,\n      placeholder: 'Select a status',\n      dataSource: 'master',\n      masterName: 'clientSubmissions',\n      labelKey: 'name',\n      valueKey: 'name',\n      initialValueKey: 'currentStatus',\n      defaultOptions: [\n        { label: 'Active', value: 'active' },\n        { label: 'Inactive', value: 'inactive' },\n        { label: 'Pending', value: 'pending' },\n        { label: 'Closed', value: 'closed' },\n      ],\n    },\n  ],\n};\n","import { changeModuleStatus } from '../../../../services/popupApi';\n\nfunction findSelectedStatusOption(status, dynamicOptions) {\n  const expected = String(status ?? '').trim().toLowerCase();\n  const options = Array.isArray(dynamicOptions?.status) ? dynamicOptions.status : [];\n  return options.find((option) => (\n    String(option?.value ?? '').trim().toLowerCase() === expected\n    || String(option?.label ?? '').trim().toLowerCase() === expected\n    || String(option?._raw?.name ?? '').trim().toLowerCase() === expected\n  )) ?? null;\n}\n\nexport const api = {\n  submit: async (values, context, submitPayload) => {\n    const selectedOption = findSelectedStatusOption(values.status, submitPayload?.dynamicOptions);\n    const raw = selectedOption?._raw ?? {};\n\n    const status = {\n      clientSubmissionStatusText: String(raw.name ?? selectedOption?.label ?? values.status ?? '').trim(),\n      clientSubmissionStatusId: Number(raw.id ?? raw.uniqueId ?? 0) || 0,\n      clientSubmissionStatusType: String(raw.type ?? '').trim(),\n    };\n\n    await changeModuleStatus(context.moduleName, context.selectedIds, status);\n  },\n};\n","export const config = {\n  getTitleText: (count) => `Remove ${count > 1 ? `${count} Candidates` : 'Candidate'} from Shortlist`,\n  titleIcon: 'delete',\n  okText: 'Remove',\n  okButtonDanger: true,\n  width: 420,\n  getBodyText: (count) =>\n    count > 1\n      ? `Are you sure you want to remove ${count} selected candidates from the shortlist?`\n      : 'Are you sure you want to remove this candidate from the shortlist?',\n  footerNote: 'The candidate will be moved back to the pipeline.',\n  fields: [],\n};\n","import { removeFromShortlist } from '../../../../services/popupApi';\n\nexport const api = {\n  onOk: async (context) => {\n    await removeFromShortlist({\n      jobId: context.jobId ?? context.selectedIds[0],\n      candidateIds: context.selectedIds,\n    });\n  },\n};\n","export const config = {\n  title: 'Add to Groups',\n  description: 'Select a group to add the selected candidate(s) to',\n  okText: 'Add to Group',\n  width: 480,\n  disabledUntilFilled: true,\n  fields: [\n    {\n      name: 'groupId',\n      label: 'Group',\n      type: 'select',\n      required: true,\n      placeholder: 'Select a group',\n      fetchOptionsKey: 'candidateGroups',\n    },\n  ],\n};\n","import { getCandidateGroups, addCandidatesToGroup } from '../../../../services/popupApi';\n\nexport const api = {\n  getOptions: async (field) => {\n    if (field.fetchOptionsKey === 'candidateGroups') return getCandidateGroups();\n    return [];\n  },\n  // Use cached dynamicOptions (already fetched by getOptions above) — no double fetch\n  submit: async (values, _context, { dynamicOptions }) => {\n    const groups = dynamicOptions['groupId'] ?? [];\n    const selectedGroup = groups.find((g) => String(g.value) === String(values.groupId));\n    await addCandidatesToGroup({\n      candidateIds: _context.selectedIds,\n      groupId: values.groupId,\n      groupName: selectedGroup?.label ?? '',\n    });\n  },\n};\n","// Self Assign popup body — a custom-body popup (see DynamicPopup's\n// config.component escape hatch). It restores the old Jobs SelfAssignPopup\n// behaviour: GET /self-assign decides between a simple \"Are you sure you want\n// to assign this job?\" confirmation (no submissions yet) and a \"Team Members\n// Allocated\" table + warning when other users are already working the job.\n// The body owns its own No/Yes footer and submit (selfAssignJob).\nimport { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Spin, Table, message } from 'antd';\nimport { ExclamationCircleFilled } from '@ant-design/icons';\nimport { getSelfAssignInfo, getJobAssignedRecruiters, selfAssignJob } from '../../../../services/popupApi';\n\nconst columns = [\n  {\n    title: 'Name',\n    key: 'name',\n    render: (_, record) =>\n      record.name ||\n      `${record.first_name ?? ''} ${record.last_name ?? ''}`.trim() ||\n      record.user_name ||\n      'Assigned user',\n  },\n  { title: 'Role', dataIndex: 'role_name', key: 'role', render: (v) => v || '-' },\n  { title: 'Reporting', dataIndex: 'reporting_name', key: 'reporting', render: (v) => v || '-' },\n];\n\nexport default function SelfAssignBody({ selectedIds, onClose }) {\n  const jobId = selectedIds?.[0];\n  const [loading, setLoading] = useState(true);\n  const [submitting, setSubmitting] = useState(false);\n  const [info, setInfo] = useState({ assignedUsers: [], totalSubmissions: 0, message: '' });\n  // The already-assigned recruiters — available regardless of submission count\n  // (GET /pay-details), unlike self-assign's assignedUsers which the backend\n  // only returns once the job HAS submissions. This is what lets the popup\n  // always list everyone already on the job.\n  const [recruiters, setRecruiters] = useState([]);\n\n  useEffect(() => {\n    let cancelled = false;\n    setLoading(true);\n    Promise.all([\n      getSelfAssignInfo(jobId).catch((error) => {\n        if (!cancelled) message.error(error?.message ?? 'Failed to load self-assign details');\n        return { assignedUsers: [], totalSubmissions: 0, message: '' };\n      }),\n      getJobAssignedRecruiters(jobId).catch(() => ({ recruitersData: [] })),\n    ])\n      .then(([selfInfo, payDetails]) => {\n        if (cancelled) return;\n        setInfo(selfInfo);\n        setRecruiters(Array.isArray(payDetails?.recruitersData) ? payDetails.recruitersData : []);\n      })\n      .finally(() => { if (!cancelled) setLoading(false); });\n    return () => { cancelled = true; };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [jobId]);\n\n  const handleYes = async () => {\n    setSubmitting(true);\n    try {\n      await selfAssignJob({ jobIds: [jobId] });\n      message.success('Job assigned successfully');\n      onClose?.({ success: true });\n    } catch (error) {\n      message.error(error?.message ?? 'Failed to assign job');\n    } finally {\n      setSubmitting(false);\n    }\n  };\n\n  if (loading) {\n    return <div style={{ display: 'flex', justifyContent: 'center', padding: 48 }}><Spin size=\"large\" /></div>;\n  }\n\n  // Prefer the richer self-assign rows (Name / Role / Reporting) when present;\n  // otherwise fall back to the pay-details recruiters so the \"already assigned\"\n  // list shows even when the job has no submissions yet.\n  const payDetailRows = recruiters.map((r) => ({\n    user_id: r.recruiterId ?? r.id ?? r.user_id,\n    name: r.name ?? '',\n    role_name: r.role_name ?? r.roleName ?? '',\n    reporting_name: r.reporting_name ?? r.reportingName ?? '',\n  }));\n  const payDetailRowsById = new Map(\n    payDetailRows.map((row) => [String(row.user_id ?? ''), row]),\n  );\n  const rows = (info.assignedUsers?.length ?? 0) > 0\n    ? info.assignedUsers.map((user) => {\n        const id = user.user_id ?? user.userId ?? user.recruiterId ?? user.id;\n        const directory = payDetailRowsById.get(String(id ?? '')) ?? {};\n        return {\n          ...user,\n          user_id: id,\n          name: directory.name || user.name || '',\n          role_name: directory.role_name || user.role_name || user.roleName || '',\n          reporting_name:\n            directory.reporting_name || user.reporting_name || user.reportingName || '',\n        };\n      })\n    : payDetailRows;\n  const hasAllocated = rows.length > 0;\n\n  return (\n    <div className=\"self-assign-popup-body\">\n      {hasAllocated ? (\n        <>\n          <div style={{ fontWeight: 700, marginBottom: 8 }}>Team Members Allocated</div>\n          <Table\n            columns={columns}\n            dataSource={rows}\n            pagination={false}\n            rowKey={(r) => r.user_id ?? `${r.first_name}-${r.last_name}`}\n            size=\"small\"\n            className=\"mb-3 no-header-bg\"\n            scroll={{ y: 200 }}\n          />\n          <div\n            className=\"warning-card\"\n            style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}\n          >\n            <ExclamationCircleFilled style={{ color: '#faad14', fontSize: 18 }} />\n            <div style={{ fontSize: 13 }}>\n              These users are already assigned to this job. Do you still want to assign yourself as\n              well?\n            </div>\n          </div>\n        </>\n      ) : (\n        <div style={{ padding: '8px 0' }}>\n          {info.message || 'No one is currently assigned to this job. Do you want to assign yourself?'}\n        </div>\n      )}\n\n      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 12, marginTop: 24 }}>\n        <Button size=\"small\" onClick={() => onClose?.()} disabled={submitting}>\n          No\n        </Button>\n        <Button type=\"primary\" size=\"small\" onClick={handleYes} loading={submitting}>\n          Yes\n        </Button>\n      </div>\n    </div>\n  );\n}\n\nSelfAssignBody.propTypes = {\n  selectedIds: PropTypes.array,\n  onClose: PropTypes.func,\n};\n","// Self Assign — a custom-body popup (see DynamicPopup's config.component\n// escape hatch). SelfAssignBody fetches GET /self-assign and renders either a\n// simple confirmation or the \"Team Members Allocated\" table + warning, and owns\n// its own No/Yes footer + submit. Admin lists this by popupKey \"self-assign\".\nimport SelfAssignBody from './SelfAssignBody.jsx';\n\nexport const config = {\n  title: 'Self Assign',\n  width: 480,\n  className: 'self-assign-modal',\n  component: SelfAssignBody,\n};\n","// Self Assign is a custom-body popup: SelfAssignBody owns its own submit\n// (selfAssignJob after the Yes confirmation), so the framework-level submit is\n// a no-op. Kept for POPUP registration symmetry.\nexport const api = {\n  submit: async () => {},\n};\n","// Resolves the job's CLIENT rate ceiling from the clicked job record. jobPayDetails\n// is normally a flat object, but if a deployment stores it as a history ARRAY the\n// last element is the current one — hence \"the last array index\". Falls back to the\n// flat clientBudget shape. Returns the max the candidate rate may reach, or null.\nfunction clientRateCeiling(job = {}) {\n  const pd = Array.isArray(job.jobPayDetails)\n    ? job.jobPayDetails[job.jobPayDetails.length - 1]\n    : (job.jobPayDetails ?? job.clientBudget ?? {});\n  const end = Number(pd.clientBudgetEnd);\n  const start = Number(pd.clientBudgetStart);\n  if (Number.isFinite(end) && end > 0) return end;\n  if (Number.isFinite(start) && start > 0) return start;\n  return null;\n}\n\n// candidateRate validator — shared by the field's Form.Item rule. Enforces:\n//   • range \"To\" strictly greater than \"From\"\n//   • the entered rate not exceeding the job's client rate ceiling.\nfunction validateCandidateRate(value, context) {\n  const v = value ?? {};\n  if (v.isRange && v.minAmount != null && v.maxAmount != null\n    && Number(v.maxAmount) <= Number(v.minAmount)) {\n    return 'To rate must be greater than From rate.';\n  }\n  const ceiling = clientRateCeiling(context?.selectedRecords?.[0] ?? {});\n  const entered = v.isRange ? Number(v.maxAmount) : Number(v.amount);\n  if (ceiling != null && Number.isFinite(entered) && entered > ceiling) {\n    return `Candidate rate must not exceed the client rate (${ceiling}).`;\n  }\n  return '';\n}\n\nexport const config = {\n  getTitleText: (_count, _itemLabel, record) => {\n    const jobName = record?.jobTitle || record?.title || '';\n    return jobName ? `Assign - ${jobName}` : 'Assign';\n  },\n  okText: 'Assign',\n  width: 520,\n  disabledUntilFilled: true,\n  showAlreadyAssigned: true,\n  // Taking a recruiter OFF the job is a saveable change on its own — without\n  // this, \"Assign to\" being required kept the OK button disabled and rejected\n  // the submit, so a removal could never be persisted.\n  allowRemovalOnlySubmit: true,\n  // getFields (not a static list) so the candidate-rate field can carry the\n  // clicked job's client-rate ceiling for the inline hint + validator.\n  getFields: (context) => {\n    const ceiling = clientRateCeiling(context?.selectedRecords?.[0] ?? {});\n    return [\n      {\n        name: 'assignToUserId',\n        label: 'Assign to',\n        // Multi-select: one Assign can add several recruiters at once. The submit\n        // merges every selected id into recruitersData, which the backend\n        // (ResolveAssignmentRecruiterIDs) unions with the existing recruiters.\n        type: 'multi-select',\n        required: true,\n        placeholder: 'Select recruiter(s)',\n        fetchOptionsKey: 'assignToUsers',\n      },\n      // {\n      //   name: 'candidateRate',\n      //   label: 'Candidate Rate',\n      //   type: 'candidate-rate',\n      //   rateCeiling: ceiling,\n      //   validator: validateCandidateRate,\n      // },\n      // {\n      //   name: 'priority',\n      //   label: 'Priority',\n      //   type: 'priority-checkbox',\n      //   checkboxLabel: 'Mark as High',\n      // },\n    ];\n  },\n};\n","import { getAssignableUsers, getJobAssignedRecruiters, assignJobToOthers } from '../../../../services/popupApi';\n\nexport const api = {\n  getOptions: async (field) => {\n    if (field.fetchOptionsKey === 'assignToUsers') return getAssignableUsers();\n    return [];\n  },\n  loadExtraData: async (context) => getJobAssignedRecruiters(context.selectedIds[0]),\n  submit: async (values, context, { removedIds, extraData }) => {\n    await assignJobToOthers({\n      jobIds: context.selectedIds,\n      userId: values.assignToUserId,\n      // rate: values.candidateRate,\n      // priority: values.priority,\n      removedIds,\n      existingRecruiters: extraData?.recruitersData,\n    });\n  },\n};\n","export const config = {\n  title: 'Add Sticky Notes',\n  getTitleText: (_count, _itemLabel, _firstRecord, popupContext) =>\n    (popupContext.editingNoteId ? 'Edit Sticky Notes' : 'Add Sticky Notes'),\n  okText: 'Save',\n  width: 480,\n  fields: [\n    {\n      name: 'heading',\n      label: 'Heading',\n      type: 'input',\n      required: true,\n      placeholder: 'Enter heading',\n      initialValueKey: 'editingHeading',\n    },\n    {\n      name: 'targetDate',\n      label: 'Target Date',\n      type: 'date-picker',\n      required: false,\n      initialValueKey: 'editingTargetDate',\n    },\n    {\n      name: 'comments',\n      label: 'Comments',\n      type: 'mention-textarea',\n      required: true,\n      rows: 5,\n      placeholder: \"Enter your note here... Use '@' to mention someone.\",\n      mentionFetchKey: 'mentionUsers',\n      initialValueKey: 'editingComments',\n    },\n  ],\n};\n","import { getMentionUsers, addStickyNote, updateStickyNote } from '../../../../services/popupApi';\n\nexport const api = {\n  getMentionOptions: async (_field, search) => getMentionUsers(search),\n  submit: async (values, context) => {\n    const targetDate = values.targetDate ? values.targetDate.toISOString() : '';\n\n    if (context.editingNoteId) {\n      await updateStickyNote(context.editingNoteId, {\n        title: values.heading,\n        targetDate,\n        notes: values.comments,\n      });\n    } else {\n      await addStickyNote({\n        relatedIds: context.selectedIds,\n        module: context.moduleName,\n        title: values.heading,\n        targetDate,\n        notes: values.comments,\n      });\n    }\n    window.dispatchEvent(new Event('sticky-notes:refresh'));\n  },\n};\n","export const config = {\n  title: 'Move to Onboarding',\n  bodyText: 'Are you sure you want to move this candidate to onboarding?',\n  okText: 'Yes',\n  cancelText: 'No',\n  width: 420,\n  successMessage: 'Moved to onboarding successfully',\n  // On success, land on the Onboarding screen (instead of returning to the\n  // background list). DynamicPopupRoute honours this and still stamps a\n  // refreshTimestamp so the destination reloads fresh.\n  successNavigate: '/onboarding',\n  fields: [\n    {\n      name: 'sendOnboardingEmail',\n      type: 'priority-checkbox',\n      checkboxLabel: 'Send Onboarding Email',\n    },\n  ],\n};\n","import { moveToOnboarding } from '../../../../services/popupApi';\n\nexport const api = {\n  submit: async (values, context) => {\n    await moveToOnboarding({\n      submissionId: context.selectedRecords?.[0]?.submissionId,\n      isMail: values.sendOnboardingEmail,\n    });\n  },\n};\n","// Reads a rate container that may be stored as a FLAT object, an append-only\n// HISTORY array (latest entry = current value), or flattened dotted keys (the\n// detail header's record shape) — covers every caller without caring how the\n// record was loaded.\nfunction lastEntry(value) {\n  if (Array.isArray(value)) return value[value.length - 1] ?? {};\n  return value && typeof value === 'object' ? value : {};\n}\n\nconst CURRENCY_SYMBOL = { USD: '$', INR: '₹', EUR: '€', GBP: '£' };\n\nfunction pick(record, container, key) {\n  const nested = lastEntry(record?.[container])[key];\n  if (nested !== undefined && nested !== null && nested !== '') return nested;\n  const flat = record?.[`${container}.${key}`];\n  return flat !== undefined && flat !== null && flat !== '' ? flat : undefined;\n}\n\nfunction currentCandidateRate(ctx) {\n  const record = ctx.selectedRecords?.[0] ?? {};\n  const amount = pick(record, 'candidateRate', 'candidateAcceptedRate')\n    ?? pick(record, 'candidateBudget', 'candidateBudgetStart');\n  if (amount === undefined || Number(amount) === 0) return null;\n  const currency = pick(record, 'candidateRate', 'candidateAcceptedCurrency')\n    ?? pick(record, 'candidateBudget', 'candidateBudgetCurrency');\n  const symbol = pick(record, 'candidateRate', 'candidateAcceptedCurrencySymbol')\n    ?? pick(record, 'candidateBudget', 'candidateBudgetCurrencySymbol')\n    ?? CURRENCY_SYMBOL[String(currency ?? '').toUpperCase()]\n    ?? (currency || '$');\n  const unit = pick(record, 'candidateRate', 'candidateAcceptedPayUnit')\n    ?? pick(record, 'candidateBudget', 'candidateBudgetUnit')\n    ?? '';\n  return { amount, symbol, unit };\n}\n\nexport const config = {\n  title: 'Approve Rate',\n  okText: 'Approve',\n  width: 520,\n  className: 'medium-modal',\n  successMessage: 'Rate approved',\n  getBodyText: (count, singularLabel, itemLabel, itemTitle, ctx) => {\n    const rate = currentCandidateRate(ctx);\n    return `Candidate Rate: ${rate ? `${rate.symbol}${rate.amount}${rate.unit ? `/${rate.unit}` : ''}` : '-'}`;\n  },\n  fields: [\n    {\n      name: 'candidateProposedRate',\n      label: 'Proposed Rate',\n      type: 'number',\n      required: true,\n      placeholder: 'Amount',\n      min: 0,\n      inlineRow: 'proposedRate',\n      validator: (value, ctx) => {\n        if (value === undefined || value === null || value === '') return undefined;\n        const rate = currentCandidateRate(ctx);\n        if (rate && Number(value) <= Number(rate.amount)) {\n          return 'Proposed rate must be greater than Candidate Rate';\n        }\n        return undefined;\n      },\n    },\n    {\n      name: 'candidateProposedRateCurrency',\n      label: 'Currency',\n      type: 'select',\n      required: true,\n      inlineRow: 'proposedRate',\n      defaultOptions: [\n        { label: '$ USD', value: '$' },\n        { label: '₹ INR', value: '₹' },\n        { label: '€ EUR', value: '€' },\n      ],\n    },\n    {\n      name: 'candidateProposedRateUnit',\n      label: 'Unit',\n      type: 'select',\n      required: true,\n      inlineRow: 'proposedRate',\n      defaultOptions: [\n        { label: 'Year', value: 'yr' },\n        { label: 'Month', value: 'mo' },\n        { label: 'Week', value: 'wk' },\n        { label: 'Hour', value: 'hr' },\n        { label: 'Daily', value: 'day' },\n      ],\n    },\n    {\n      name: 'submitVia',\n      label: 'Submit Via',\n      type: 'radio',\n      required: true,\n      defaultOptions: [\n        { label: 'Mail', value: 'Mail' },\n        { label: 'VMS', value: 'VMS' },\n      ],\n    },\n  ],\n};\n","import { message } from 'antd';\nimport { approveSubmission, getVMSApprove } from '../../../../services/popupApi';\n\nexport const api = {\n  submit: async (values, context) => {\n    const submissionId = context.selectedIds[0];\n    // Primary write — the native, schema-free gateway approve. Once this\n    // resolves the submission IS approved; nothing after may turn that into a\n    // failure toast.\n    await approveSubmission(submissionId, {\n      candidateProposedRate: values.candidateProposedRate,\n      candidateProposedRateCurrency: values.candidateProposedRateCurrency,\n      candidateProposedRateUnit: values.candidateProposedRateUnit,\n      submitVia: values.submitVia,\n    });\n\n    if (values.submitVia === 'VMS') {\n      // VMS notification is a best-effort SIDE EFFECT that proxies to the legacy\n      // submissions service — which 500s on rate-history arrays. Its failure\n      // must NOT report the (already committed) approval as failed, which was\n      // the \"shows error even though it worked\" bug. Swallow + warn instead of\n      // rethrowing so the popup shows success.\n      try {\n        await getVMSApprove(submissionId);\n      } catch {\n        message.warning('Approved. VMS notification could not be sent — use Send Mail to notify the client.');\n      }\n    } else {\n      message.info('Approved — use Send Mail to notify the client.');\n    }\n  },\n};\n","/**\n * mailApproveApi.js\n * API calls for the manager Submission Approval (mail-approve) flow.\n *\n * EM-Testing owns this service itself — @realtek/core-theme intentionally does\n * not ship feature-specific business logic, only the shared building blocks\n * (SUBMISSIONS_URL, getStoredToken, logout). See CORE-THEME's src/index.js:\n * \"The host app keeps those thin route wrappers itself and composes them from\n * the building blocks.\" This mirrors ZINNEXT-V1's local services/submissionsApi.js,\n * but reuses the npm package for auth/token/base-url instead of duplicating them.\n *\n * Endpoints (SUBMISSIONS_URL):\n *   GET  /review?tenantId=&businessId=&businessUnitId=&submissionId=  — fetch data\n *   GET  /evaluate-form?submissionId=&proposedRate=35 $ USD Hourly    — approve + set rate\n *   GET  /approved?submissionId=                                       — approve without rate\n *   POST /reject-submission                                            — reject\n */\n\nimport { SUBMISSIONS_URL } from './apiConfig';\nimport { getStoredToken, logout } from './authApi';\n\nasync function fetchJsonWithAuth(path, options = {}) {\n  const token = getStoredToken();\n  if (!token) {\n    const error = new Error('Authentication required');\n    error.status = 401;\n    throw error;\n  }\n\n  const res = await fetch(`${SUBMISSIONS_URL}${path}`, {\n    ...options,\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: `Bearer ${token}`,\n      ...options.headers,\n    },\n  });\n\n  if (res.status === 401) logout();\n\n  if (!res.ok) {\n    const error = new Error(`API ${res.status}: ${res.statusText}`);\n    error.status = res.status;\n    throw error;\n  }\n  return res.json();\n}\n\n/**\n * Fetch submission data for the Evaluate Form page.\n * Uses /review — returns the full record without modifying any status.\n */\nexport async function getEvaluateForm(submissionId) {\n  const tenantId       = localStorage.getItem('tenantId')       || '';\n  const businessId     = localStorage.getItem('businessId')     || '';\n  const businessUnitId = localStorage.getItem('businessUnitId') || '';\n\n  const params = new URLSearchParams({ tenantId, businessId, businessUnitId, submissionId });\n  const json = await fetchJsonWithAuth(`/review?${params.toString()}`);\n  return json.data ?? json;\n}\n\n/**\n * Manager approves the submission.\n * Rate string format the backend expects: \"35 $ USD Hourly\"\n */\nexport async function approveSubmission(submissionId, { proposedRate, currency, payUnit } = {}) {\n  const hasRate = proposedRate !== undefined && proposedRate !== '' && proposedRate !== null;\n\n  if (hasRate) {\n    const sym = { USD: '$', INR: '₹', EUR: '€', GBP: '£', CAD: '$' }[currency] ?? '$';\n    const rateString = `${proposedRate} ${sym} ${currency ?? 'USD'} ${payUnit ?? 'Hourly'}`;\n    const json = await fetchJsonWithAuth(\n      `/evaluate-form?submissionId=${encodeURIComponent(submissionId)}&proposedRate=${encodeURIComponent(rateString)}`\n    );\n    return json.data ?? json;\n  }\n\n  const json = await fetchJsonWithAuth(`/approved?submissionId=${encodeURIComponent(submissionId)}`);\n  return json.data ?? json;\n}\n\nexport async function approveSubmissionV2(submissionId, payload = {}) {\n  const json = await fetchJsonWithAuth(`/approved/v2?submissionId=${encodeURIComponent(submissionId)}`, {\n    method: 'POST',\n    body: JSON.stringify(payload),\n  });\n  return json.data ?? json;\n}\n\nexport async function getApproveMailDraft(submissionId) {\n  // Manager-approve mail must be addressed to the internal approver, not the\n  // client's recruiter/contact. The submissions service keeps the same client\n  // mail template/body for this mode and only changes recipient resolution.\n  const params = new URLSearchParams({ submissionId, submissionType: 'manager' });\n  const json = await fetchJsonWithAuth(`/mail-form?${params.toString()}`);\n  return json.data ?? json;\n}\n\nexport async function sendApproveMail(payload) {\n  const token = getStoredToken();\n  if (!token) {\n    const error = new Error('Authentication required');\n    error.status = 401;\n    throw error;\n  }\n\n  const formData = new FormData();\n  formData.append('json', JSON.stringify(payload));\n\n  const res = await fetch(`${SUBMISSIONS_URL}/send-mail-client-doc`, {\n    method: 'POST',\n    headers: { Authorization: `Bearer ${token}` },\n    body: formData,\n  });\n\n  if (res.status === 401) logout();\n\n  const json = await res.json().catch(() => ({}));\n  if (!res.ok || json?.status === false) {\n    const error = new Error(json?.message ?? json?.error ?? `API ${res.status}: ${res.statusText}`);\n    error.status = res.status;\n    throw error;\n  }\n  return json.data ?? json;\n}\n\n/**\n * Manager rejects the submission.\n * rejectReasonId: 1 = re-submission, 2 = rejected, 3 = need update\n */\nexport async function rejectSubmission(submissionId, { rejectReasonId, rejectReasonComments }) {\n  const json = await fetchJsonWithAuth('/reject-submission', {\n    method: 'POST',\n    body: JSON.stringify({ submissionId, rejectReasonId, rejectReasonComments }),\n  });\n  return json.data ?? json;\n}\n","// Manager Approve popup body — renders the shared, config-driven\n// FinanceApprovalPanel (type = submissionManager) inside the dynamic popup.\n// Admin tags a module's \"Approve\" action to popupKey \"manager-approve\".\n//\n// This backend has NO by-id detail route for submissions/clients/jobs\n// (module-data-detail 404s) and its list projections drop the reference IDs,\n// so the popup resolves the full picture itself, in-file, from the endpoints\n// that DO work:\n//   • getFormGroups(submission,id) → recordMeta.{clientId, jobId}\n//   • jobs   → getJobDetailView (jobPayDetails = Client Job Rate, jobTitle)\n//   • clients   list → clientName (+ vmsFee when the projection exposes it)\n//   • employers list → empCompanyName / empCompanyLocation\n//   • locations list → taxValue (W2 tax) + name, matched by id OR name\nimport { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Drawer, Modal, Radio, Spin, message } from 'antd';\nimport FinanceApprovalPanel from '../../../finance/FinanceApprovalPanel.jsx';\nimport { FINANCE_TYPE_SUBMISSION_MANAGER } from '../../../finance/financeApprovalConfig.js';\nimport { resolveSubmissionFinance, getReferralOptions, idOf } from '../../../finance/financeApprovalData.js';\nimport { approveSubmission as approveSubmissionViaVms } from '../../../../services/popupApi';\nimport {\n  getApproveMailDraft,\n} from '../../../../services/mailApproveApi';\nimport { sendBulkMail } from '../../../../services/dropdownApi';\nimport { getModuleDocuments } from '../../../../services/documentApi';\nimport { fetchJsonWithAuth } from '../../../../services/authApi';\nimport { AUTH_URL } from '../../../../services/apiConfig';\nimport CommonMailComposer, { resolveTemplateText } from '../../CommonMailComposer.jsx';\nimport { areValidEmails, parseEmails } from '../../mailUtils.js';\n\nfunction latestArrayEntry(value) {\n  return Array.isArray(value) ? value[value.length - 1] : value;\n}\n\nfunction persistedProposedRate(submission = {}) {\n  const entry = latestArrayEntry(submission?.proposedRate);\n  const value = entry?.candidateProposedRate\n    ?? submission?.candidateProposedRate\n    ?? submission?.proposedRateValue;\n  const number = Number(value);\n  return Number.isFinite(number) ? number : 0;\n}\n\nfunction persistedJobBillRate(resolved, seed = {}) {\n  const job = resolved?.record?.job ?? resolved?.job ?? seed?.job ?? {};\n  const pay = latestArrayEntry(job?.jobPayDetails) ?? {};\n  const submission = resolved?.record?.submission ?? seed ?? {};\n  const budget = latestArrayEntry(submission?.clientBudget) ?? submission?.clientBudget ?? {};\n\n  // FinanceApprovalPanel uses the END/to value as Client Job Rate when the job\n  // contains a budget range. Keep the mail value identical to the popup value.\n  const value = pay?.clientBudgetEnd\n    ?? pay?.clientBudgetStart\n    ?? budget?.clientBudgetEnd\n    ?? budget?.clientBudgetStart;\n  const number = Number(value);\n  return Number.isFinite(number) ? number : 0;\n}\n\nfunction normalizeRateCurrency(computed = {}) {\n  const raw = String(computed?.currencyRaw ?? '').trim().toUpperCase();\n  const display = String(computed?.currency ?? '').trim();\n\n  if (display && !/^[A-Z]{3}$/i.test(display)) return display;\n  if (raw === 'USD' || display.toUpperCase() === 'USD') return '$';\n  if (raw === 'INR' || display.toUpperCase() === 'INR') return '₹';\n  if (raw === 'EUR' || display.toUpperCase() === 'EUR') return '€';\n  if (raw === 'GBP' || display.toUpperCase() === 'GBP') return '£';\n  return display || raw;\n}\n\nfunction normalizeRateUnit(computed = {}) {\n  const raw = String(computed?.rateUnit ?? 'hr').trim();\n  return raw.replace(/^\\/+/, '') || 'hr';\n}\n\nfunction formatManagerMailRate(rate, computed = {}) {\n  const number = Number(rate);\n  if (!Number.isFinite(number)) return '';\n  const currency = normalizeRateCurrency(computed);\n  const unit = normalizeRateUnit(computed);\n  return `${currency}${number}/${unit}`;\n}\n\nfunction replaceRenderedFinanceValue(value, labelPattern, replacement) {\n  if (replacement === undefined || replacement === null || replacement === '') return String(value ?? '');\n\n  let output = String(value ?? '');\n  const renderedValue = String(replacement);\n  let matched = false;\n\n  // Table templates are common in Admin -> Templates. In that shape the label\n  // and value live in separate cells, for example:\n  //   <td>Pay Rate</td><td>0</td>\n  // Replace the COMPLETE second cell so a value already rendered by /mail-form\n  // (0, an old rate, or map[...]) cannot leak into the Manager Approve mail.\n  const tableCellLabel = new RegExp(\n    `(<(?:td|th)[^>]*>[\\\\s\\\\S]*?${labelPattern}[\\\\s\\\\S]*?</(?:td|th)>\\\\s*<(?:td|th)[^>]*>)([\\\\s\\\\S]*?)(</(?:td|th)>)`,\n    'gi',\n  );\n  output = output.replace(tableCellLabel, (_, prefix, _oldValue, suffix) => {\n    matched = true;\n    return `${prefix}${renderedValue}${suffix}`;\n  });\n\n  // List/paragraph templates often bold the label in the same element.\n  const taggedLabel = new RegExp(\n    `(<(?:strong|b)[^>]*>\\\\s*${labelPattern}\\\\s*:?\\\\s*</(?:strong|b)>\\\\s*)([\\\\s\\\\S]*?)(?=</(?:li|p|div)>)`,\n    'gi',\n  );\n  output = output.replace(taggedLabel, (_, prefix) => {\n    matched = true;\n    return `${prefix}${renderedValue}`;\n  });\n\n  // Plain-text fallback for templates without table/bold markup. Only run this\n  // when neither structured form matched, otherwise the same row could be\n  // processed twice and produce duplicated values (for example 6060).\n  if (!matched) {\n    const inlineLabel = new RegExp(\n      `(${labelPattern}\\\\s*:?[ \\\\t]*)([^<\\\\r\\\\n]*)`,\n      'gi',\n    );\n    output = output.replace(inlineLabel, (_, prefix) => `${prefix}${renderedValue}`);\n  }\n\n  return output;\n}\n\nfunction resolveManagerApproveFinancePlaceholders(value, submission, computed, resolved, seed) {\n  const liveProposed = Number(computed?.proposedRate);\n  const proposedRate = Number.isFinite(liveProposed)\n    ? liveProposed\n    : persistedProposedRate(submission);\n\n  const liveBillRate = Number(computed?.clientJobRate);\n  const jobBillRate = Number.isFinite(liveBillRate) && liveBillRate > 0\n    ? liveBillRate\n    : persistedJobBillRate(resolved, seed);\n\n  const values = { proposedRate, jobBillRate };\n\n  // First handle templates where the raw runtime placeholders survive the\n  // backend template resolver.\n  let output = String(value ?? '').replace(\n    /{{\\.?((?:proposedRate)|(?:jobBillRate))}}/g,\n    (token, key) => {\n      const resolvedValue = values[key];\n      return resolvedValue === undefined || resolvedValue === null ? token : String(resolvedValue);\n    },\n  );\n\n  // Then handle the current backend behavior where /mail-form has already\n  // replaced those placeholders with 0 using persisted DB data.\n  output = replaceRenderedFinanceValue(\n    output,\n    '(?:Proposed\\\\s*Rate|Pay\\\\s*Rate)',\n    formatManagerMailRate(proposedRate, computed),\n  );\n  output = replaceRenderedFinanceValue(\n    output,\n    '(?:Job\\\\s*)?Bill\\\\s*Rate',\n    formatManagerMailRate(jobBillRate, computed),\n  );\n\n  return output;\n}\n\n// firstText — first non-blank value. `??` only falls through on null/undefined,\n// so an upstream chain that resolves to '' (see submittedBy below) would stop\n// dead on it and never reach the fallbacks that exist for exactly that case.\nfunction firstText(...values) {\n  return values\n    .map((value) => (value === null || value === undefined ? '' : String(value).trim()))\n    .find(Boolean) ?? '';\n}\n\nconst sameText = (a, b) => Boolean(a) && a.toLowerCase() === firstText(b).toLowerCase();\n\n// resolveSubmittedBy — \"Submitted By\" must name the PERSON who submitted.\n// resolveSubmissionFinance's display.submittedBy is a `||` chain that ends in\n// `flat.recruiterName || flat.submitSource`, and neither of those is a\n// submitter: submitSource is the submission's SOURCE (\"Internal\", or a vendor)\n// — this very function reads it as `vendor` one line down — and recruiterName\n// is the ASSIGNED recruiter. Real submissions store submitSource but no\n// recruiterName, so display.submittedBy came back as the source string, which\n// is truthy, which meant the correct seed.signatureEmail fallback never ran\n// and the popup tagged \"Internal\" as the submitter.\n// So: take the resolved value only when it is not one of those source/vendor\n// strings, then fall back to the submitter's own signature email.\nfunction resolveSubmittedBy(seed, display, vendor) {\n  const resolved = firstText(display.submittedBy);\n  const isSourceLeak = sameText(resolved, vendor)\n    || sameText(resolved, seed.submitSource)\n    || sameText(resolved, seed.supplierName)\n    || sameText(resolved, seed.source)\n    || sameText(resolved, seed.candidateSource);\n  return firstText(isSourceLeak ? '' : resolved, seed.signatureEmail);\n}\n\n// Display identity — resolved values (form-groups + joins) win over the\n// clicked row, which on the detail surface is flattened and often stale.\nfunction buildIdentity(seed, display = {}) {\n  const vendor = display.employerName ?? seed.supplierName ?? seed.submitSource;\n  return {\n    client: display.clientName ?? seed.clientName,\n    role: display.jobTitle ?? seed.jobTitle ?? seed.designation,\n    reqId: display.reqId ?? seed.jobClientRefrenceId ?? seed.mspReqId ?? seed.submissionId,\n    name: display.candidateName\n      || [seed.firstName, seed.lastName].filter(Boolean).join(' ')\n      || seed.candidateFullName,\n    location: display.jobLocation ?? seed.city ?? seed.currentLocation ?? seed.jobLocation,\n    vendor,\n    submittedBy: resolveSubmittedBy(seed, display, vendor),\n    submittedAt: display.createdAt ?? seed.createdAt,\n    email: display.email ?? seed.email,\n    employerLocation: display.employerLocation,\n    employerName: display.employerName,\n  };\n}\n\nfunction scalarObjectId(value) {\n  const raw = value?.$oid ?? value?._id?.$oid ?? value?._id ?? value?.id?.$oid ?? value?.id ?? value;\n  if (raw === null || raw === undefined || typeof raw === 'object') return '';\n  const text = String(raw).trim();\n  return /^[a-f\\d]{24}$/i.test(text) ? text : '';\n}\n\nfunction resolveJobId(...values) {\n  for (const value of values) {\n    const id = [\n      value?.jobId,\n      value?.JobId,\n      value?.job_id,\n      value?.jobDetails?._id,\n      value?.jobDetails?.id,\n      value?.job?._id,\n      value?.job?.id,\n      value?.submission?.jobId,\n      value?.submission?.JobId,\n      value?.submission?.job_id,\n      value?.submission?.jobDetails?._id,\n      value?.submission?.jobDetails?.id,\n      value?.submission?.job?._id,\n      value?.submission?.job?.id,\n      value?.recordMeta?.jobId,\n      value?.recordMeta?.JobId,\n      value?.recordMeta?.job_id,\n      value?.submission?.recordMeta?.jobId,\n      value?.submission?.recordMeta?.JobId,\n      value?.submission?.recordMeta?.job_id,\n    ].map(scalarObjectId).find(Boolean);\n    if (id) return id;\n  }\n  return '';\n}\n\n// referralPayload — the fields ApproveSubmissionHandler (Be_Auth_DevOps)\n// reads to push a new submissions.referralDetails entry. Omitted entirely\n// when no referral was attached, so a plain rate-only approve never touches\n// that array.\nfunction referralPayload(referral) {\n  if (!referral?.referralId) return {};\n\n  // The submission approve API is consumed by more than one backend version.\n  // Persist the manager-entered referral snapshot using both the canonical and\n  // legacy aliases, and also send the normalized object used by the newer\n  // submission handler to append submissions.referralDetails[].\n  //\n  // IMPORTANT: use the referral passed by FinanceApprovalPanel here. Its\n  // referralRate is computed from the CURRENT edit state, so a manager changing\n  // 10 -> 15 must persist 15 rather than the referral master's old rate.\n  const referralRate = Number(referral.referralRate ?? referral.referalRate ?? 0) || 0;\n  const referralType = String(\n    referral.referralType ?? referral.referalType ?? 'RECURRING',\n  ).trim() || 'RECURRING';\n  const referralId = referral.referralId ?? referral.referalId;\n\n  return {\n    referralId,\n    referalId: referralId,\n    referralRate,\n    referalRate: referralRate,\n    referralType,\n    referalType: referralType,\n    referralEnabled: true,\n    referalEnabled: true,\n    isReferralApplicable: true,\n    referralDetails: {\n      referralId,\n      referalId: referralId,\n      referralRate,\n      referalRate: referralRate,\n      referralType,\n      referalType: referralType,\n      referralEnabled: true,\n      referalEnabled: true,\n      isReferralApplicable: true,\n    },\n  };\n}\n\nfunction stripDocumentPlaceholderArtifacts(value = '') {\n  // Legacy mail-template interpolation stringifies stored file maps as e.g.\n  // \"map[resumeLocation: ... resumeUniqueName: ... resumeUploadName: ...]\".\n  // A document placeholder represents an ATTACHMENT, not visible mail text.\n  // Remove only map fragments that clearly describe file/document metadata.\n  return String(value ?? '')\n    .replace(/map\\[[^\\]]*(?:resume|document|attachment|file)[^\\]]*\\]/gi, '')\n    .replace(/<p>\\s*<\\/p>/gi, '')\n    .replace(/(?:<br\\s*\\/?>\\s*){3,}/gi, '<br><br>')\n    .trim();\n}\n\nfunction candidateIdFrom(...values) {\n  for (const value of values) {\n    const candidateId = [\n      value?.candidateId,\n      value?.applicantId,\n      value?.candidate?._id,\n      value?.candidate?.id,\n      value?.submission?.candidateId,\n      value?.submission?.applicantId,\n      value?.recordMeta?.candidateId,\n      value?.recordMeta?.applicantId,\n    ].map(scalarObjectId).find(Boolean);\n    if (candidateId) return candidateId;\n  }\n  return '';\n}\n\nasync function documentToFile(document) {\n  const url = document?.fileUrl ?? document?.downloadUrl ?? document?.url;\n  if (!url) return null;\n  const response = await fetch(url);\n  if (!response.ok) throw new Error(`Unable to load ${document?.fileName || 'resume'}`);\n  const blob = await response.blob();\n  const name = document?.fileName\n    ?? document?.uploadedFileName\n    ?? document?.originalName\n    ?? document?.uniqueName\n    ?? 'resume';\n  return new File([blob], name, {\n    type: document?.contentType || blob.type || 'application/octet-stream',\n  });\n}\n\nasync function resolveResumeAttachments(submissionId, resolved, seed) {\n  // New uploads normally live in the common documents registry against the\n  // candidate record. Check the submission too for older/migrated data.\n  const documentRows = [];\n  const submissionDocs = await getModuleDocuments('submissions', submissionId, 'resume').catch(() => ({ data: [] }));\n  documentRows.push(...(submissionDocs?.data ?? []));\n\n  let candidateId = candidateIdFrom(resolved?.record?.submission, seed, resolved?.record);\n  if (!candidateId) {\n    // The list-view projection can omit candidateId/applicantId. Read the raw\n    // submission only to recover that linkage; this does not alter the popup's\n    // existing finance-resolution flow.\n    const rawJson = await fetchJsonWithAuth(\n      AUTH_URL,\n      `/module/list?module=submissions&id=${encodeURIComponent(submissionId)}`,\n    ).catch(() => ({}));\n    const payload = rawJson?.data ?? rawJson ?? {};\n    const rows = Array.isArray(payload?.data) ? payload.data : (Array.isArray(payload) ? payload : []);\n    candidateId = candidateIdFrom(rows[0]);\n  }\n\n  if (candidateId) {\n    const candidateDocs = await getModuleDocuments('candidates', candidateId, 'resume').catch(() => ({ data: [] }));\n    documentRows.push(...(candidateDocs?.data ?? []));\n  }\n\n  const files = (await Promise.all(documentRows.map(documentToFile))).filter(Boolean);\n\n  // Most candidates have one current resume. De-duplicate in case the registry\n  // returns the same file more than once.\n  const seen = new Set();\n  return files.filter((file) => {\n    const key = `${file.name}:${file.size}:${file.type}`;\n    if (seen.has(key)) return false;\n    seen.add(key);\n    return true;\n  });\n}\n\nfunction normalizeDraft(draft = {}) {\n  return {\n    to: (draft.to ?? draft.To ?? []).map((item) => item.email ?? item.Email ?? item).filter(Boolean).join(', '),\n    cc: (draft.cc ?? draft.Cc ?? []).map((item) => item.email ?? item.Email ?? item).filter(Boolean).join(', '),\n    bcc: (draft.bcc ?? draft.Bcc ?? []).map((item) => item.email ?? item.Email ?? item).filter(Boolean).join(', '),\n    subject: draft.subject ?? draft.Subject ?? '',\n    contents: stripDocumentPlaceholderArtifacts(draft.content?.value ?? draft.Content?.Value ?? draft.contents ?? draft.body ?? ''),\n  };\n}\n\nexport default function ManagerApproveBody({ context, selectedIds, selectedRecords, moduleName, onClose }) {\n  const seed = selectedRecords?.[0] ?? {};\n  const submissionId = selectedIds?.[0] ?? idOf(seed);\n  const [resolved, setResolved] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [referralOptions, setReferralOptions] = useState([]);\n  const [approvalChoiceOpen, setApprovalChoiceOpen] = useState(false);\n  const [approvalMode, setApprovalMode] = useState('vms');\n  const [pendingComputed, setPendingComputed] = useState(null);\n  const [pendingReferral, setPendingReferral] = useState(null);\n  const [approvalSubmitting, setApprovalSubmitting] = useState(false);\n  const [mailDrawerOpen, setMailDrawerOpen] = useState(false);\n  const [mailLoading, setMailLoading] = useState(false);\n  const [mailSending, setMailSending] = useState(false);\n  const [mail, setMail] = useState({\n    to: '', cc: '', bcc: '', subject: '', contents: '', attachments: [], showCc: false, showBcc: false,\n  });\n\n  useEffect(() => {\n    let cancelled = false;\n    resolveSubmissionFinance(submissionId, seed)\n      .then((data) => { if (!cancelled) setResolved(data); })\n      .catch((error) => {\n        if (cancelled) return;\n        message.error(error?.message ?? 'Unable to load finance details');\n        setResolved({ record: { submission: seed }, lookups: {}, display: {} });\n      })\n      .finally(() => { if (!cancelled) setLoading(false); });\n    return () => { cancelled = true; };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [submissionId]);\n\n  // The \"Add Referral\" section (submissionManager stage now allows Delivery\n  // Manager to attach one here too) needs the referral list — was never\n  // fetched by this popup, so the dropdown rendered \"No data\".\n  useEffect(() => {\n    let cancelled = false;\n    getReferralOptions()\n      .then((options) => { if (!cancelled) setReferralOptions(options); })\n      .catch(() => {});\n    return () => { cancelled = true; };\n  }, []);\n\n  const submitApproval = async () => {\n    if (!pendingComputed) return;\n    if (approvalMode === 'mail') {\n      setApprovalChoiceOpen(false);\n      setMailDrawerOpen(true);\n      setMailLoading(true);\n      try {\n        const [draft, attachments] = await Promise.all([\n          getApproveMailDraft(submissionId).then(normalizeDraft),\n          resolveResumeAttachments(submissionId, resolved, seed).catch((error) => {\n            console.warn('Unable to resolve resume attachment:', error);\n            return [];\n          }),\n        ]);\n        const submissionRecord = resolved?.record?.submission ?? seed;\n        setMail({\n          to: resolveManagerApproveFinancePlaceholders(draft.to, submissionRecord, pendingComputed, resolved, seed),\n          cc: resolveManagerApproveFinancePlaceholders(draft.cc, submissionRecord, pendingComputed, resolved, seed),\n          bcc: resolveManagerApproveFinancePlaceholders(draft.bcc, submissionRecord, pendingComputed, resolved, seed),\n          subject: resolveManagerApproveFinancePlaceholders(draft.subject, submissionRecord, pendingComputed, resolved, seed),\n          contents: resolveManagerApproveFinancePlaceholders(draft.contents, submissionRecord, pendingComputed, resolved, seed),\n          attachments,\n          showCc: Boolean(draft.cc),\n          showBcc: Boolean(draft.bcc),\n        });\n      } catch (error) {\n        message.error(error?.message ?? 'Unable to prepare approval mail');\n      } finally {\n        setMailLoading(false);\n      }\n      return;\n    }\n\n    setApprovalSubmitting(true);\n    try {\n      await approveSubmissionViaVms(submissionId, {\n        candidateProposedRate: pendingComputed.proposedRate,\n        candidateProposedRateCurrency: pendingComputed.currencyRaw ?? pendingComputed.currency,\n        candidateProposedRateUnit: pendingComputed.rateUnit,\n        submitVia: 'VMS',\n        ...referralPayload(pendingReferral),\n      });\n      message.success('Submission approved');\n      setApprovalChoiceOpen(false);\n      setPendingComputed(null);\n      setPendingReferral(null);\n      onClose?.({ success: true });\n    } catch (error) {\n      message.error(error?.message ?? 'Unable to approve submission');\n    } finally {\n      setApprovalSubmitting(false);\n    }\n  };\n\n  const canSendMail = !mailLoading\n    && parseEmails(mail.to).length > 0\n    && areValidEmails(mail.to)\n    && areValidEmails(mail.cc)\n    && areValidEmails(mail.bcc)\n    && mail.subject.trim()\n    && mail.contents.trim();\n\n  const sendMailAndApprove = async () => {\n    if (!pendingComputed || !canSendMail || mailSending) return;\n    setMailSending(true);\n    const approvalPayload = {\n      candidateProposedRate: pendingComputed.proposedRate,\n      candidateProposedRateCurrency: pendingComputed.currencyRaw ?? pendingComputed.currency,\n      candidateProposedRateUnit: pendingComputed.rateUnit,\n    };\n    try {\n      await approveSubmissionViaVms(submissionId, {\n        ...approvalPayload,\n        submitVia: 'VMS',\n        ...referralPayload(pendingReferral),\n      });\n      const mailJobId = resolveJobId(resolved?.record, seed);\n      if (!mailJobId) {\n        message.warning('Submission approved, but job details were not available to send mail');\n      } else {\n        try {\n          await sendBulkMail({\n            jobId: mailJobId,\n            toMail: parseEmails(mail.to),\n            ccMail: parseEmails(mail.cc),\n            bccMail: parseEmails(mail.bcc),\n            subject: mail.subject,\n            contents: mail.contents,\n            attachments: mail.attachments ?? [],\n          });\n          message.success('Approval mail sent and submission approved');\n        } catch (mailError) {\n          message.warning(mailError?.message\n            ? `Submission approved, but mail was not sent: ${mailError.message}`\n            : 'Submission approved, but mail was not sent');\n        }\n      }\n      setMailDrawerOpen(false);\n      setPendingComputed(null);\n      setPendingReferral(null);\n      onClose?.({ success: true });\n    } catch (error) {\n      message.error(error?.message ?? 'Unable to send approval mail');\n    } finally {\n      setMailSending(false);\n    }\n  };\n\n  const actions = useMemo(() => ({\n    submissionApprove: async ({ computed, referral }) => {\n      // Unit and currency are written back AS RESOLVED, never as literals.\n      // This used to send `candidateProposedRateUnit: 'hr'`, so approving a\n      // daily or monthly rate silently rewrote it to hourly — the recruiter's\n      // choice was destroyed by the act of approving it. computed.rateUnit is\n      // the engine's resolution (submission → candidate budget → job → config\n      // default) and computed.currencyRaw is the currency exactly as stored,\n      // so an ISO code (\"USD\") is not rewritten into a symbol on approve.\n      setPendingComputed(computed);\n      // Captured here (not read off `computed`) because the referral the\n      // Delivery Manager attached lives in the panel's own local state — see\n      // referralPayload() above for what actually gets sent.\n      setPendingReferral(referral ?? null);\n      setApprovalMode('vms');\n      setApprovalChoiceOpen(true);\n    },\n    // Reject hands off to the dedicated Reject popup (reason dropdown +\n    // comments) instead of rejecting inline — config marks this reject with\n    // `openPopup: 'reject'`. Swap this popup for that one over the SAME page\n    // (replace, so Back returns to the page, not here); carry the selection so\n    // the reject popup's own api.submit targets this submission.\n    submissionReject: async () => {\n      context?.navigate?.('/popup/reject', {\n        replace: true,\n        state: {\n          background: context?.background ?? null,\n          selectedIds,\n          selectedRecords,\n          moduleName,\n        },\n      });\n    },\n  }), [context, selectedIds, selectedRecords, moduleName]);\n\n  if (loading || !resolved) {\n    return <div style={{ display: 'flex', justifyContent: 'center', padding: 48 }}><Spin size=\"large\" /></div>;\n  }\n\n  return (\n    <>\n      <FinanceApprovalPanel\n        type={FINANCE_TYPE_SUBMISSION_MANAGER}\n        record={resolved.record}\n        lookups={resolved.lookups}\n        identity={buildIdentity(seed, resolved.display)}\n        referralOptions={referralOptions}\n        onAddReferral={() => context?.navigate?.('/referrals-create')}\n        currentUserId={typeof localStorage !== 'undefined' ? localStorage.getItem('userId') ?? undefined : undefined}\n        actions={actions}\n        onClose={() => onClose?.()}\n        variant=\"popup\"\n      />\n      <Modal\n        title=\"Choose approval method\"\n        open={approvalChoiceOpen}\n        okText=\"Approve\"\n        confirmLoading={approvalSubmitting}\n        onOk={submitApproval}\n        onCancel={() => {\n          if (approvalSubmitting) return;\n          setApprovalChoiceOpen(false);\n          setPendingComputed(null);\n          setPendingReferral(null);\n        }}\n      >\n        <Radio.Group\n          value={approvalMode}\n          onChange={(event) => setApprovalMode(event.target.value)}\n          style={{ display: 'grid', gap: 12 }}\n        >\n          <Radio value=\"vms\">Via VMS</Radio>\n          <Radio value=\"mail\">Via Mail</Radio>\n        </Radio.Group>\n      </Modal>\n      <Drawer\n        open={mailDrawerOpen}\n        placement=\"right\"\n        onClose={() => {\n          if (mailSending) return;\n          setMailDrawerOpen(false);\n        }}\n        closable={false}\n        rootClassName=\"mail-popup\"\n        width={620}\n        maskClosable={false}\n        footer={(\n          <div className=\"mail-popup__footer\">\n            <Button onClick={() => setMailDrawerOpen(false)} disabled={mailSending}>\n              Cancel\n            </Button>\n            <Button type=\"primary\" loading={mailSending} disabled={!canSendMail} onClick={sendMailAndApprove}>\n              Send\n            </Button>\n          </div>\n        )}\n      >\n        {mailLoading ? (\n          <div style={{ display: 'flex', justifyContent: 'center', padding: 48 }}>\n            <Spin size=\"large\" />\n          </div>\n        ) : (\n          <CommonMailComposer\n            value={mail}\n            onChange={setMail}\n            moduleName=\"submissions\"\n            ready={!mailLoading}\n            title=\"Submit Via Mail\"\n            contextRecords={[resolved.record?.submission ?? seed]}\n          />\n        )}\n      </Drawer>\n    </>\n  );\n}\n\nManagerApproveBody.propTypes = {\n  context: PropTypes.object,\n  selectedIds: PropTypes.array,\n  selectedRecords: PropTypes.array,\n  moduleName: PropTypes.string,\n  onClose: PropTypes.func,\n};\n","// Manager Approve — a custom-body popup (see DynamicPopup's config.component\n// escape hatch). It renders the FinanceApprovalPanel (submissionManager)\n// instead of a field form, so there is no `fields`/`okText` here. Admin lists\n// this by its popupKey \"manager-approve\" and tags it to a module's Approve\n// action.\nimport ManagerApproveBody from './ManagerApproveBody.jsx';\n\nexport const config = {\n  title: 'Manager Approve',\n  width: 780,\n  className: 'fa-modal manager-approve-modal',\n  component: ManagerApproveBody,\n};\n","// Manager Approve is a custom-body popup: ManagerApproveBody owns its own\n// submit (native approve/reject via the finance panel's action bar), so the\n// framework-level submit is a no-op. Kept for POPUP registration symmetry.\nexport const api = {\n  submit: async () => {},\n};\n","// Manager Re-Approve popup body — same data resolution as ManagerApproveBody\n// (resolveSubmissionFinance), plus the CFO's rejection reason: pulled from the\n// submission's own activity log rather than a separate approval-request\n// fetch, since workforceCFOApprovalController.go pushes a submissionActivity\n// entry with activityType \"CFO Rejected\" and the real reason as\n// activityComments every time a CFO rejects. The LAST such entry is \"what the\n// CFO said most recently\" even across repeated reject/resubmit cycles.\nimport { useEffect, useMemo, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Spin, message } from 'antd';\nimport FinanceApprovalPanel from '../../../finance/FinanceApprovalPanel.jsx';\nimport { FINANCE_TYPE_SUBMISSION_MANAGER_REAPPROVE } from '../../../finance/financeApprovalConfig.js';\nimport { resolveSubmissionFinance, idOf } from '../../../finance/financeApprovalData.js';\nimport { approveSubmission, sendSubmissionForCfoApproval } from '../../../../services/popupApi';\nimport { getActivity } from '../../../../services/detailedViewApi';\n\n// firstText — first non-blank value. `??` only falls through on null/undefined,\n// so an upstream chain that resolves to '' (see submittedBy below) would stop\n// dead on it and never reach the fallbacks that exist for exactly that case.\nfunction firstText(...values) {\n  return values\n    .map((value) => (value === null || value === undefined ? '' : String(value).trim()))\n    .find(Boolean) ?? '';\n}\n\nconst sameText = (a, b) => Boolean(a) && a.toLowerCase() === firstText(b).toLowerCase();\n\n// resolveSubmittedBy — same defect and same rule as ManagerApproveBody.\n// \"Submitted By\" must name the PERSON who submitted, but\n// resolveSubmissionFinance's display.submittedBy is a `||` chain ending in\n// `flat.recruiterName || flat.submitSource` — submitSource is the submission's\n// SOURCE (\"Internal\", or a vendor; read as `vendor` one line down) and\n// recruiterName is the ASSIGNED recruiter. Real submissions store submitSource\n// but no recruiterName, so display.submittedBy came back as that source\n// string, truthy, so the correct seed.signatureEmail fallback never ran.\nfunction resolveSubmittedBy(seed, display, vendor) {\n  const resolved = firstText(display.submittedBy);\n  const isSourceLeak = sameText(resolved, vendor)\n    || sameText(resolved, seed.submitSource)\n    || sameText(resolved, seed.supplierName)\n    || sameText(resolved, seed.source)\n    || sameText(resolved, seed.candidateSource);\n  return firstText(isSourceLeak ? '' : resolved, seed.signatureEmail);\n}\n\n// Same identity-building rule as ManagerApproveBody: resolved values (form\n// groups + joins) win over the clicked row, which on the list/detail surface\n// is flattened and often stale.\nfunction buildIdentity(seed, display = {}) {\n  const vendor = display.employerName ?? seed.supplierName ?? seed.submitSource;\n  return {\n    client: display.clientName ?? seed.clientName,\n    role: display.jobTitle ?? seed.jobTitle ?? seed.designation,\n    reqId: display.reqId ?? seed.jobClientRefrenceId ?? seed.mspReqId ?? seed.submissionId,\n    name: display.candidateName\n      || [seed.firstName, seed.lastName].filter(Boolean).join(' ')\n      || seed.candidateFullName,\n    location: display.jobLocation ?? seed.city ?? seed.currentLocation ?? seed.jobLocation,\n    vendor,\n    submittedBy: resolveSubmittedBy(seed, display, vendor),\n    submittedAt: display.createdAt ?? seed.createdAt,\n    email: display.email ?? seed.email,\n    employerLocation: display.employerLocation,\n    employerName: display.employerName,\n  };\n}\n\n// lastCfoRejection — the newest submissionActivity entry the CFO reject\n// endpoint stamped. Activity lists here come back OLDEST-first (see\n// ActivityTab/timelineUtils elsewhere), so scan from the end; tolerate a\n// stray case difference rather than require an exact literal match.\nfunction lastCfoRejection(activity) {\n  const rows = Array.isArray(activity) ? activity : [];\n  for (let i = rows.length - 1; i >= 0; i -= 1) {\n    const type = String(rows[i]?.activityType ?? '').trim().toLowerCase();\n    if (type === 'cfo rejected') return rows[i];\n  }\n  return null;\n}\n\n// titleCase — capitalize each word, so a stored comment like \"the rate is too\n// high\" reads as \"The Rate Is Too High\" in the rejection banner.\nfunction titleCase(text) {\n  return String(text ?? '')\n    .toLowerCase()\n    .replace(/\\b\\w/g, (ch) => ch.toUpperCase());\n}\n\nexport default function ManagerReapproveBody({ selectedIds, selectedRecords, onClose }) {\n  const seed = selectedRecords?.[0] ?? {};\n  const submissionId = selectedIds?.[0] ?? idOf(seed);\n  const [resolved, setResolved] = useState(null);\n  const [engagementId, setEngagementId] = useState('');\n  const [loading, setLoading] = useState(true);\n\n  useEffect(() => {\n    let cancelled = false;\n    setLoading(true);\n    Promise.all([\n      resolveSubmissionFinance(submissionId, seed),\n      getActivity('submission', submissionId).catch(() => []),\n    ])\n      .then(([data, activity]) => {\n        if (cancelled) return;\n        const rejection = lastCfoRejection(activity);\n        // Linked onboarding engagement — the backend surfaces\n        // onboarding.workforceEngagementId into recordMeta; fall back to the\n        // clicked row in case it carried it. Needed to re-send to the CFO.\n        setEngagementId(idOf(data?.meta?.workforceEngagementId\n          ?? seed?.onboarding?.workforceEngagementId\n          ?? seed?.workforceEngagementId));\n        // Reason source, in order: the submission's own reject audit\n        // (internalSubmissionStatus.rejectLog.rejectReasonComments, surfaced\n        // by the backend into recordMeta = data.meta) → the last \"CFO Rejected\"\n        // activity comment. Shown Title-Cased in the banner.\n        const rawReason = data?.meta?.rejectReasonComments\n          || rejection?.activityComments\n          || '';\n        setResolved({\n          ...data,\n          record: {\n            ...data.record,\n            submission: {\n              ...data.record.submission,\n              cfoRejectionReason: rawReason ? titleCase(rawReason) : '',\n              cfoRejectedAt: data?.meta?.rejectedAt ?? rejection?.activityTime ?? null,\n            },\n          },\n        });\n      })\n      .catch((error) => {\n        if (cancelled) return;\n        message.error(error?.message ?? 'Unable to load finance details');\n        setResolved({ record: { submission: seed }, lookups: {}, display: {} });\n      })\n      .finally(() => { if (!cancelled) setLoading(false); });\n    return () => { cancelled = true; };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [submissionId]);\n\n  const actions = useMemo(() => ({\n    // \"Send For Approval\" — the re-approval's single forward action. It calls\n    // BOTH APIs: re-send the engagement to the CFO first (the critical step —\n    // if it fails the submission stays \"CFO Rejected\" so the manager can\n    // retry), then re-approve the submission to record the fixed proposed rate.\n    submissionReapproveSend: async ({ computed }) => {\n      await sendSubmissionForCfoApproval(engagementId, {\n        submissionId,\n        billRate: computed.proposedRate,\n        payRate: computed.employerRate,\n        // Currency as STORED (computed.currencyRaw), not the symbol the panel\n        // renders — the CFO request must carry the tenant's own code/symbol\n        // rather than a value normalised for display.\n        currency: computed.currencyRaw ?? computed.currency,\n        // The unit as RESOLVED, for the same reason as the currency above: the\n        // service used to hardcode 'hr' in this request body, so a monthly or\n        // yearly engagement was described to the CFO as hourly — a right number\n        // against a wrong unit, which reads as a completely different amount.\n        rateUnit: computed.rateUnit,\n        // Do not send referral data from the manager re-approval popup.\n        // The onboarding referral already stored on workforceEngagements must\n        // remain unchanged and will be copied into the new CFO request by the backend.\n        vmsPercent: computed.clientVmsPercent,\n      });\n      // context:'resend' tells the shared /submissions/approve handler this is\n      // a rate-correction RESEND (after a CFO rejection), not a fresh approval —\n      // it logs a distinct \"resent_for_approval\" activity entry instead of\n      // \"approved\", so the timeline doesn't show two approvals for one request.\n      // Unit + currency written back AS RESOLVED — a literal 'hr' here would\n      // overwrite a daily/monthly rate's unit every time it was re-approved.\n      await approveSubmission(submissionId, {\n        candidateProposedRate: computed.proposedRate,\n        candidateProposedRateCurrency: computed.currencyRaw ?? computed.currency,\n        candidateProposedRateUnit: computed.rateUnit,\n        submitVia: 'Mail',\n        context: 'resend',\n      });\n      message.success('Re-approved and sent for CFO approval');\n      onClose?.({ success: true });\n    },\n  }), [submissionId, engagementId, onClose]);\n\n  if (loading || !resolved) {\n    return <div style={{ display: 'flex', justifyContent: 'center', padding: 48 }}><Spin size=\"large\" /></div>;\n  }\n\n  return (\n    <FinanceApprovalPanel\n      type={FINANCE_TYPE_SUBMISSION_MANAGER_REAPPROVE}\n      record={resolved.record}\n      lookups={resolved.lookups}\n      identity={buildIdentity(seed, resolved.display)}\n      currentUserId={typeof localStorage !== 'undefined' ? localStorage.getItem('userId') ?? undefined : undefined}\n      actions={actions}\n      onClose={() => onClose?.()}\n      variant=\"popup\"\n    />\n  );\n}\n\nManagerReapproveBody.propTypes = {\n  selectedIds: PropTypes.array,\n  selectedRecords: PropTypes.array,\n  onClose: PropTypes.func,\n};\n","// Manager Re-Approve — a custom-body popup (see DynamicPopup's config.component\n// escape hatch), same shape as manager-approve, but for the loop-back after a\n// CFO rejection: renders FinanceApprovalPanel with type\n// submissionManagerReapprove (rejection banner + \"last rejected rate\" hint).\n// Admin tags a module's \"Re-Approve\" action to popupKey \"manager-reapprove\" —\n// gated by a Module Action Rule so it only shows when the submission's\n// internal status is \"CFO Rejected\" (see cmd/wire-submission-cfo-reapprove).\nimport ManagerReapproveBody from './ManagerReapproveBody.jsx';\n\nexport const config = {\n  title: 'Re-Approve',\n  width: 780,\n  className: 'fa-modal manager-approve-modal',\n  component: ManagerReapproveBody,\n};\n","// Manager Re-Approve is a custom-body popup: ManagerReapproveBody owns its\n// own submit (native approve/reject via the finance panel's action bar), so\n// the framework-level submit is a no-op. Kept for POPUP registration symmetry.\nexport const api = {\n  submit: async () => {},\n};\n","export const rejectionReasons = [\n  { id: 1, name: 'Re-Submission' },\n  { id: 2, name: \"Candidate doesn't fit into the profile\" },\n  { id: 3, name: 'Incomplete candidate details - (Re-Submission)' },\n];\n\nexport const config = {\n  title: 'Reject',\n  okText: 'Reject',\n  okButtonDanger: true,\n  width: 480,\n  successMessage: 'Submission rejected successfully',\n  fields: [\n    {\n      name: 'rejectReason',\n      label: 'Rejection Reasons',\n      type: 'select',\n      required: true,\n      placeholder: 'Select rejection reasons',\n      defaultOptions: rejectionReasons.map((reason) => ({ label: reason.name, value: reason.id })),\n    },\n    {\n      name: 'rejectReasonComments',\n      label: 'Comments',\n      type: 'textarea',\n      required: true,\n      rows: 4,\n    },\n  ],\n};\n","import { rejectSubmission } from '../../../../services/popupApi';\nimport { rejectionReasons } from './config';\n\nexport const api = {\n  submit: async (values, context) => {\n    // The popup's Select field normalizes every option value to a string\n    // (see fieldRegistry.normalizeSelectOptions), so values.rejectReason is\n    // \"1\"/\"2\"/\"3\" even though rejectionReasons.id is numeric — compare as\n    // strings or the lookup always misses and the reason silently blanks out.\n    const reason = rejectionReasons.find((r) => String(r.id) === String(values.rejectReason));\n    await rejectSubmission({\n      submissionId: context.selectedIds[0],\n      rejectReasonId: values.rejectReason,\n      rejectReason: reason?.name ?? '',\n      rejectReasonComments: values.rejectReasonComments,\n    });\n  },\n};\n","import { config as deleteConfig } from './delete/config';\nimport { api as deleteApi } from './delete/api';\nimport { config as quickSubmitConfig } from './quick-submit/config';\nimport { api as quickSubmitApi } from './quick-submit/api';\nimport { config as addNotesConfig } from './add-notes/config';\nimport { api as addNotesApi } from './add-notes/api';\nimport { config as tagToJobConfig } from './tag-to-job/config';\nimport { api as tagToJobApi } from './tag-to-job/api';\nimport { config as changeStatusConfig } from './change-status/config';\nimport { api as changeStatusApi } from './change-status/api';\nimport { config as removeFromShortlistConfig } from './remove-from-shortlist/config';\nimport { api as removeFromShortlistApi } from './remove-from-shortlist/api';\nimport { config as addToGroupsConfig } from './add-to-groups/config';\nimport { api as addToGroupsApi } from './add-to-groups/api';\nimport { config as selfAssignConfig } from './self-assign/config';\nimport { api as selfAssignApi } from './self-assign/api';\nimport { config as othersAssignConfig } from './others-assign/config';\nimport { api as othersAssignApi } from './others-assign/api';\nimport { config as stickyNotesConfig } from './sticky-notes/config';\nimport { api as stickyNotesApi } from './sticky-notes/api';\nimport { config as moveToOnboardingConfig } from './move-to-onboarding/config';\nimport { api as moveToOnboardingApi } from './move-to-onboarding/api';\nimport { config as approveRateConfig } from './approve-rate/config';\nimport { api as approveRateApi } from './approve-rate/api';\nimport { config as managerApproveConfig } from './manager-approve/config';\nimport { api as managerApproveApi } from './manager-approve/api';\nimport { config as managerReapproveConfig } from './manager-reapprove/config';\nimport { api as managerReapproveApi } from './manager-reapprove/api';\nimport { config as rejectConfig } from './reject/config';\nimport { api as rejectApi } from './reject/api';\n\nexport const POPUP_CONFIGS = {\n  'delete': deleteConfig,\n  'quick-submit': quickSubmitConfig,\n  'add-notes': addNotesConfig,\n  'tag-to-job': tagToJobConfig,\n  'change-status': changeStatusConfig,\n  'remove-from-shortlist': removeFromShortlistConfig,\n  'add-to-groups': addToGroupsConfig,\n  'self-assign': selfAssignConfig,\n  'others-assign': othersAssignConfig,\n  'sticky-notes': stickyNotesConfig,\n  'move-to-onboarding': moveToOnboardingConfig,\n  'approve-rate': approveRateConfig,\n  'manager-approve': managerApproveConfig,\n  'manager-reapprove': managerReapproveConfig,\n  'reject': rejectConfig,\n};\n\nconst popupApiMap = {\n  'delete': deleteApi,\n  'quick-submit': quickSubmitApi,\n  'add-notes': addNotesApi,\n  'tag-to-job': tagToJobApi,\n  'change-status': changeStatusApi,\n  'remove-from-shortlist': removeFromShortlistApi,\n  'add-to-groups': addToGroupsApi,\n  'self-assign': selfAssignApi,\n  'others-assign': othersAssignApi,\n  'sticky-notes': stickyNotesApi,\n  'move-to-onboarding': moveToOnboardingApi,\n  'approve-rate': approveRateApi,\n  'manager-approve': managerApproveApi,\n  'manager-reapprove': managerReapproveApi,\n  'reject': rejectApi,\n};\n\nexport default popupApiMap;\n","import { useEffect, useMemo, useState } from 'react';\nimport { Alert, Input, Modal, Table, message } from 'antd';\nimport { getModuleDataList } from '../../services/moduleDataApi';\nimport { createModuleRecordGeneric } from '../../services/adminApi';\nimport { getActingIdentity } from '../../services/authApi';\n\nfunction rowsFromResponse(response) {\n  const payload = response?.data ?? response;\n  if (Array.isArray(payload)) return payload;\n  return payload?.data ?? payload?.rows ?? payload?.records ?? payload?.items ?? payload?.list ?? [];\n}\n\nfunction valueFrom(record, ...keys) {\n  for (const key of keys) {\n    const value = String(key).split('.').reduce((current, part) => current?.[part], record);\n    if (value !== undefined && value !== null && value !== '') return value;\n  }\n  return '';\n}\n\nfunction isActiveAssignment(record) {\n  const deleted = String(valueFrom(record, 'isDeleted', 'deleted')).toLowerCase();\n  const status = String(valueFrom(record, 'assignmentStatus', 'status')).toLowerCase();\n  return deleted !== 'true' && deleted !== '1' && !['removed', 'inactive', 'deleted'].includes(status);\n}\n\nfunction candidateName(record) {\n  const explicit = valueFrom(record, 'candidateName', 'candidate_name', 'fullName', 'name');\n  if (explicit) return String(explicit);\n  return [valueFrom(record, 'firstName', 'first_name'), valueFrom(record, 'lastName', 'last_name')]\n    .filter(Boolean)\n    .join(' ') || 'Unnamed candidate';\n}\n\nfunction candidateId(record) {\n  return String(valueFrom(record, 'candidateId', 'candidate_id', 'candidate._id', 'candidate.id'));\n}\n\nfunction engagementId(record) {\n  return String(valueFrom(record, 'workforceEngagementId', 'engagementId', '_id', 'id'));\n}\n\nfunction batchName(record) {\n  return String(valueFrom(record, 'batchName', 'name', 'title', 'batch_name'));\n}\n\nexport default function AddBatchCandidatePopup({ open = true, context = {}, onClose }) {\n  const [rows, setRows] = useState([]);\n  const [selectedKeys, setSelectedKeys] = useState([]);\n  const [search, setSearch] = useState('');\n  const [loading, setLoading] = useState(true);\n  const [submitting, setSubmitting] = useState(false);\n  const [error, setError] = useState('');\n  const [assignedByCandidateId, setAssignedByCandidateId] = useState(new Map());\n\n  const batchId = String(context.selectedIds?.[0]\n    ?? context.selectedRecords?.[0]?._id\n    ?? context.selectedRecords?.[0]?.id\n    ?? context.batchId\n    ?? '');\n\n  useEffect(() => {\n    if (!open) return undefined;\n    let cancelled = false;\n    Promise.resolve()\n      .then(() => {\n        if (!cancelled) setLoading(true);\n        return Promise.all([\n          getModuleDataList('onboarding', 200, 0),\n          getModuleDataList('batchCandidates', 1000, 0).catch(() => []),\n        ]);\n      })\n      .then(([onboardingResponse, batchCandidatesResponse]) => {\n        if (cancelled) return;\n        setRows(rowsFromResponse(onboardingResponse));\n        setAssignedByCandidateId(new Map(\n          rowsFromResponse(batchCandidatesResponse)\n            .filter(isActiveAssignment)\n            .map((record) => [String(valueFrom(record, 'candidateId', 'candidate_id')), record])\n            .filter(([id]) => id),\n        ));\n      })\n      .catch((loadError) => {\n        if (!cancelled) setError(loadError.message || 'Unable to load onboarding candidates');\n      })\n      .finally(() => {\n        if (!cancelled) setLoading(false);\n      });\n    return () => { cancelled = true; };\n  }, [open]);\n\n  const filteredRows = useMemo(() => {\n    const query = search.trim().toLowerCase();\n    if (!query) return rows;\n    return rows.filter((record) => [\n      candidateName(record),\n      valueFrom(record, 'email', 'candidateEmail', 'candidate_email'),\n      valueFrom(record, 'status', 'onboardingStatus', 'onboarding_status'),\n    ].some((value) => String(value).toLowerCase().includes(query)));\n  }, [rows, search]);\n\n  async function handleAdd() {\n    if (!batchId) {\n      setError('Select a batch before adding candidates');\n      return;\n    }\n    const selected = rows.filter((record) => selectedKeys.includes(engagementId(record)));\n    if (!selected.length) return;\n    const alreadyAssigned = selected\n      .map((record) => ({ record, assignment: assignedByCandidateId.get(candidateId(record)) }))\n      .filter((item) => item.assignment);\n    if (alreadyAssigned.length) {\n      const names = alreadyAssigned.map(({ record }) => candidateName(record)).join(', ');\n      setError(`${names} ${alreadyAssigned.length === 1 ? 'is' : 'are'} already added to a batch. Each candidate can be added to only one batch.`);\n      return;\n    }\n\n    setSubmitting(true);\n    setError('');\n    try {\n      const { userId } = getActingIdentity();\n      const selectedBatchName = batchName(context.selectedRecords?.[0]) || batchName(context);\n      await Promise.all(selected.map((record) => createModuleRecordGeneric('batchCandidates', {\n        schemaVersion: 1,\n        batchId,\n        batchName: selectedBatchName,\n        candidateId: candidateId(record),\n        workforceEngagementId: engagementId(record),\n        source: 'ONBOARDING',\n        assignmentStatus: 'ASSIGNED',\n        assignedAt: new Date().toISOString(),\n        assignedBy: userId ?? 0,\n        isDeleted: false,\n      })));\n      message.success(`${selected.length} candidate${selected.length === 1 ? '' : 's'} added to the batch`);\n      onClose?.({ refresh: true });\n    } catch (submitError) {\n      setError(submitError.message || 'Unable to add candidates to the batch');\n    } finally {\n      setSubmitting(false);\n    }\n  }\n\n  const columns = [\n    { title: 'Candidate', key: 'candidate', render: (_, record) => candidateName(record) },\n    {\n      title: 'Email',\n      key: 'email',\n      render: (_, record) => valueFrom(record, 'email', 'candidateEmail', 'candidate_email') || '—',\n    },\n    {\n      title: 'Onboarding status',\n      key: 'status',\n      render: (_, record) => valueFrom(record, 'status', 'onboardingStatus', 'onboarding_status') || '—',\n    },\n  ];\n\n  return (\n    <Modal\n      open={open}\n      title=\"Add Candidate to Batch\"\n      okText=\"Add\"\n      onOk={handleAdd}\n      onCancel={() => onClose?.()}\n      okButtonProps={{ disabled: selectedKeys.length === 0 || !batchId, loading: submitting }}\n      cancelButtonProps={{ disabled: submitting }}\n      closable={!submitting}\n      maskClosable={false}\n      width={760}\n      centered\n    >\n      {error && <Alert type=\"error\" showIcon message={error} style={{ marginBottom: 12 }} />}\n      <Input.Search\n        allowClear\n        placeholder=\"Search onboarding candidates\"\n        value={search}\n        onChange={(event) => setSearch(event.target.value)}\n        style={{ marginBottom: 12 }}\n      />\n      <Table\n        rowKey={(record) => engagementId(record)}\n        columns={columns}\n        dataSource={filteredRows}\n        loading={loading}\n        size=\"small\"\n        pagination={{ pageSize: 10, showSizeChanger: false }}\n        rowSelection={{\n          selectedRowKeys: selectedKeys,\n          onChange: setSelectedKeys,\n          getCheckboxProps: (record) => {\n            const assignment = assignedByCandidateId.get(candidateId(record));\n            return {\n              disabled: !candidateId(record) || !engagementId(record) || Boolean(assignment),\n              title: assignment ? 'Candidate is already added to a batch' : undefined,\n            };\n          },\n        }}\n        locale={{ emptyText: loading ? 'Loading candidates…' : 'No onboarding candidates found' }}\n      />\n    </Modal>\n  );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\nimport DynamicPopup from './DynamicPopup';\nimport { POPUP_CONFIGS } from '../popupConfigs';\nimport builtInApiMap from '../definitions';\nimport { getCustomForms } from '../../../services/adminApi';\nimport { fetchJsonWithAuth } from '../../../services/authApi';\nimport { AUTH_URL } from '../../../services/apiConfig';\nimport AddBatchCandidatePopup from '../AddBatchCandidatePopup';\n\nconst POPUP_FIELD_TYPES = {\n  text: 'input',\n  string: 'input',\n  textarea: 'textarea',\n  date: 'date-picker',\n  datepicker: 'date-picker',\n  multiselect: 'multi-select',\n  lookup: 'search-select',\n};\n\nfunction toPopupConfig(form) {\n  if (!form) return null;\n  const groups = [...(form.groups ?? [])].sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0));\n  const fields = groups.flatMap((group) => (\n    [...(group.fields ?? [])]\n      .filter((field) => field.show !== 0 && field.show !== false)\n      .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0))\n      .map((field) => ({\n        ...field,\n        name: field.name ?? field.field,\n        label: field.label ?? field.field,\n        type: POPUP_FIELD_TYPES[String(field.type ?? 'text').toLowerCase()] ?? field.type ?? 'input',\n        required: field.required ?? field.req === 1,\n        options: (field.options ?? []).map((option) => ({\n          label: option.label ?? option.name ?? option.value,\n          value: option.value ?? option.id ?? option.label,\n        })),\n      }))\n  ));\n\n  // Navigation-on-success is admin-overridable, not just a literal in a popup\n  // definition file. `move-to-onboarding` ships `successNavigate: '/onboarding'`\n  // as its DEFAULT; a project that lands somewhere else sets it on the custom\n  // form and no code changes. Everything else keeps the standard behaviour of\n  // returning to the page the popup was opened over.\n  //\n  // Guarded exactly like form after-submit targets (utils/afterSubmitNav\n  // safeNavTarget): an in-app absolute path only, so an admin cannot turn a\n  // popup into an open redirect or a javascript:/data: payload.\n  const navTarget = safePopupNavTarget(form.successNavigate);\n\n  return {\n    title: form.label,\n    fields,\n    ...(navTarget ? { successNavigate: navTarget } : {}),\n  };\n}\n\n// safePopupNavTarget — see toPopupConfig. Returns null for anything that is not\n// a plain in-app path (\"/onboarding\"); \"//evil.com\" and \"javascript:…\" included.\nexport function safePopupNavTarget(value) {\n  const raw = String(value ?? '').trim();\n  if (!raw || !raw.startsWith('/') || raw.startsWith('//')) return null;\n  if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) return null;\n  return raw;\n}\n\nfunction applyPopupFieldOverrides(config, overrides = []) {\n  if (!config || !Array.isArray(overrides) || !overrides.length) return config;\n\n  const byName = new Map(\n    overrides\n      .filter((override) => override?.name)\n      .map((override) => [String(override.name), override]),\n  );\n\n  if (!byName.size) return config;\n\n  return {\n    ...config,\n    fields: (config.fields ?? []).map((field) => {\n      const override = byName.get(String(field.name))\n        ?? byName.get(String(field.label))\n        ?? (byName.size === 1 && (config.fields ?? []).length === 1 ? overrides[0] : null);\n      if (!override) return field;\n      const { name, ...fieldOverride } = override;\n      return { ...field, ...fieldOverride };\n    }),\n  };\n}\n\n/**\n * Route wrapper for DynamicPopup.\n *\n * Drop straight into your App.jsx popup routes — NO props required.\n * The built-in apiMap and POPUP_CONFIGS are used automatically:\n *\n *   <Route path=\"/popup/:popupKey\" element={<DynamicPopupRoute />} />\n *\n * To add project-specific popups alongside the built-ins:\n *\n *   const myConfigs = { 'send-offer': { title: 'Send Offer', fields: [...] } };\n *   const myApiMap  = { 'send-offer': { submit: async (values, ctx) => { ... } } };\n *   <Route path=\"/popup/:popupKey\"\n *     element={<DynamicPopupRoute apiMap={myApiMap} extraConfigs={myConfigs} />} />\n *\n * Props:\n *   apiMap       — merged on top of the built-in handlers, so you only need to\n *                  list NEW keys; built-in popup APIs (delete, add-notes, …) keep working.\n *   extraConfigs — same merge pattern for configs.\n */\nexport default function DynamicPopupRoute({ apiMap = {}, extraConfigs = {} }) {\n  // Merge: caller's entries win; built-ins fill the gaps.\n  const mergedApiMap = useMemo(() => ({ ...builtInApiMap, ...apiMap }), [apiMap]);\n  const mergedConfigs = useMemo(() => {\n    const configs = { ...POPUP_CONFIGS };\n    Object.entries(extraConfigs).forEach(([key, override]) => {\n      configs[key] = { ...(configs[key] ?? {}), ...override };\n    });\n    return configs;\n  }, [extraConfigs]);\n  const { popupKey } = useParams();\n  const navigate = useNavigate();\n  const { state = {} } = useLocation();\n\n  const [adminConfigResult, setAdminConfigResult] = useState({ key: '', config: null });\n\n  useEffect(() => {\n    let cancelled = false;\n    if (!popupKey || !state.moduleName) {\n      return undefined;\n    }\n    const lookupKey = `${state.moduleName}:${popupKey}`;\n    getCustomForms(state.moduleName, 'popup', popupKey)\n      .then((forms) => {\n        if (!cancelled) setAdminConfigResult({ key: lookupKey, config: toPopupConfig(forms[0]) });\n      })\n      .catch(() => {\n        if (!cancelled) setAdminConfigResult({ key: lookupKey, config: null });\n      });\n    return () => { cancelled = true; };\n  }, [popupKey, state.moduleName]);\n\n  const config = useMemo(() => {\n    const builtIn = mergedConfigs[popupKey];\n    const lookupKey = `${state.moduleName}:${popupKey}`;\n    const adminConfig = adminConfigResult.key === lookupKey ? adminConfigResult.config : null;\n    const baseConfig = adminConfig ? { ...builtIn, ...adminConfig } : builtIn;\n    return applyPopupFieldOverrides(baseConfig, state.popupAction?.popupFieldOverrides);\n  }, [adminConfigResult, mergedConfigs, popupKey, state.moduleName, state.popupAction?.popupFieldOverrides]);\n\n  // Memoized so that router re-renders don't create a new object reference on every tick,\n  // which would otherwise cause DynamicPopup's effects to re-run unnecessarily.\n  const context = useMemo(\n    () => ({\n      selectedIds: state.selectedIds ?? [],\n      selectedRecords: state.selectedRecords ?? [],\n      moduleName: state.moduleName ?? '',\n      navigate,\n      // The page this popup opened over (row action stamps state.background).\n      // Exposed so a custom-body popup can hand off to a SIBLING popup over the\n      // same page — e.g. Manager Approve's Reject opening the Reject popup —\n      // without the page vanishing behind it.\n      background: state.background ?? null,\n      ...(state.popupContext ?? {}),\n    }),\n    [navigate, state.selectedIds, state.selectedRecords, state.moduleName, state.popupContext, state.background],\n  );\n\n  const configuredApi = useMemo(() => {\n    const popupAction = state.popupAction;\n    if (!popupAction?.apiPath) return {};\n    return {\n      submit: (values, popupContext) => {\n        const method = String(popupAction.apiMethod || 'POST').toUpperCase();\n        return fetchJsonWithAuth(\n          AUTH_URL,\n          popupAction.apiPath.startsWith('/') ? popupAction.apiPath : `/${popupAction.apiPath}`,\n          {\n            method,\n            body: ['GET', 'DELETE'].includes(method) ? undefined : JSON.stringify({\n              ...values,\n              selectedIds: popupContext.selectedIds,\n              selectedRecords: popupContext.selectedRecords,\n              moduleName: popupContext.moduleName,\n            }),\n          },\n        );\n      },\n    };\n  }, [state.popupAction]);\n\n  // Closing a route-mounted popup returns to the page it was opened from.\n  // On a SUCCESSFUL mutation (delete, assign, change-status, tag-to-job, …)\n  // the caller passes { success: true }; we then return to the background list\n  // location stamped with a fresh `refreshTimestamp`, which ListView watches to\n  // refetch its listing (and clear the row selection) — so every module's popup\n  // actions refresh the list automatically instead of leaving stale rows on\n  // screen. A plain cancel/X (no result) just pops history, preserving the\n  // list's scroll/state untouched.\n  const handlePopupClose = (result) => {\n    const background = state.background;\n    // A popup may declare config.successNavigate to send the user to a specific\n    // route on success (e.g. Move to Onboarding → /onboarding) instead of\n    // returning to the list it was opened from. Still stamps refreshTimestamp\n    // so the destination refetches.\n    if (result?.success && config?.successNavigate) {\n      navigate(config.successNavigate, {\n        replace: true,\n        state: { refreshTimestamp: Date.now() },\n      });\n      return;\n    }\n    if (result?.success && background?.pathname) {\n      navigate(`${background.pathname}${background.search ?? ''}`, {\n        replace: true,\n        state: { ...(background.state ?? {}), refreshTimestamp: Date.now() },\n      });\n      return;\n    }\n    navigate(-1);\n  };\n\n  if (popupKey === 'add-batch-candidate') {\n    return (\n      <AddBatchCandidatePopup\n        open\n        context={context}\n        onClose={handlePopupClose}\n      />\n    );\n  }\n\n  return (\n    <DynamicPopup\n      open\n      config={config}\n      context={context}\n      onClose={handlePopupClose}\n      api={{ ...(mergedApiMap[popupKey] ?? {}), ...configuredApi }}\n    />\n  );\n}\n","export const config = {\n  title: 'Vendor Share',\n  maxVendorSelect: 1000,\n  defaultTab: 'myVendor',\n  defaultPageSize: 10,\n  vendorTabs: [\n    { key: 'myVendor', label: 'My Vendors' },\n    { key: 'allVendor', label: 'All Vendors' },\n  ],\n  vendorColumns: [\n    { title: 'Vendor Name', dataIndex: 'vendorName', key: 'vendorName' },\n    { title: 'Email', dataIndex: 'vendorEmail', key: 'vendorEmail' },\n    { title: 'Location', dataIndex: 'vendorLocation', key: 'vendorLocation' },\n    { title: 'Updated On', dataIndex: 'updatedOn', key: 'updatedOn' },\n  ],\n};\n","import { getGroupedVendorHotlist, getBulkMailDetails, sendBulkMail } from '../../../../services/dropdownApi';\n\nexport const api = {\n  getVendorList: ({ jobId, limit, offset, type }) =>\n    getGroupedVendorHotlist({ jobId, limit, offset, sortBy: 'new', type }),\n\n  getMailDetails: (jobId) => getBulkMailDetails(jobId),\n\n  submit: ({ jobId, toMail, ccMail, bccMail, subject, contents }) =>\n    sendBulkMail({ jobId, toMail, ccMail, bccMail, subject, contents }),\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport { Button, Drawer, Input, message, Table } from 'antd';\nimport { CloseOutlined, SearchOutlined, TeamOutlined } from '@ant-design/icons';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { config } from './definitions/vendor-share/config';\nimport { api } from './definitions/vendor-share/api';\nimport CustomPagination from '../CustomPagination';\nimport CommonMailComposer from './CommonMailComposer';\nimport { areValidEmails, parseEmails } from './mailUtils';\n\nconst vendorColumns = config.vendorColumns.map((col) => ({\n  ...col,\n  render: (val) => val || '-',\n}));\n\nexport default function VendorShareDrawer() {\n  const navigate = useNavigate();\n  const location = useLocation();\n  const {\n    selectedIds = [],\n    selectedRecords = [],\n    recipients = [],\n    subject: initialSubject = '',\n    onSend,\n    moduleName = '',\n    popupAction = {},\n  } = location.state ?? {};\n\n  const jobId = selectedIds[0] ?? selectedRecords[0]?._id ?? selectedRecords[0]?.id;\n\n  const [mail, setMail] = useState({ to: recipients.join(', '), cc: '', bcc: '', subject: initialSubject, contents: '', showCc: false, showBcc: false });\n  const [detailsLoaded, setDetailsLoaded] = useState(!jobId);\n\n  const [vendorTab, setVendorTab] = useState(config.defaultTab);\n  const [vendorSearch, setVendorSearch] = useState('');\n  const [vendors, setVendors] = useState([]);\n  const [myVendorCount, setMyVendorCount] = useState(0);\n  const [allVendorCount, setAllVendorCount] = useState(0);\n  const [vendorTotal, setVendorTotal] = useState(0);\n  const [vendorPage, setVendorPage] = useState(1);\n  const [vendorPageSize, setVendorPageSize] = useState(config.defaultPageSize);\n  const [vendorLoading, setVendorLoading] = useState(false);\n  const [selectedVendorKeys, setSelectedVendorKeys] = useState([]);\n\n  useEffect(() => {\n    if (!jobId) return;\n    let cancelled = false;\n    setVendorLoading(true);\n    const limit = vendorSearch ? 100 : vendorPageSize;\n    const offset = vendorSearch ? 0 : (vendorPage - 1) * vendorPageSize;\n    api.getVendorList({ jobId, limit, offset, type: vendorTab })\n      .then((res) => {\n        if (cancelled) return;\n        const vendorList = res?.data?.vendorList ?? res?.data ?? [];\n        const myCount = res?.data?.myVendorCount ?? 0;\n        const allCount = res?.data?.allVendorCount ?? 0;\n        setVendors(Array.isArray(vendorList) ? vendorList : []);\n        setMyVendorCount(myCount);\n        setAllVendorCount(allCount);\n        setVendorTotal(vendorTab === 'myVendor' ? myCount : allCount);\n      })\n      .catch(() => { if (!cancelled) { setVendors([]); setVendorTotal(0); } })\n      .finally(() => { if (!cancelled) setVendorLoading(false); });\n    return () => { cancelled = true; };\n  }, [jobId, vendorTab, vendorPage, vendorPageSize, vendorSearch]);\n\n  useEffect(() => {\n    if (!jobId) return;\n    api.getMailDetails(jobId).then((data) => setMail((current) => ({\n      ...current,\n      subject: data.subject || current.subject,\n      contents: data.contents || current.contents,\n      to: data.toMail?.length ? (Array.isArray(data.toMail) ? data.toMail.join(', ') : String(data.toMail)) : current.to,\n      cc: data.ccMail?.length ? (Array.isArray(data.ccMail) ? data.ccMail.join(', ') : String(data.ccMail)) : current.cc,\n    }))).catch(() => {}).finally(() => setDetailsLoaded(true));\n  }, [jobId]);\n\n  const selectedVendorEmails = useMemo(() => selectedVendorKeys\n    .map((key) => vendors.find((vendor) => vendor.vendorId === key)?.vendorEmail ?? '')\n    .filter(Boolean), [selectedVendorKeys, vendors]);\n\n  const composerMail = useMemo(() => ({\n    ...mail,\n    bcc: [...new Set([...parseEmails(mail.bcc), ...selectedVendorEmails])].join(', '),\n    showBcc: mail.showBcc || selectedVendorEmails.length > 0,\n  }), [mail, selectedVendorEmails]);\n\n  function handleComposerChange(next) {\n    const vendorSet = new Set(selectedVendorEmails);\n    setMail({ ...next, bcc: parseEmails(next.bcc).filter((email) => !vendorSet.has(email)).join(', ') });\n  }\n\n  const canSend = (parseEmails(composerMail.to).length || parseEmails(composerMail.bcc).length)\n    && areValidEmails(composerMail.to) && areValidEmails(composerMail.cc) && areValidEmails(composerMail.bcc) && composerMail.subject.trim();\n  const tabCount = (key) => key === 'myVendor' ? myVendorCount : allVendorCount;\n\n  function handleClose() { navigate(-1); }\n\n  function handleSend() {\n    if (!canSend) return;\n    api.submit({\n      jobId,\n      toMail: parseEmails(composerMail.to),\n      ccMail: parseEmails(composerMail.cc),\n      bccMail: parseEmails(composerMail.bcc),\n      subject: composerMail.subject,\n      contents: composerMail.contents,\n    }).then((res) => {\n      if (res?.status === true) {\n        message.success(res?.data || 'Mail sent successfully.');\n        if (typeof onSend === 'function') onSend({ ...composerMail, message: composerMail.contents, selectedIds });\n        navigate(-1);\n      } else {\n        message.error(res?.message || res?.data || 'Failed to send mail. Please try again.');\n      }\n    }).catch((err) => { message.error(err?.message || 'Failed to send mail. Please try again.'); });\n  }\n\n  const filteredVendors = useMemo(() => {\n    if (!vendorSearch) return vendors;\n    const q = vendorSearch.toLowerCase();\n    return vendors.filter((v) =>\n      (v.vendorName ?? '').toLowerCase().includes(q)\n      || (v.vendorEmail ?? '').toLowerCase().includes(q)\n      || (v.vendorLocation ?? '').toLowerCase().includes(q),\n    );\n  }, [vendors, vendorSearch]);\n\n  const footer = (\n    <div className=\"vendor-share__footer\">\n      <Button onClick={handleClose}>Cancel</Button>\n      <Button type=\"primary\" disabled={!canSend} onClick={handleSend}>Send</Button>\n    </div>\n  );\n\n  return (\n    <Drawer\n      open\n      placement=\"right\"\n      onClose={handleClose}\n      closable={false}\n      rootClassName=\"vendor-share\"\n      width=\"95%\"\n      footer={footer}\n    >\n      <div className=\"vendor-share__body\">\n\n        {/* ── Left: Vendor List ── */}\n        <div className=\"vendor-share__left\">\n          {/* vendor-header: close + title + search (flex row), tabs below */}\n          <div className=\"vendor-share__vendor-header\">\n            <div className=\"vendor-share__vendor-header-row\">\n              <Button\n                type=\"text\"\n                icon={<CloseOutlined />}\n                onClick={handleClose}\n                size=\"small\"\n                style={{ marginRight: 8 }}\n              />\n              <span className=\"dynamic-popup__header-icon-box\">\n                <TeamOutlined />\n              </span>\n              <span className=\"dynamic-popup__header-label\">Vendor List</span>\n              {/* margin-left:auto in CSS pushes search to the right */}\n              <div className=\"vendor-share__vendor-search\">\n                <SearchOutlined className=\"vendor-share__search-icon\" />\n                <Input\n                  variant=\"borderless\"\n                  placeholder=\"Search vendor\"\n                  value={vendorSearch}\n                  onChange={(e) => { setVendorSearch(e.target.value); setVendorPage(1); }}\n                  className=\"vendor-share__search-input\"\n                />\n              </div>\n            </div>\n\n            <div className=\"vendor-share__vendor-tabs\">\n              {config.vendorTabs.map((tab) => (\n                <span\n                  key={tab.key}\n                  className={`vendor-share__vendor-tab${vendorTab === tab.key ? ' vendor-share__vendor-tab--active' : ''}`}\n                  onClick={() => { setVendorTab(tab.key); setVendorPage(1); setSelectedVendorKeys([]); }}\n                >\n                  {tab.label} ({tabCount(tab.key)})\n                </span>\n              ))}\n            </div>\n          </div>\n\n          <div className=\"vendor-share__vendor-table-wrapper\">\n            <Table\n              rowKey={(record) => record.vendorId}\n              columns={vendorColumns}\n              dataSource={filteredVendors}\n              loading={vendorLoading}\n              pagination={false}\n              size=\"small\"\n              rowSelection={{\n                selectedRowKeys: selectedVendorKeys,\n                onChange: (keys) => {\n                  if (keys.length > config.maxVendorSelect) return;\n                  setSelectedVendorKeys(keys);\n                },\n              }}\n              scroll={{ y: 'calc(100vh - 340px)' }}\n            />\n          </div>\n\n          <div className=\"vendor-share__vendor-footer\">\n            <CustomPagination\n              current={vendorPage}\n              pageSize={vendorPageSize}\n              total={vendorTotal}\n              onChange={(page) => setVendorPage(page)}\n              onPageSizeChange={(size) => setVendorPageSize(size)}\n            />\n          </div>\n        </div>\n\n        {/* ── Right: Share / Compose ── */}\n        <div className=\"vendor-share__right\">\n          <CommonMailComposer\n            value={composerMail}\n            onChange={handleComposerChange}\n            moduleName={moduleName}\n            defaultTemplateId={popupAction.defaultTemplateId ?? location.state?.defaultTemplateId ?? ''}\n            ready={detailsLoaded}\n            contextRecords={selectedRecords}\n            title=\"Share\"\n            hint=\"Select vendors or add email addresses\"\n            bccHint=\"Vendor emails are added automatically\"\n            afterBcc={selectedVendorKeys.length > 0 ? <div className=\"vendor-share__selected-count\">{selectedVendorKeys.length} / {config.maxVendorSelect} Vendors selected</div> : null}\n          />\n        </div>\n\n      </div>\n    </Drawer>\n  );\n}\n","// /// validationRules.js\n\nimport { message } from \"antd\";\nimport dayjs from \"dayjs\";\n\n// // ==========================\n// // REGEX CONSTANTS\n// // ==========================\n// export const REGEX = {\n//   EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n\n//   PHONE: /^[0-9]{10}$/,\n\n//   PASSWORD:\n//     /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$/,\n\n//   ALPHABETS: /^[A-Za-z ]+$/,\n\n//   ALPHANUMERIC: /^[A-Za-z0-9 ]+$/,\n\n//   NUMBER: /^[0-9]+$/,\n\n//   URL: /^(https?:\\/\\/)?([\\w.-]+)+(:\\d+)?(\\/([\\w/_.]*)?)?$/,\n\n//   CANDIDATE_ID: /^[A-Za-z0-9-]+$/,\n\n//   REMARKS: /^[A-Za-z0-9\\s.,'\"\\-()!?/@#$%&]*$/,\n\n//   DESIGNATION: /^[a-zA-Z0-9\\s,.\\-&()]{2,100}$/,\n\n//   DOB: /^(0[1-9]|1[0-2])\\/(0[1-9]|[12][0-9]|3[01])\\/\\d{4}$/,\n\n//   LINKEDIN:\n//     /^(https?:\\/\\/)?(www\\.)?linkedin\\.com\\/(in|company)\\/[a-zA-Z0-9-_%]+\\/?$/i,\n\n//   COMPANY_NAME: /^[A-Za-z0-9\\s&.,'()-]+$/,\n// };\n\n// // ==========================\n// // COMMON VALIDATION MESSAGES\n// // ==========================\n// export const VALIDATION_MESSAGES = {\n//   REQUIRED: (field) => `Mandatory field`,\n\n//   INVALID_EMAIL: \"Please enter valid email.\",\n\n//   INVALID_PHONE: \"Phone number must contain exactly 10 digits.\",\n\n//   INVALID_PASSWORD:\n//     \"Password must contain uppercase, lowercase, number, special character and minimum 8 characters.\",\n\n//   INVALID_ALPHABETS: \"Only alphabets and spaces are allowed.\",\n\n//   INVALID_ALPHANUMERIC:\n//     \"Only letters, numbers and spaces are allowed.\",\n\n//   INVALID_NUMBER: \"Only numbers are allowed.\",\n\n//   INVALID_URL: \"Please enter a valid URL.\",\n\n//   INVALID_CANDIDATE_ID:\n//     \"Candidate ID can contain only letters, numbers and hyphens.\",\n\n//   INVALID_REMARKS: \"Remarks contain invalid characters.\",\n\n//   INVALID_DESIGNATION:\n//     \"Designation contains invalid characters.\",\n\n//   INVALID_DOB: \"DOB must be in MM/DD/YYYY format.\",\n\n//   INVALID_LINKEDIN:\n//     \"Please enter a valid LinkedIn URL.\",\n\n//   INVALID_COMPANY_NAME:\n//     \"Company name contains invalid characters.\",\n// };\n\n// // ==========================\n// // COMMON RULE GENERATOR\n// // ==========================\n// export const validationRules = {\n//   required: (fieldName = \"Field\") => ({\n//     required: true,\n//     message: VALIDATION_MESSAGES.REQUIRED(fieldName),\n//   }),\n\n//   email: () => ({\n//     pattern: REGEX.EMAIL,\n//     message: VALIDATION_MESSAGES.INVALID_EMAIL,\n//   }),\n\n//   phone: () => ({\n//     pattern: REGEX.PHONE,\n//     message: VALIDATION_MESSAGES.INVALID_PHONE,\n//   }),\n\n//   password: () => ({\n//     pattern: REGEX.PASSWORD,\n//     message: VALIDATION_MESSAGES.INVALID_PASSWORD,\n//   }),\n\n//   alphabets: () => ({\n//     pattern: REGEX.ALPHABETS,\n//     message: VALIDATION_MESSAGES.INVALID_ALPHABETS,\n//   }),\n\n//   alphanumeric: () => ({\n//     pattern: REGEX.ALPHANUMERIC,\n//     message: VALIDATION_MESSAGES.INVALID_ALPHANUMERIC,\n//   }),\n\n//   number: () => ({\n//     pattern: REGEX.NUMBER,\n//     message: VALIDATION_MESSAGES.INVALID_NUMBER,\n//   }),\n\n//   url: () => ({\n//     pattern: REGEX.URL,\n//     message: VALIDATION_MESSAGES.INVALID_URL,\n//   }),\n\n//   candidateId: () => ({\n//     pattern: REGEX.CANDIDATE_ID,\n//     message: VALIDATION_MESSAGES.INVALID_CANDIDATE_ID,\n//   }),\n\n//   remarks: () => ({\n//     pattern: REGEX.REMARKS,\n//     message: VALIDATION_MESSAGES.INVALID_REMARKS,\n//   }),\n\n//   designation: () => ({\n//     pattern: REGEX.DESIGNATION,\n//     message: VALIDATION_MESSAGES.INVALID_DESIGNATION,\n//   }),\n\n//   dob: () => ({\n//     pattern: REGEX.DOB,\n//     message: VALIDATION_MESSAGES.INVALID_DOB,\n//   }),\n\n//   linkedin: () => ({\n//     pattern: REGEX.LINKEDIN,\n//     message: VALIDATION_MESSAGES.INVALID_LINKEDIN,\n//   }),\n\n//   companyName: () => ({\n//     pattern: REGEX.COMPANY_NAME,\n//     message: VALIDATION_MESSAGES.INVALID_COMPANY_NAME,\n//   }),\n// };\n\n\n\n\n/// validationRules.js\n\n// ==========================\n// REGEX CONSTANTS\n// ==========================\nexport const REGEX = {\n    EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z][a-zA-Z-]*\\.[a-zA-Z]{2,}$/,\n\n    PHONE: /^[0-9]{10}$/,\n\n    PASSWORD:\n        /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$/,\n\n    ALPHABETS: /^[A-Za-z ]+$/,\n\n    ALPHANUMERIC: /^(?!\\s)[A-Za-z0-9 ]+$/,\n\n    NUMBER: /^[0-9]+$/,\n\n    URL: /^(https?:\\/\\/)?(www\\.)?([a-zA-Z0-9-]+\\.)+(com|org|net|in|co|io|gov|edu)(\\/[^\\s]*)?$/i,\n\n    CANDIDATE_ID: /^[A-Za-z0-9-]+$/,\n\n    REMARKS: /^[A-Za-z0-9\\s.,'\"\\-()!?/@#$%&]*$/,\n\n    DESIGNATION: /^[a-zA-Z0-9\\s,.\\-&()]{2,100}$/,\n\n    DOB: /^(0[1-9]|1[0-2])\\/(0[1-9]|[12][0-9]|3[01])\\/\\d{4}$/,\n\n    COMPANY_NAME: /^[A-Za-z0-9\\s&.,'()-]+$/,\n\n    // First Letter Caps + No Spaces\n    FIRST_NAME: /^[A-Z][a-zA-Z]*$/,\n\n    // Capitalize Every Word + No Double Spaces\n    FULL_NAME: /^[A-Z][a-zA-Z]*(?: [A-Z][a-zA-Z]*)*$/,\n\n    // No Spaces Allowed\n    NO_SPACES: /^\\S+$/,\n\n    // Starts With Capital\n    STARTS_WITH_CAPITAL: /^[A-Z].*$/,\n};\nexport const FILE_VALIDATION = {\n    SINGLE_FILE_COUNT: 1,\n    MULTI_FILE_COUNT: 5,\n\n    MAX_FILE_SIZE: 2, // MB\n\n    ALLOWED_FILE_TYPES: [\n        \"image/jpeg\",\n        \"image/png\",\n        \"application/pdf\",\n    ],\n};\n// ==========================\n// VALIDATION MESSAGES\n// ==========================\nexport const VALIDATION_MESSAGES = {\n    REQUIRED: (field) => `Mandatory Field`,\n\n    INVALID_EMAIL: \"Please enter a valid email address.\",\n\n    INVALID_PHONE: \"Phone number must contain exactly 10 digits.\",\n\n    INVALID_PASSWORD:\n        \"Password must contain uppercase, lowercase, number, special character and minimum 8 characters.\",\n\n    INVALID_ALPHABETS: \"Only alphabets and spaces are allowed.\",\n\n    INVALID_ALPHANUMERIC:\n        \"Only letters, numbers and spaces are allowed.\",\n\n    INVALID_NUMBER: \"Only numbers are allowed.\",\n\n    INVALID_URL: \"Please enter a valid URL.\",\n\n    INVALID_CANDIDATE_ID: (field) => `${field} can contain only letters, numbers and hyphens.`,\n\n    INVALID_REMARKS: \"Remarks contain invalid characters.\",\n\n    INVALID_DESIGNATION:\n        \"Designation contains invalid characters.\",\n\n    INVALID_DOB: \"DOB must be in MM/DD/YYYY format.\",\n\n    INVALID_LINKEDIN:\n        \"Please enter a valid LinkedIn URL.\",\n\n    INVALID_COMPANY_NAME:\n        \"Company name contains invalid characters.\",\n\n    INVALID_FIRST_NAME:\n        \"First letter must be capital and spaces are not allowed.\",\n\n    INVALID_FULL_NAME:\n        \"Each word must start with a capital letter.\",\n\n    NO_SPACES_ALLOWED: \"Spaces are not allowed.\",\n\n    MUST_START_WITH_CAPITAL:\n        \"First letter must be capital.\",\n\n    INVALID_FILE_TYPE:\n        \"Only JPG, PNG and PDF files are allowed.\",\n\n    INVALID_FILE_SIZE:\n        `File upload must be ${FILE_VALIDATION.MAX_FILE_SIZE} MB below.`,\n\n    INVALID_FILE_TYPE:\n        \"Only JPG, PNG and PDF files are allowed.\",\n\n    SINGLE_FILE_ONLY:\n        \"Only one file can be uploaded.\",\n};\n\n// ==========================\n// COMMON FORMATTERS\n// ==========================\nexport const VALIDATION_LENGTH_NAME = {\n    FIRST_NAME_MIN: 3,\n    FIRST_NAME_MAX: 30,\n};\n\nexport const VALIDATION_LENGTH_REMARKS = {\n    REMARKS_MIN: 10,\n    REMARKS_MAX: 250,\n};\nexport const formatters = {\n    // Remove all spaces\n    removeSpaces: (value = \"\") => value.replace(/\\s/g, \"\"),\n\n    // First letter capital\n    capitalizeFirstLetter: (value = \"\") =>\n        value.charAt(0).toUpperCase() + value.slice(1),\n\n    // Capitalize every word\n    capitalizeWords: (value = \"\") =>\n        value.replace(/\\b\\w/g, (char) => char.toUpperCase()),\n\n    // Remove extra spaces\n    removeExtraSpaces: (value = \"\") =>\n        value.replace(/\\s+/g, \" \").trim(),\n\n    // First Name Formatter\n    firstNameFormatter: (value = \"\") => {\n        return value\n            .replace(/\\s+/g, \" \") // remove extra spaces\n            .trimStart() // no starting spaces\n            .replace(/\\b\\w/g, (char) => char.toUpperCase());\n    },\n\n    // Full Name Formatter\n    fullNameFormatter: (value = \"\") => {\n        return value\n            .replace(/\\s+/g, \" \")\n            .trimStart()\n            .replace(/\\b\\w/g, (char) => char.toUpperCase());\n    },\n    phoneFormatter: (value = \"\") =>\n        value.replace(/\\D/g, \"\").slice(0, 10),\n\n    dobFormatter: (value = \"\") => {\n\n        // remove non-numeric\n        const cleaned = value.replace(/\\D/g, \"\");\n\n        // format DD/MM/YYYY\n        if (cleaned.length <= 2) {\n            return cleaned;\n        }\n\n        if (cleaned.length <= 4) {\n            return `${cleaned.slice(0, 2)}/${cleaned.slice(2)}`;\n        }\n\n        return `${cleaned.slice(0, 2)}/${cleaned.slice(\n            2,\n            4\n        )}/${cleaned.slice(4, 8)}`;\n    },\n};\n\n// ==========================\n// COMMON RULE GENERATOR\n// ==========================\nexport const validationRules = {\n    required: (fieldName = \"Field\") => ({\n        required: true,\n        message: VALIDATION_MESSAGES.REQUIRED(fieldName),\n    }),\n\n    email: () => ({\n        pattern: REGEX.EMAIL,\n        message: VALIDATION_MESSAGES.INVALID_EMAIL,\n    }),\n\n    phone: () => ({\n        pattern: REGEX.PHONE,\n        message: VALIDATION_MESSAGES.INVALID_PHONE,\n    }),\n\n    password: () => ({\n        pattern: REGEX.PASSWORD,\n        message: VALIDATION_MESSAGES.INVALID_PASSWORD,\n    }),\n\n    alphabets: () => ({\n        pattern: REGEX.ALPHABETS,\n        message: VALIDATION_MESSAGES.INVALID_ALPHABETS,\n    }),\n\n    alphanumeric: () => ({\n        pattern: REGEX.ALPHANUMERIC,\n        message: VALIDATION_MESSAGES.INVALID_ALPHANUMERIC,\n    }),\n\n    number: () => ({\n        pattern: REGEX.NUMBER,\n        message: VALIDATION_MESSAGES.INVALID_NUMBER,\n    }),\n\n    url: () => ({\n        pattern: REGEX.URL,\n        message: VALIDATION_MESSAGES.INVALID_URL,\n    }),\n\n    // candidateId: () => ({\n    //     pattern: REGEX.CANDIDATE_ID,\n    //     message: VALIDATION_MESSAGES.INVALID_CANDIDATE_ID,\n    // }),\n    candidateId: (field = \"ID\") => ({\n        pattern: REGEX.CANDIDATE_ID,\n        message:\n            VALIDATION_MESSAGES.INVALID_CANDIDATE_ID(\n                field\n            ),\n    }),\n    remarks: () => ({\n        pattern: REGEX.REMARKS,\n        message: VALIDATION_MESSAGES.INVALID_REMARKS,\n        REMARKS_MIN:\n            `Remarks must be at least ${VALIDATION_LENGTH_REMARKS.REMARKS_MIN} characters.`,\n        REMARKS_MAX:\n            `Remarks must not exceed ${VALIDATION_LENGTH_REMARKS.REMARKS_MAX} characters.`,\n    }),\n\n    designation: () => ({\n        pattern: REGEX.DESIGNATION,\n        message: VALIDATION_MESSAGES.INVALID_DESIGNATION,\n    }),\n\n    dob: (required = true) => ({\n        validator: (_, value) => {\n\n            // Required check\n            if (!value) {\n                return required\n                    ? Promise.reject(\n                        new Error(\"Date of Birth is required.\")\n                    )\n                    : Promise.resolve();\n            }\n\n            // MM/DD/YYYY regex check\n            if (!REGEX.DOB.test(value)) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.INVALID_DOB\n                    )\n                );\n            }\n\n            // Strict date validation\n            const dob = dayjs(\n                value,\n                \"MM/DD/YYYY\",\n                true\n            );\n\n            if (!dob.isValid()) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.INVALID_DOB\n                    )\n                );\n            }\n\n            // Future date validation\n            const today = dayjs().endOf(\"day\");\n\n            if (dob.isAfter(today)) {\n                return Promise.reject(\n                    new Error(\n                        \"Date of Birth cannot be a future date.\"\n                    )\n                );\n            }\n\n            // Age validation\n            const age = today.diff(dob, \"year\");\n\n            if (age < 21) {\n                return Promise.reject(\n                    new Error(\n                        \"Age must be at least 21 years.\"\n                    )\n                );\n            }\n\n            return Promise.resolve();\n        },\n    }),\n\n    linkedin: () => ({\n        pattern: REGEX.LINKEDIN,\n        message: VALIDATION_MESSAGES.INVALID_LINKEDIN,\n    }),\n\n    companyName: () => ({\n        pattern: REGEX.COMPANY_NAME,\n        message: VALIDATION_MESSAGES.INVALID_COMPANY_NAME,\n    }),\n\n    firstName: () => ({\n        pattern: REGEX.FIRST_NAME,\n        message: VALIDATION_MESSAGES.INVALID_FIRST_NAME,\n        FIRST_NAME_MIN:\n            `First Name must be at least ${VALIDATION_LENGTH_NAME.FIRST_NAME_MIN} characters.`,\n        FIRST_NAME_MAX:\n            `First Name must not exceed ${VALIDATION_LENGTH_NAME.FIRST_NAME_MAX} characters.`,\n    }),\n    firstNameMinLength: () => ({\n        min: VALIDATION_LENGTH_NAME.FIRST_NAME_MIN,\n        message: VALIDATION_MESSAGES.FIRST_NAME_MIN,\n    }),\n\n    firstNameMaxLength: () => ({\n        max: VALIDATION_LENGTH_NAME.FIRST_NAME_MAX,\n        message: VALIDATION_MESSAGES.FIRST_NAME_MAX,\n    }),\n\n    remarksMinLength: () => ({\n        min: VALIDATION_LENGTH_REMARKS.REMARKS_MIN,\n        message: VALIDATION_MESSAGES.REMARKS_MIN,\n    }),\n\n    remarksMaxLength: () => ({\n        max: VALIDATION_LENGTH_REMARKS.REMARKS_MAX,\n        message: VALIDATION_MESSAGES.REMARKS_MAX,\n    }),\n    fullName: () => ({\n        pattern: REGEX.FULL_NAME,\n        message: VALIDATION_MESSAGES.INVALID_FULL_NAME,\n    }),\n\n    noSpaces: () => ({\n        pattern: REGEX.NO_SPACES,\n        message: VALIDATION_MESSAGES.NO_SPACES_ALLOWED,\n    }),\n\n    startsWithCapital: () => ({\n        pattern: REGEX.STARTS_WITH_CAPITAL,\n        message: VALIDATION_MESSAGES.MUST_START_WITH_CAPITAL,\n    }),\n    fileUpload: () => ({\n        validator: (_, fileList) => {\n\n            if (!fileList || fileList.length === 0) {\n                return Promise.resolve();\n            }\n\n            for (let fileObj of fileList) {\n\n                const file =\n                    fileObj.originFileObj || fileObj;\n\n                // File size validation\n                const isValidSize =\n                    file.size / 1024 / 1024 <=\n                    FILE_VALIDATION.MAX_FILE_SIZE;\n\n                if (!isValidSize) {\n\n                    message.error(\n                        VALIDATION_MESSAGES.INVALID_FILE_SIZE\n                    );\n\n                    return Promise.reject(\n                        new Error(\n                            VALIDATION_MESSAGES.INVALID_FILE_SIZE\n                        )\n                    );\n                }\n\n                // File type validation\n                const isValidType =\n                    FILE_VALIDATION.ALLOWED_FILE_TYPES.includes(\n                        file.type\n                    );\n\n                if (!isValidType) {\n                    return Promise.reject(\n                        new Error(\n                            VALIDATION_MESSAGES.INVALID_FILE_TYPE\n                        )\n                    );\n                }\n            }\n\n            return Promise.resolve();\n        },\n    }),\n    singleFileUpload: () => ({\n        validator: (_, fileList) => {\n\n            if (!fileList || fileList.length === 0) {\n                return Promise.resolve();\n            }\n\n            // Single file check\n            if (\n                fileList.length >\n                FILE_VALIDATION.SINGLE_FILE_COUNT\n            ) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.SINGLE_FILE_ONLY\n                    )\n                );\n            }\n\n            const file = fileList[0];\n\n            // File size validation\n            const isValidSize =\n                file.size / 1024 / 1024 <\n                FILE_VALIDATION.MAX_FILE_SIZE;\n\n            if (!isValidSize) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.INVALID_FILE_SIZE\n                    )\n                );\n            }\n\n            // File type validation\n            const isValidType =\n                FILE_VALIDATION.ALLOWED_FILE_TYPES.includes(\n                    file.type\n                );\n\n            if (!isValidType) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.INVALID_FILE_TYPE\n                    )\n                );\n            }\n\n            return Promise.resolve();\n        },\n    }),\n\n    // Multiple File Upload\n    multiFileUpload: () => ({\n        validator: (_, fileList) => {\n\n            if (!fileList || fileList.length === 0) {\n                return Promise.resolve();\n            }\n\n            // File count validation\n            if (\n                fileList.length >\n                FILE_VALIDATION.MULTI_FILE_COUNT\n            ) {\n                return Promise.reject(\n                    new Error(\n                        VALIDATION_MESSAGES.INVALID_FILE_COUNT\n                    )\n                );\n            }\n\n            for (let file of fileList) {\n\n                // File size validation\n                const isValidSize =\n                    file.size / 1024 / 1024 <\n                    FILE_VALIDATION.MAX_FILE_SIZE;\n\n                if (!isValidSize) {\n                    return Promise.reject(\n                        new Error(\n                            VALIDATION_MESSAGES.INVALID_FILE_SIZE\n                        )\n                    );\n                }\n\n                // File type validation\n                const isValidType =\n                    FILE_VALIDATION.ALLOWED_FILE_TYPES.includes(\n                        file.type\n                    );\n\n                if (!isValidType) {\n                    return Promise.reject(\n                        new Error(\n                            VALIDATION_MESSAGES.INVALID_FILE_TYPE\n                        )\n                    );\n                }\n            }\n\n            return Promise.resolve();\n        },\n    }),\n};\n","/// UserForm.jsx\n\nimport React from \"react\";\nimport { Form, Input, Button, Row, Col, Space, Select, Upload, message } from \"antd\";\nimport { formatters, validationRules } from \"./validation\";\nimport { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';\n\nexport const uploadValidation = {\n\n    beforeUpload: (file) => {\n\n        const allowedTypes = [\n            \"image/jpeg\",\n            \"image/png\",\n            \"application/pdf\",\n        ];\n\n        const isValidType =\n            allowedTypes.includes(file.type);\n\n        if (!isValidType) {\n\n            message.error(\n                \"Only JPG, PNG and PDF files are allowed.\"\n            );\n\n            // Prevent file from upload list\n            return Upload.LIST_IGNORE;\n        }\n\n        const isValidSize =\n            file.size / 1024 / 1024 <= 2;\n\n        if (!isValidSize) {\n\n            message.error(\n                \"File upload must be 2 MB below.\"\n            );\n\n            // Prevent file from upload list\n            return Upload.LIST_IGNORE;\n        }\n\n        // Prevent auto upload\n        return false;\n    },\n};\nconst UserForm = () => {\n    const [form] = Form.useForm();\n\n    const onFinish = (values) => {\n        console.log(\"Form Values:\", values);\n    };\n\n    return (\n        <div style={{ padding: 24 }}>\n            <Form\n                form={form}\n                layout=\"vertical\"\n                onFinish={onFinish}\n                autoComplete=\"off\"\n            >\n                <Row gutter={16}>\n                    {/* EMAIL */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Email\"\n                            name=\"email\"\n                            rules={[\n                                validationRules.required(\"Email\"),\n                                validationRules.email(),\n                            ]}\n                        >\n                            <Input />\n                        </Form.Item>\n                    </Col>\n\n                    {/* PHONE */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Phone Number\"\n                            name=\"phone\"\n                            rules={[\n                                validationRules.required(\"Phone Number\"),\n                                validationRules.phone(),\n                            ]}\n                            validateTrigger={[\"onBlur\", \"onChange\"]}\n                        >\n                            <Input\n                                maxLength={10}\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        phone: formatters.phoneFormatter(\n                                            e.target.value\n                                        ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* PASSWORD */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Password\"\n                            name=\"password\"\n                            rules={[\n                                validationRules.required(\"Password\"),\n                                validationRules.password(),\n                            ]}\n                        >\n                            <Input.Password />\n                        </Form.Item>\n                    </Col>\n\n                    {/* FULL NAME */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Full Name\"\n                            name=\"fullName\"\n                            rules={[\n                                validationRules.required(\"Full Name\"),\n                                validationRules.alphabets(),\n                                validationRules.firstNameMinLength(),\n                                validationRules.firstNameMaxLength(),\n                            ]}\n                        >\n                            <Input\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        fullName: formatters.firstNameFormatter(\n                                            e.target.value\n                                        ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* USERNAME */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Username\"\n                            name=\"username\"\n                            rules={[\n                                validationRules.required(\"Username\"),\n                                validationRules.alphanumeric(),\n                            ]}\n                        >\n                            <Input\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        username:\n                                            formatters.removeExtraSpaces(\n                                                e.target.value\n                                            ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* WEBSITE URL */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Website URL\"\n                            name=\"website\"\n                            rules={[\n                                validationRules.required(\"Website URL\"),\n                                validationRules.url(),\n                            ]}\n                        >\n                            <Input\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        website:\n                                            formatters.removeExtraSpaces(\n                                                e.target.value\n                                            ),\n                                    });\n                                }} />\n                        </Form.Item>\n                    </Col>\n                    {/* MSP Req ID */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"MSP Req ID\"\n                            name=\"mspreqID\"\n                            rules={[\n                                validationRules.required(\"MSP Req ID\"),\n                                validationRules.candidateId(\"MSP Req ID\"),\n                            ]}\n                        >\n                            <Input\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        mspreqID:\n                                            formatters.removeExtraSpaces(\n                                                e.target.value\n                                            ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n                    {/* CANDIDATE ID */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Candidate ID\"\n                            name=\"candidateId\"\n                            rules={[\n                                validationRules.required(\"Candidate ID\"),\n                                validationRules.candidateId(\"Candidate ID\"),\n                            ]}\n                        >\n                            <Input\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        candidateId:\n                                            formatters.removeExtraSpaces(\n                                                e.target.value\n                                            ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* REMARKS */}\n                    <Col span={24}>\n                        <Form.Item\n                            label=\"Remarks\"\n                            name=\"remarks\"\n                            rules={[\n                                validationRules.required(\"Remarks\"),\n                                validationRules.remarks(),\n                                validationRules.remarksMinLength(),\n                                validationRules.remarksMaxLength(),\n                            ]}\n                        >\n                            <Input.TextArea\n                                rows={4}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* DESIGNATION */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Designation\"\n                            name=\"designation\"\n                            rules={[\n                                validationRules.required(\"Designation\"),\n                                validationRules.designation(),\n                            ]}\n                        >\n                            <Input />\n                        </Form.Item>\n                    </Col>\n\n                    {/* DOB */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Date of Birth\"\n                            name=\"dob\"\n                            rules={[validationRules.dob()]}\n                        >\n                            <Input\n                                placeholder=\"MM/DD/YYYY\"\n                                maxLength={10}\n                                onChange={(e) => {\n                                    form.setFieldsValue({\n                                        dob: formatters.dobFormatter(\n                                            e.target.value\n                                        ),\n                                    });\n                                }}\n                            />\n                        </Form.Item>\n                    </Col>\n\n                    {/* COMPANY NAME */}\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Company Name\"\n                            name=\"companyName\"\n                            rules={[\n                                validationRules.required(\"Company Name\"),\n                                validationRules.companyName(),\n                            ]}\n                        >\n                            <Input />\n                        </Form.Item>\n                    </Col>\n                    <Col span={12}>\n                        <Form.Item\n                            name=\"contractType\"\n                            label=\"Contract Type\"\n                        >\n                            <Select\n\n                                showSearch\n                                allowClear\n                                filterOption={(input, option) =>\n                                    (option?.label ?? \"\")\n                                        .toLowerCase()\n                                        .includes(input.toLowerCase())\n                                }\n                            >\n                                <Select.Option value=\"C2C\" label=\"C2C\">\n                                    C2C\n                                </Select.Option>\n                                <Select.Option\n                                    value=\"W2-Contract\"\n                                    label=\"W2-Contract\"\n                                >\n                                    W2-Contract\n                                </Select.Option>\n                                <Select.Option\n                                    value=\"W2-Fulltime\"\n                                    label=\"W2-Fulltime\"\n                                >\n                                    W2-Fulltime\n                                </Select.Option>\n                                <Select.Option value=\"1099\" label=\"1099\">\n                                    1099\n                                </Select.Option>\n                            </Select>\n                        </Form.Item>\n                    </Col>\n                    <Col span={12}>\n                        <Form.Item\n                            name=\"candidateProposedRateCurrency\"\n                            label=\"Currency\"\n                        >\n                            <Select\n                                showSearch\n                                allowClear\n                            >\n                                <Select.Option value=\"$\">$</Select.Option>\n                                <Select.Option value=\"₹\">₹</Select.Option>\n                                <Select.Option value=\"€\">€</Select.Option>\n                                <Select.Option value=\"zł\">\n                                    zł\n                                </Select.Option>\n                                <Select.Option value=\"£\">£</Select.Option>\n                                <Select.Option value=\"kr\">\n                                    kr\n                                </Select.Option>\n                                <Select.Option value=\"Fr\">\n                                    Fr\n                                </Select.Option>\n                                <Select.Option value=\"kr\">\n                                    kr\n                                </Select.Option>\n                            </Select>\n                        </Form.Item>\n                    </Col>\n                    {/* <Col span={12}>\n                        <Form.Item\n                            label=\"Resume\"\n                            name=\"resume\"\n                            valuePropName=\"fileList\"\n                            getValueFromEvent={(e) => e?.fileList}\n                            rules={[\n                                validationRules.singleFileUpload(),\n                            ]}\n                        >\n                            <Upload\n                                beforeUpload={\n                                    uploadValidation.beforeUpload\n                                }\n                                maxCount={1}\n                            >\n                                <Button>\n                                    Upload Resume\n                                </Button>\n                            </Upload>\n                        </Form.Item>\n                    </Col> */}\n                    <Col span={12}>\n\n                        <Form.Item\n                            label=\"Resume new\"\n                            name=\"resume\"\n                        >\n                            <Upload\n                                beforeUpload={\n                                    uploadValidation.beforeUpload\n                                }\n                                maxCount={1}\n                            >\n                                <Button>\n                                    Upload Resume\n                                </Button>\n                            </Upload>\n                        </Form.Item>\n\n                    </Col>\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Documents\"\n                            name=\"documents\"\n                            valuePropName=\"fileList\"\n                            getValueFromEvent={(e) => e?.fileList}\n                            rules={[\n                                validationRules.multiFileUpload(),\n                            ]}\n                        >\n                            <Upload\n                                multiple\n                                beforeUpload={\n                                    uploadValidation.beforeUpload\n                                }\n                            >\n                                <Button>\n                                    Upload Documents\n                                </Button>\n                            </Upload>\n                        </Form.Item>\n                    </Col>\n                    <Col span={12}>\n                        <Form.Item\n                            label=\"Upload File\"\n                            name=\"file\"\n                            valuePropName=\"fileList\"\n                            getValueFromEvent={(e) => e?.fileList}\n                            rules={[\n                                validationRules.fileUpload(),\n                            ]}\n                        >\n                            <Upload\n                                beforeUpload={\n                                    uploadValidation.beforeUpload\n                                }\n                                maxCount={1}\n                            >\n                                <Button>\n                                    Upload\n                                </Button>\n                            </Upload>\n                        </Form.Item>\n                    </Col>\n                </Row>\n                <Row>\n                    <Form.List name=\"users\">\n                        {(fields, { add, remove }) => (\n                            <>\n                                {fields.map(({ key, name, ...restField }) => (\n                                    <>\n                                        <Col span={12}>\n                                            <Form.Item\n                                                required\n                                                {...restField}\n                                                rules={[{ required: true, message: \"First name is requried\" }]}\n                                                name={[name, 'first']}\n                                            // rules={[{ required: true, message: 'Missing first name' }]}\n                                            >\n                                                <Input placeholder=\"First Name\" />\n                                            </Form.Item>\n                                        </Col>\n                                        <Col span={11}>\n                                            <Form.Item\n                                                {...restField}\n                                                required\n                                                name={[name, 'last']}\n                                            // rules={[{ required: true, message: 'Missing last name' }]}\n                                            >\n                                                <Input placeholder=\"Last Name\" />\n                                            </Form.Item>\n                                        </Col>\n                                        <Col span={1}>\n                                            <MinusCircleOutlined onClick={() => remove(name)} />\n                                        </Col>\n                                    </>\n                                ))}\n                                <Form.Item>\n                                    <Button type=\"dashed\" onClick={() => add()} block icon={<PlusOutlined />}>\n                                        Add field\n                                    </Button>\n                                </Form.Item>\n                            </>\n                        )}\n                    </Form.List>\n                </Row>\n\n                {/* SUBMIT BUTTON */}\n                <Form.Item>\n                    <Button type=\"primary\" htmlType=\"submit\">\n                        Submit\n                    </Button>\n\n                    <Button\n                        style={{ marginLeft: 10 }}\n                        onClick={() => form.resetFields()}\n                    >\n                        Reset\n                    </Button>\n                </Form.Item>\n            </Form>\n        </div>\n    );\n};\n\nexport default UserForm;\n","import AppShell from '../../components/layouts/AppShell.jsx';\nimport AdminDashboard from './AdminDashboard.jsx';\n\n// Complete package page used by consumer applications. AdminDashboard remains\n// separately exported for hosts that already provide their own AppShell.\nexport default function AdminPageWithShell(props) {\n  return (\n    <AppShell>\n      <AdminDashboard {...props} />\n    </AppShell>\n  );\n}\n","import { Card, Row, Col, Statistic, Typography, Space } from 'antd';\nimport { FileTextOutlined, CheckCircleOutlined, UserOutlined, FilterOutlined } from '@ant-design/icons';\n\nconst { Text } = Typography;\n\nconst defaultStats = [\n  { label: 'Total Jobs', value: 1697, icon: 'fileText' },\n  { label: 'Active Jobs', value: 1685, icon: 'checkCircle' },\n  { label: 'My Jobs', value: 600, icon: 'user' },\n];\n\nconst iconByName = {\n  fileText: <FileTextOutlined />,\n  checkCircle: <CheckCircleOutlined />,\n  user: <UserOutlined />,\n  filter: <FilterOutlined />,\n};\n\nexport default function StatsCards({ stats = defaultStats }) {\n  return (\n    <Card>\n      <Row gutter={[12, 12]}>\n        {stats.map(s => (\n          <Col key={s.label} xs={24} sm={24} md={8} lg={8} xl={8}>\n            <Card className=\"stats-inner-card\">\n              <Space align=\"center\">\n                {iconByName[s.icon] ?? iconByName.fileText}\n                <Text>{s.label}</Text>\n              </Space>\n              <Statistic value={s.value} />\n            </Card>\n          </Col>\n        ))}\n      </Row>\n    </Card>\n  );\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { Typography, message } from 'antd';\nimport { TeamOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport ParamListView from '../../../components/ParamListView';\nimport { getAllUsers } from '../../../services/adminApi';\nimport '../../../styles/UserSettingsSection.css';\n\nconst { Text } = Typography;\n\nfunction getUserDisplayName(raw) {\n  return (\n    raw?.USER_NAME ?? raw?.user_name ?? raw?.username ??\n    raw?.name      ?? raw?.full_name ?? raw?.fullName ??\n    raw?.email     ?? `User ${raw?.USER_ID ?? raw?.user_id ?? '?'}`\n  );\n}\n\nfunction normalizeUserRecord(raw) {\n  return {\n    ...raw,\n    key:      raw.USER_ID   ?? raw.user_id   ?? raw.userId ?? raw.id ?? raw._id,\n    _name:    getUserDisplayName(raw),\n    _email:   raw.email     ?? raw.EMAIL     ?? raw.user_email ?? '',\n    _role:    raw.role_name ?? raw.roleName  ?? raw.ROLE_NAME  ?? '',\n    _rawRef:  raw,\n  };\n}\n\nexport default function UsersSection() {\n  const [users, setUsers]               = useState([]);\n  const [total, setTotal]               = useState(0);\n  const [loading, setLoading]           = useState(false);\n  const [page, setPage]                 = useState(1);\n  const [pageSize, setPageSize]         = useState(10);\n  const [searchQuery, setSearchQuery]   = useState('');\n\n  const fetchUsers = useCallback(async ({ offset, limit, searchQuery: sq } = {}) => {\n    setLoading(true);\n    try {\n      const result = await getAllUsers({ offset, limit, searchQuery: sq ?? '' });\n      const normalized = (result.users ?? []).map(normalizeUserRecord);\n      setUsers(normalized);\n      setTotal(result.total ?? normalized.length);\n    } catch {\n      message.error('Failed to load users');\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      fetchUsers({ offset: (page - 1) * pageSize, limit: pageSize, searchQuery });\n    });\n  }, [fetchUsers, page, pageSize, searchQuery]);\n\n  const fields = [\n    {\n      label: 'Name', value: '_name', width: 220,\n      render: (name, record) => (\n        <div>\n          <Text strong style={{ fontSize: 13 }}>{name}</Text>\n          {record._email && <div style={{ fontSize: 11, color: 'var(--color-text-muted)' }}>{record._email}</div>}\n        </div>\n      ),\n    },\n    { label: 'Role', value: '_role', width: 180 },\n  ];\n\n  return (\n    <AppCard icon={<TeamOutlined />} title=\"Users\"\n      style={{ marginBottom: 0 }}\n      bodyStyle={{ padding: 0 }}>\n      <ParamListView\n        listName=\"Users\"\n        dataSource={users}\n        fields={fields}\n        loading={loading}\n        total={total}\n        current={page}\n        pageSize={pageSize}\n        onPageChange={(p) => setPage(p)}\n        onPageSizeChange={(s) => { setPageSize(s); setPage(1); }}\n        onSearch={(q) => { setSearchQuery(q); setPage(1); }}\n      />\n    </AppCard>\n  );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { Button, Input, message, Modal, Spin, Switch, Tabs, Typography } from 'antd';\nimport { HolderOutlined, TeamOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport ParamListView from '../../../components/ParamListView';\nimport {\n  getAllTeams,\n  getTeamModuleFields,\n  updateTeam,\n  updateTeamModuleFieldConfig,\n} from '../../../services/adminApi';\nimport '../../../styles/UserSettingsSection.css';\n\nconst { Text } = Typography;\n\nconst MODULE_TABS = [\n  { key: 'job',         label: 'Jobs'        },\n  { key: 'candidate',   label: 'Candidates'  },\n  { key: 'submissions', label: 'Submissions' },\n];\n\nconst CONFIG_TYPES = [\n  { key: 'listView', label: 'List View' },\n  { key: 'filter',   label: 'Filter'    },\n  { key: 'form',     label: 'Form'      },\n];\n\nfunction FieldRow({ field, index, onToggle, onReorder }) {\n  const dragIdx = useRef(null);\n  const [over, setOver]         = useState(false);\n  const [dragging, setDragging] = useState(false);\n\n  function handleDragStart(e) { dragIdx.current = index; e.dataTransfer.effectAllowed = 'move'; setDragging(true); }\n  function handleDragEnd()    { setDragging(false); setOver(false); }\n  function handleDragOver(e)  { e.preventDefault(); setOver(true); }\n  function handleDragLeave()  { setOver(false); }\n  function handleDrop(e) {\n    e.preventDefault(); setOver(false);\n    if (dragIdx.current !== null && dragIdx.current !== index) onReorder(dragIdx.current, index);\n    dragIdx.current = null;\n  }\n\n  return (\n    <div\n      draggable\n      onDragStart={handleDragStart} onDragEnd={handleDragEnd}\n      onDragOver={handleDragOver}   onDragLeave={handleDragLeave} onDrop={handleDrop}\n      className={`uss-field-row with-edit${over ? ' drag-over' : ''}${dragging ? ' dragging' : ''}`}\n    >\n      <span className=\"uss-drag-handle\"><HolderOutlined /></span>\n      <span className=\"uss-field-name\">\n        {field.fieldName}\n        <span className=\"uss-field-key\">{field.fieldKey}</span>\n      </span>\n      <span className=\"uss-toggle-cell\">\n        <Switch size=\"small\" checked={field.isVisible}            onChange={(v) => onToggle(index, 'isVisible', v)} />\n      </span>\n      <span className=\"uss-toggle-cell\">\n        <Switch size=\"small\" checked={Boolean(field.isEditable)}  onChange={(v) => onToggle(index, 'isEditable', v)} />\n      </span>\n      <span className=\"uss-toggle-cell\">\n        <Switch size=\"small\" checked={Boolean(field.ismandatory)} onChange={(v) => onToggle(index, 'ismandatory', v)} />\n      </span>\n    </div>\n  );\n}\n\nfunction ModuleFieldConfig({ team, configType }) {\n  const [moduleFields, setModuleFields] = useState({});\n  const [loading, setLoading]           = useState(false);\n  const [saving, setSaving]             = useState({});\n  const [activeModule, setActiveModule] = useState('job');\n\n  useEffect(() => {\n    if (!team) return;\n    setLoading(true);\n    getTeamModuleFields(team, configType)\n      .then(setModuleFields)\n      .catch(() => message.error('Failed to load field config'))\n      .finally(() => setLoading(false));\n  }, [team, configType]);\n\n  const fields = moduleFields[activeModule] ?? [];\n\n  function setFields(module, updater) {\n    setModuleFields((prev) => ({\n      ...prev,\n      [module]: typeof updater === 'function' ? updater(prev[module] ?? []) : updater,\n    }));\n  }\n\n  function handleToggle(idx, key, val) {\n    setFields(activeModule, (prev) => prev.map((f, i) => i === idx ? { ...f, [key]: val } : f));\n  }\n\n  function handleReorder(from, to) {\n    setFields(activeModule, (prev) => {\n      const arr = [...prev];\n      const [moved] = arr.splice(from, 1);\n      arr.splice(to, 0, moved);\n      return arr.map((f, i) => ({ ...f, order: i }));\n    });\n  }\n\n  async function handleSave() {\n    const mod = activeModule;\n    setSaving((p) => ({ ...p, [mod]: true }));\n    try {\n      await updateTeamModuleFieldConfig(team, mod, fields, configType);\n      message.success('Saved');\n    } catch {\n      message.error('Save failed');\n    } finally {\n      setSaving((p) => ({ ...p, [mod]: false }));\n    }\n  }\n\n  return (\n    <Spin spinning={loading}>\n      <Tabs size=\"small\" activeKey={activeModule} onChange={setActiveModule}\n        items={MODULE_TABS.map((t) => ({ key: t.key, label: t.label }))} />\n      <div className=\"uss-field-header with-edit\">\n        <span /><span>Field</span>\n        <span style={{ textAlign: 'center' }}>Visible</span>\n        <span style={{ textAlign: 'center' }}>Editable</span>\n        <span style={{ textAlign: 'center' }}>Mandatory</span>\n      </div>\n      <div className=\"uss-field-list\">\n        {fields.length === 0 && !loading && <div className=\"uss-empty\">No fields found.</div>}\n        {fields.map((field, idx) => (\n          <FieldRow key={field.fieldKey ?? idx} field={field} index={idx}\n            onToggle={handleToggle} onReorder={handleReorder} />\n        ))}\n      </div>\n      <div className=\"uss-modal-footer\">\n        <Button type=\"primary\" size=\"small\" loading={saving[activeModule]} onClick={handleSave}>\n          Save {MODULE_TABS.find((t) => t.key === activeModule)?.label}\n        </Button>\n      </div>\n    </Spin>\n  );\n}\n\nexport default function TeamsSection() {\n  const [selectedTeam, setSelectedTeam] = useState(null);\n  const [configOpen, setConfigOpen]     = useState(false);\n  const [editOpen, setEditOpen]         = useState(false);\n  const [configType, setConfigType]     = useState('listView');\n  const [teams, setTeams]               = useState([]);\n  const [total, setTotal]               = useState(0);\n  const [loading, setLoading]           = useState(false);\n  const [editName, setEditName]         = useState('');\n  const [editSaving, setEditSaving]     = useState(false);\n\n  const fetchTeams = useCallback(async () => {\n    setLoading(true);\n    try {\n      const result = await getAllTeams();\n      setTeams(result.teams);\n      setTotal(result.total);\n    } catch {\n      message.error('Failed to load teams');\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  useEffect(() => { fetchTeams(); }, [fetchTeams]);\n\n  function openConfig(team) {\n    setSelectedTeam(team);\n    setConfigType('listView');\n    setConfigOpen(true);\n  }\n\n  function openEdit(team) {\n    setSelectedTeam(team);\n    setEditName(team.teamName ?? '');\n    setEditOpen(true);\n  }\n\n  async function handleSaveTeamName() {\n    if (!editName.trim()) { message.warning('Team name is required'); return; }\n    setEditSaving(true);\n    try {\n      await updateTeam(selectedTeam, {\n        teamName: editName.trim(),\n        managerId: selectedTeam.managerId,\n        memberIds: selectedTeam.memberIds,\n      });\n      message.success('Team updated');\n      setEditOpen(false);\n      fetchTeams();\n    } catch {\n      message.error('Failed to update team');\n    } finally {\n      setEditSaving(false);\n    }\n  }\n\n  const fields = [\n    { label: 'Team Name', value: 'teamName', width: 200 },\n    { label: 'Manager',   value: 'manager',  width: 200 },\n    { label: 'Members',   value: 'memberCount', width: 90, sorter: false },\n    {\n      label: 'Actions', value: '_actions', width: 160, sorter: false,\n      render: (_, record) => (\n        <div style={{ display: 'flex', gap: 4 }}>\n          <Button size=\"small\" type=\"link\" onClick={() => openEdit(record)}>Edit</Button>\n          <Button size=\"small\" type=\"link\" onClick={() => openConfig(record)}>Configure</Button>\n        </div>\n      ),\n    },\n  ];\n\n  return (\n    <>\n      <AppCard icon={<TeamOutlined />} title=\"Teams\"\n        style={{ marginBottom: 0 }}\n        bodyStyle={{ padding: 0 }}>\n        <ParamListView\n          listName=\"Teams\"\n          dataSource={teams}\n          fields={fields}\n          loading={loading}\n          total={total}\n        />\n      </AppCard>\n\n      {/* Edit team name */}\n      <Modal open={editOpen} onCancel={() => setEditOpen(false)}\n        title={<><TeamOutlined style={{ color: 'var(--color-brand)', marginRight: 6 }} />Edit Team</>}\n        width={420} footer={null} destroyOnClose>\n        <div className=\"uss-edit-team-body\" style={{ paddingTop: 12 }}>\n          <div>\n            <div className=\"uss-edit-team-label\">Team Name</div>\n            <Input value={editName} onChange={(e) => setEditName(e.target.value)}\n              onPressEnter={handleSaveTeamName} placeholder=\"Enter team name\" />\n          </div>\n          <div className=\"uss-modal-footer\">\n            <Button onClick={() => setEditOpen(false)}>Cancel</Button>\n            <Button type=\"primary\" loading={editSaving} onClick={handleSaveTeamName}>Save</Button>\n          </div>\n        </div>\n      </Modal>\n\n      {/* Field config */}\n      <Modal\n        className=\"uss-modal\"\n        open={configOpen}\n        onCancel={() => setConfigOpen(false)}\n        title={\n          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n            <TeamOutlined style={{ color: 'var(--color-brand)' }} />\n            <span>Configure: {selectedTeam?.teamName}</span>\n          </div>\n        }\n        width={720} footer={null} destroyOnClose\n      >\n        <div style={{ marginBottom: 12 }}>\n          <div className=\"uss-config-toggle\">\n            {CONFIG_TYPES.map((ct) => (\n              <button key={ct.key}\n                className={`uss-config-btn${configType === ct.key ? ' active' : ''}`}\n                onClick={() => setConfigType(ct.key)}>{ct.label}</button>\n            ))}\n          </div>\n        </div>\n        {selectedTeam && (\n          <ModuleFieldConfig\n            key={`${selectedTeam?.teamId}-${configType}`}\n            team={selectedTeam}\n            configType={configType}\n          />\n        )}\n      </Modal>\n    </>\n  );\n}","// ─────────────────────────────────────────────────────────────────────────\n// RolePermPanel — the role permission matrix (module × action grid).\n// Shared between PermissionsPage.jsx (dedicated Roles & Permissions page)\n// and RolesSection.jsx (the \"Permissions\" tab on a role's config modal) so\n// there is exactly one implementation of load/toggle/save for role\n// permissions — configure once per role, applies to every user with it.\n// ─────────────────────────────────────────────────────────────────────────\nimport { useEffect, useMemo, useState } from 'react';\nimport { Button, Spin, Tag, Tooltip, message } from 'antd';\nimport { CheckOutlined, EditOutlined, InfoCircleOutlined, LockOutlined, UnlockOutlined } from '@ant-design/icons';\nimport { getRoleId, getRolePermissions, updateRolePermissions } from '../../../../services/adminApi';\nimport { isPermissionApplicable } from '../../../../utils/permissionApplicability';\nimport '../../../../styles/PermissionsPage.css';\n\n// ── Label helpers ─────────────────────────────────────────────────────────────\n\nconst KNOWN_KEYS = ['view', 'add', 'edit', 'delete'];\n\nconst DEFAULT_ACTION_LABELS = {\n  view: 'View', add: 'Add', edit: 'Edit', delete: 'Delete',\n  sourcing: 'Sourcing', assign: 'Assign', share: 'Share',\n  change_status: 'Status', my_jobs: 'My Jobs', all_jobs: 'All Jobs',\n  po_msa: 'PO MSA', reApprove: 'ReApprove', sendApprove: 'Send Approve',\n};\n\nfunction defaultActionLabel(key) {\n  return DEFAULT_ACTION_LABELS[key] ?? key.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction sortedPermKeys(keys) {\n  const known = KNOWN_KEYS.filter((k) => keys.includes(k));\n  const rest  = keys.filter((k) => !KNOWN_KEYS.includes(k)).sort();\n  return [...known, ...rest];\n}\n\nexport function allPermKeysFromData(data) {\n  const set = new Set();\n  Object.values(data).forEach(({ permissions }) =>\n    Object.keys(permissions ?? {}).forEach((k) => set.add(k))\n  );\n  return sortedPermKeys([...set]);\n}\n\nexport function countEnabled(data) {\n  let enabled = 0, total = 0;\n  Object.entries(data).forEach(([menuName, { permissions }]) => {\n    Object.entries(permissions ?? {}).forEach(([permissionKey, { value }]) => {\n      if (!isPermissionApplicable(menuName, permissionKey)) return;\n      total++;\n      if (value === '1') enabled++;\n    });\n  });\n  return { enabled, total };\n}\n\n\nfunction ensureOnboardingWorkflowPermissions(data = {}) {\n  if (!data || typeof data !== 'object') return data;\n  const onboardingKey = Object.keys(data).find(\n    (key) => String(key).trim().toLowerCase() === 'onboarding',\n  );\n  if (!onboardingKey) return data;\n\n  const menu = data[onboardingKey] ?? {};\n  const permissions = { ...(menu.permissions ?? {}) };\n  for (const key of ['sendApprove', 'reApprove']) {\n    if (!Object.keys(permissions).some((existing) => existing.toLowerCase() === key.toLowerCase())) {\n      permissions[key] = { id: 0, value: '0' };\n    }\n  }\n  return {\n    ...data,\n    [onboardingKey]: {\n      ...menu,\n      permissions,\n    },\n  };\n}\n\n// ── Inline editable name ──────────────────────────────────────────────────────\n\nfunction InlineName({ value, onSave, className }) {\n  const [editing, setEditing] = useState(false);\n  const [draft,   setDraft]   = useState(value);\n\n  useEffect(() => { setDraft(value); }, [value]);\n\n  function commit() {\n    setEditing(false);\n    const t = draft.trim();\n    if (t && t !== value) onSave(t);\n    else setDraft(value);\n  }\n\n  if (editing) {\n    return (\n      <input\n        autoFocus\n        className={`perm-inline-input${className ? ` ${className}` : ''}`}\n        value={draft}\n        style={{ width: Math.max(48, draft.length * 8) }}\n        onChange={(e) => setDraft(e.target.value)}\n        onBlur={commit}\n        onKeyDown={(e) => {\n          if (e.key === 'Enter')  commit();\n          if (e.key === 'Escape') { setEditing(false); setDraft(value); }\n          e.stopPropagation();\n        }}\n        onClick={(e) => e.stopPropagation()}\n      />\n    );\n  }\n\n  return (\n    <span\n      className={`perm-editable-name${className ? ` ${className}` : ''}`}\n      onDoubleClick={(e) => { e.stopPropagation(); setEditing(true); }}\n    >\n      {value}\n      <EditOutlined className=\"perm-name-edit-icon\" />\n    </span>\n  );\n}\n\n// ── Action pill ───────────────────────────────────────────────────────────────\n\nfunction ActionPill({ entry, label, onToggle, onLabelSave }) {\n  const [editing, setEditing] = useState(false);\n  const [draft,   setDraft]   = useState(label);\n  const isOn      = entry?.value === '1';\n  const available = !!entry;\n\n  useEffect(() => { setDraft(label); }, [label]);\n\n  function commitLabel() {\n    setEditing(false);\n    const t = draft.trim();\n    if (t && t !== label) onLabelSave(t);\n    else setDraft(label);\n  }\n\n  return (\n    <Tooltip title={available ? (isOn ? 'Click to disable' : 'Click to enable') : 'Not applicable for this module'}>\n      <div\n        className={`perm-action-pill${isOn ? ' on' : ''}${!available ? ' na' : ''}`}\n        onClick={() => { if (!editing && available) onToggle(); }}\n      >\n        <span className={`perm-action-pill-dot${isOn ? ' on' : ''}`} />\n\n        {editing ? (\n          <input\n            autoFocus\n            className=\"perm-pill-input\"\n            value={draft}\n            style={{ width: Math.max(36, draft.length * 7) }}\n            onChange={(e) => setDraft(e.target.value)}\n            onBlur={commitLabel}\n            onKeyDown={(e) => {\n              if (e.key === 'Enter')  commitLabel();\n              if (e.key === 'Escape') { setEditing(false); setDraft(label); }\n              e.stopPropagation();\n            }}\n            onClick={(e) => e.stopPropagation()}\n          />\n        ) : (\n          <span\n            className=\"perm-action-pill-label\"\n            onDoubleClick={(e) => { e.stopPropagation(); setEditing(true); }}\n          >\n            {label}\n          </span>\n        )}\n\n        {isOn && !editing && <CheckOutlined className=\"perm-action-pill-check\" />}\n      </div>\n    </Tooltip>\n  );\n}\n\n// ── Module card ───────────────────────────────────────────────────────────────\n\nfunction ModuleCard({ menuName, menuData, permKeys, onChange, displayName, actionLabels, onModuleLabelSave, onActionLabelSave }) {\n  const perms   = menuData?.permissions ?? {};\n  const visiblePermKeys = permKeys.filter((key) => isPermissionApplicable(menuName, key));\n  const onCount = visiblePermKeys.filter((key) => perms[key]?.value === '1').length;\n  const total   = visiblePermKeys.filter((key) => perms[key]).length;\n  const allOn   = total > 0 && onCount === total;\n  const someOn  = onCount > 0 && !allOn;\n\n  return (\n    <div className={`perm-module-card${allOn ? ' all-on' : someOn ? ' some-on' : ''}`}>\n      <div className=\"perm-module-card-header\">\n        <InlineName\n          value={displayName}\n          onSave={(v) => onModuleLabelSave(menuName, v)}\n          className=\"perm-module-card-name\"\n        />\n        {total > 0 && (\n          <span className={`perm-module-card-badge${onCount > 0 ? ' active' : ''}`}>\n            {onCount}/{total}\n          </span>\n        )}\n      </div>\n      <div className=\"perm-module-card-body\">\n        {visiblePermKeys.map((k) => (\n          <ActionPill\n            key={k}\n            entry={perms[k]}\n            label={actionLabels[k] ?? defaultActionLabel(k)}\n            onToggle={() => onChange(menuName, k)}\n            onLabelSave={(v) => onActionLabelSave(k, v)}\n          />\n        ))}\n      </div>\n    </div>\n  );\n}\n\n// ── Role perm panel ───────────────────────────────────────────────────────────\n\nexport default function RolePermPanel({\n  role,\n  moduleLabels = {}, actionLabels = {},\n  onModuleLabelSave = () => {}, onActionLabelSave = () => {},\n}) {\n  const [data,    setData]    = useState({});\n  const [local,   setLocal]   = useState({});\n  const [loading, setLoading] = useState(false);\n  const [saving,  setSaving]  = useState(false);\n  const [dirty,   setDirty]   = useState(false);\n\n  const roleId = getRoleId(role);\n\n  useEffect(() => {\n    if (!roleId) return;\n    setLoading(true);\n    setDirty(false);\n    getRolePermissions(roleId)\n      .then((d) => {\n        const normalized = ensureOnboardingWorkflowPermissions(d);\n        setData(normalized);\n        setLocal(normalized);\n      })\n      .catch(() => message.error('Failed to load permissions'))\n      .finally(() => setLoading(false));\n  }, [roleId]);\n\n  function toggle(menuName, permKey) {\n    setDirty(true);\n    setLocal((prev) => {\n      const menu  = prev[menuName] ?? { menuId: data[menuName]?.menuId ?? 0, permissions: {} };\n      const entry = menu.permissions?.[permKey] ?? { id: 0, value: '0' };\n      return {\n        ...prev,\n        [menuName]: {\n          ...menu,\n          permissions: {\n            ...menu.permissions,\n            [permKey]: { ...entry, value: entry.value === '1' ? '0' : '1' },\n          },\n        },\n      };\n    });\n  }\n\n  async function handleSave() {\n    setSaving(true);\n    try {\n      await updateRolePermissions(roleId, local);\n      setData(local);\n      setDirty(false);\n      message.success('Permissions saved');\n    } catch (error) {\n      message.error(error?.message || 'Save failed');\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  const menuNames = useMemo(() => Object.keys(local).sort(), [local]);\n  const permKeys  = useMemo(() => allPermKeysFromData(local), [local]);\n  const { enabled, total } = useMemo(() => countEnabled(local), [local]);\n\n  return (\n    <Spin spinning={loading}>\n\n      {/* ── Panel header ── */}\n      <div className=\"perm-panel-header\">\n        <div className=\"perm-panel-title\">\n          <LockOutlined style={{ color: 'var(--color-brand)', marginRight: 6 }} />\n          <span>{role?.roleName}</span>\n          {!loading && total > 0 && (\n            <Tag color=\"blue\" style={{ marginLeft: 8, fontSize: 11 }}>\n              {enabled}/{total} enabled\n            </Tag>\n          )}\n        </div>\n        <Button\n          type=\"primary\"\n          size=\"small\"\n          icon={<UnlockOutlined />}\n          loading={saving}\n          disabled={!dirty}\n          onClick={handleSave}\n        >\n          Save Changes\n        </Button>\n      </div>\n\n      {/* ── Hint ── */}\n      <div className=\"perm-hint\">\n        <InfoCircleOutlined className=\"perm-hint-icon\" />\n        <span>\n          Click a pill to toggle. <strong>Double-click</strong> a module name or action label to rename it — labels are saved locally.\n        </span>\n      </div>\n\n      {/* ── Module cards grid ── */}\n      {menuNames.length === 0 && !loading ? (\n        <div className=\"perm-empty\">No permission entries found for this role.</div>\n      ) : (\n        <div className=\"perm-cards-grid\">\n          {menuNames.map((menuName) => (\n            <ModuleCard\n              key={menuName}\n              menuName={menuName}\n              menuData={local[menuName]}\n              permKeys={permKeys}\n              onChange={toggle}\n              displayName={moduleLabels[menuName] ?? menuName}\n              actionLabels={actionLabels}\n              onModuleLabelSave={onModuleLabelSave}\n              onActionLabelSave={onActionLabelSave}\n            />\n          ))}\n        </div>\n      )}\n\n    </Spin>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Button, message, Modal, Select, Space, Typography } from 'antd';\nimport { AppstoreOutlined, LockOutlined, SafetyOutlined } from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport ParamListView from '../../../components/ParamListView';\nimport {\n  getAllRoles,\n  getAvailableCollections,\n  getFieldConfigSeedStatus,\n  seedFieldConfig,\n} from '../../../services/adminApi';\nimport RolePermPanel from './components/RolePermPanel';\nimport ModuleFieldConfigEditor from './components/ModuleFieldConfigEditor';\nimport '../../../styles/UserSettingsSection.css';\n\nconst { Text } = Typography;\n\nconst CONFIG_TYPES = [\n  { key: 'listView',    label: 'List View'   },\n  { key: 'filter',      label: 'Filter'      },\n  { key: 'form',        label: 'Form'        },\n  { key: 'permissions', label: 'Permissions' },\n];\n\nfunction moduleTitle(value) {\n  return String(value || '')\n    .replace(/[-_]/g, ' ')\n    .replace(/\\b\\w/g, (c) => c.toUpperCase())\n    .trim();\n}\n\nfunction normalizeSeedKey(value) {\n  return String(value || '').trim().toLowerCase();\n}\n\nfunction seedOptionValue(item) {\n  return item?.key || item?.collectionName || item?.value || '';\n}\n\nfunction buildSeedOptions(statusModules = [], collections = []) {\n  const options = [];\n  const seenValues = new Set();\n  const seededKeys = new Set();\n  const moduleCollections = new Set();\n\n  statusModules.forEach((module) => {\n    const value = seedOptionValue(module);\n    if (!value) return;\n\n    const key = normalizeSeedKey(module.key || value);\n    const collectionKey = normalizeSeedKey(module.collectionName);\n    if (module.seeded) {\n      seededKeys.add(key);\n      if (collectionKey) seededKeys.add(collectionKey);\n    }\n    if (collectionKey) moduleCollections.add(collectionKey);\n\n    seenValues.add(value);\n    options.push({\n      label: module.label || moduleTitle(value),\n      value,\n      disabled: Boolean(module.seeded),\n    });\n  });\n\n  collections.forEach((collection) => {\n    const value = String(collection || '').trim();\n    if (!value || seenValues.has(value)) return;\n\n    const collectionKey = normalizeSeedKey(value);\n    if (moduleCollections.has(collectionKey) || seededKeys.has(collectionKey)) return;\n\n    seenValues.add(value);\n    options.push({\n      label: moduleTitle(value),\n      value,\n      disabled: false,\n    });\n  });\n\n  return options;\n}\n\nexport default function RolesSection() {\n  const [selectedRole, setSelectedRole] = useState(null);\n  const [modalOpen, setModalOpen]       = useState(false);\n  const [configType, setConfigType]     = useState('listView');\n  const [roles, setRoles]               = useState([]);\n  const [total, setTotal]               = useState(0);\n  const [loading, setLoading]           = useState(false);\n  const [seedOptions, setSeedOptions]   = useState([]);\n  const [seedModules, setSeedModules]   = useState([]);\n  const [seedLoading, setSeedLoading]   = useState(false);\n  const [seeding, setSeeding]           = useState(false);\n\n  const availableSeedOptions = useMemo(\n    () => seedOptions.filter((option) => !option.disabled),\n    [seedOptions]\n  );\n  const allSeeded = !seedLoading && availableSeedOptions.length === 0;\n\n  const fetchRoles = useCallback(async () => {\n    setLoading(true);\n    try {\n      const result = await getAllRoles();\n      setRoles(result.roles);\n      setTotal(result.total);\n    } catch {\n      message.error('Failed to load roles');\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  const loadSeedState = useCallback(async () => {\n    setSeedLoading(true);\n    try {\n      const [status, collections] = await Promise.all([\n        getFieldConfigSeedStatus(),\n        getAvailableCollections(),\n      ]);\n      const options = buildSeedOptions(status.modules, collections);\n      const allowed = new Set(options.filter((option) => !option.disabled).map((option) => option.value));\n      setSeedOptions(options);\n      setSeedModules((prev) => prev.filter((value) => allowed.has(value)));\n    } catch {\n      message.error('Failed to load seed status');\n    } finally {\n      setSeedLoading(false);\n    }\n  }, []);\n\n  useEffect(() => { fetchRoles(); }, [fetchRoles]);\n  useEffect(() => { loadSeedState(); }, [loadSeedState]);\n\n  async function handleSeedFieldConfig() {\n    if (seedModules.length === 0) {\n      message.warning(allSeeded ? 'All modules already seeded.' : 'Select at least one module to seed.');\n      return;\n    }\n\n    setSeeding(true);\n    try {\n      await seedFieldConfig(seedModules);\n      message.success('Role field config seeded');\n      setSeedModules([]);\n      await loadSeedState();\n    } catch (error) {\n      message.error(error?.message || 'Seed failed');\n    } finally {\n      setSeeding(false);\n    }\n  }\n\n  function openConfig(role, tab = 'listView') {\n    setSelectedRole(role);\n    setConfigType(tab);\n    setModalOpen(true);\n  }\n\n  const fields = [\n    { label: 'Role Name',   value: 'roleName',   width: 200 },\n    { label: 'Description', value: 'description', width: 240 },\n    { label: 'Users',       value: 'userCount',   width: 70, sorter: false },\n    {\n      label: 'Actions', value: '_configure', width: 200, sorter: false,\n      render: (_, record) => (\n        <Space size={2}>\n          <Button size=\"small\" type=\"link\" onClick={() => openConfig(record)}>Configure</Button>\n          <Button\n            size=\"small\"\n            type=\"link\"\n            icon={<LockOutlined />}\n            onClick={() => openConfig(record, 'permissions')}\n          >\n            Permissions\n          </Button>\n        </Space>\n      ),\n    },\n  ];\n\n  return (\n    <>\n      <AppCard\n        icon={<AppstoreOutlined />}\n        title=\"Field Config Seed\"\n        style={{ marginBottom: 12 }}\n      >\n        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>\n          <div style={{ minWidth: 320, flex: 1 }}>\n            <Select\n              mode=\"multiple\"\n              allowClear\n              showSearch\n              value={seedModules}\n              options={seedOptions}\n              placeholder={allSeeded ? 'All modules already seeded' : 'Select modules or collections to seed'}\n              disabled={seedLoading || seeding || allSeeded}\n              loading={seedLoading}\n              onChange={setSeedModules}\n              style={{ width: '100%' }}\n            />\n          </div>\n          <Button\n            type=\"primary\"\n            loading={seeding}\n            disabled={seedLoading || seedModules.length === 0}\n            onClick={handleSeedFieldConfig}\n          >\n            Seed Field Config\n          </Button>\n        </div>\n        <Text type=\"secondary\" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>\n          {allSeeded\n            ? 'Seed is disabled because all configured modules already have role field config data.'\n            : 'Already seeded modules are disabled. New modules or collections can still be seeded.'}\n        </Text>\n      </AppCard>\n      <AppCard icon={<SafetyOutlined />} title=\"Roles\"\n        style={{ marginBottom: 0 }}\n        bodyStyle={{ padding: 0 }}>\n        <ParamListView\n          listName=\"Roles\"\n          dataSource={roles}\n          fields={fields}\n          loading={loading}\n          total={total}\n        />\n      </AppCard>\n\n      <Modal\n        className=\"uss-modal\"\n        open={modalOpen}\n        onCancel={() => setModalOpen(false)}\n        title={\n          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n            <SafetyOutlined style={{ color: 'var(--color-brand)' }} />\n            <span>Configure: {selectedRole?.roleName}</span>\n          </div>\n        }\n        width={720} footer={null} destroyOnClose\n      >\n        <div style={{ marginBottom: 12 }}>\n          <div className=\"uss-config-toggle\">\n            {CONFIG_TYPES.map((ct) => (\n              <button key={ct.key}\n                className={`uss-config-btn${configType === ct.key ? ' active' : ''}`}\n                onClick={() => setConfigType(ct.key)}>{ct.label}</button>\n            ))}\n          </div>\n        </div>\n        {selectedRole && (\n          configType === 'permissions' ? (\n            <RolePermPanel key={selectedRole?.roleId} role={selectedRole} />\n          ) : (\n            <ModuleFieldConfigEditor\n              key={`${selectedRole?.roleId}-${configType}`}\n              role={selectedRole}\n              configType={configType}\n            />\n          )\n        )}\n      </Modal>\n    </>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Button, Input, message, Modal, Popconfirm, Spin, Tabs } from 'antd';\nimport {\n  DeleteOutlined,\n  EditOutlined,\n  LockOutlined,\n  PlusOutlined,\n  SafetyOutlined,\n  SearchOutlined,\n  SettingOutlined,\n} from '@ant-design/icons';\nimport AppCard from '../../../components/cards/AppCard';\nimport {\n  getAllRoles,\n  getMenuModules,\n  createMenuModule,\n  updateMenuModule,\n  deleteMenuModule,\n  getMenuActions,\n  createMenuAction,\n  updateMenuAction,\n  deleteMenuAction,\n} from '../../../services/adminApi';\nimport RolePermPanel from './components/RolePermPanel';\nimport '../../../styles/PermissionsPage.css';\n\n// ── localStorage helpers ──────────────────────────────────────────────────────\n\nconst LS_MODULE = 'perm-module-labels';\nconst LS_ACTION = 'perm-action-labels';\n\nfunction readLS(key) {\n  try { return JSON.parse(localStorage.getItem(key) ?? '{}'); } catch { return {}; }\n}\nfunction writeLS(key, val) {\n  try { localStorage.setItem(key, JSON.stringify(val)); } catch { /* ignore */ }\n}\n\n// ── Manage modal (modules + actions) ─────────────────────────────────────────\n\nfunction EditableRow({ label, onSave, onDelete, loading }) {\n  const [editing, setEditing] = useState(false);\n  const [draft, setDraft] = useState(label);\n\n  function commit() {\n    setEditing(false);\n    const t = draft.trim();\n    if (t && t !== label) onSave(t);\n    else setDraft(label);\n  }\n\n  return (\n    <div className=\"perm-manage-row\">\n      {editing ? (\n        <input\n          autoFocus\n          className=\"perm-inline-input\"\n          value={draft}\n          style={{ flex: 1, minWidth: 0 }}\n          onChange={(e) => setDraft(e.target.value)}\n          onBlur={commit}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') commit();\n            if (e.key === 'Escape') { setEditing(false); setDraft(label); }\n          }}\n        />\n      ) : (\n        <span className=\"perm-manage-row-label\">{label}</span>\n      )}\n      <div className=\"perm-manage-row-actions\">\n        <Button\n          type=\"text\" size=\"small\" icon={<EditOutlined />}\n          onClick={() => { setDraft(label); setEditing(true); }}\n          loading={loading}\n        />\n        <Popconfirm\n          title=\"Delete this item?\"\n          onConfirm={onDelete}\n          okText=\"Delete\" cancelText=\"Cancel\" okType=\"danger\"\n        >\n          <Button type=\"text\" size=\"small\" icon={<DeleteOutlined />} danger />\n        </Popconfirm>\n      </div>\n    </div>\n  );\n}\n\nfunction ManageModal({ open, onClose }) {\n  const [tab, setTab] = useState('modules');\n\n  const [modules, setModules] = useState([]);\n  const [modLoading, setModLoading] = useState(false);\n  const [newModName, setNewModName] = useState('');\n  const [savingMod, setSavingMod] = useState(false);\n\n  const [actions, setActions] = useState([]);\n  const [actLoading, setActLoading] = useState(false);\n  const [newActName, setNewActName] = useState('');\n  const [newActKey, setNewActKey] = useState('');\n  const [savingAct, setSavingAct] = useState(false);\n\n  useEffect(() => {\n    if (!open) return;\n    loadModules();\n    loadActions();\n  }, [open]);\n\n  async function loadModules() {\n    setModLoading(true);\n    try { setModules(await getMenuModules()); }\n    catch { message.error('Failed to load modules'); }\n    finally { setModLoading(false); }\n  }\n\n  async function loadActions() {\n    setActLoading(true);\n    try { setActions(await getMenuActions()); }\n    catch { message.error('Failed to load actions'); }\n    finally { setActLoading(false); }\n  }\n\n  async function handleAddModule() {\n    const name = newModName.trim();\n    if (!name) { message.warning('Enter a module name'); return; }\n    setSavingMod(true);\n    try {\n      const created = await createMenuModule({ menuName: name });\n      setModules((prev) => [...prev, created]);\n      setNewModName('');\n      message.success('Module added');\n    } catch { message.error('Failed to add module'); }\n    finally { setSavingMod(false); }\n  }\n\n  async function handleUpdateModule(id, menuName) {\n    try {\n      await updateMenuModule(id, { menuName });\n      setModules((prev) => prev.map((m) => (m.MENUID === id ? { ...m, MENUNAME: menuName } : m)));\n    } catch { message.error('Failed to update module'); }\n  }\n\n  async function handleDeleteModule(id) {\n    try {\n      await deleteMenuModule(id);\n      setModules((prev) => prev.filter((m) => m.MENUID !== id));\n      message.success('Module deleted');\n    } catch { message.error('Failed to delete module'); }\n  }\n\n  async function handleAddAction() {\n    const name = newActName.trim();\n    const key  = newActKey.trim().toLowerCase().replace(/\\s+/g, '_');\n    if (!name || !key) { message.warning('Enter both name and key'); return; }\n    setSavingAct(true);\n    try {\n      const created = await createMenuAction({ permissionName: name, permissionKey: key });\n      setActions((prev) => [...prev, created]);\n      setNewActName('');\n      setNewActKey('');\n      message.success('Action added');\n    } catch (err) {\n      message.error(err?.message?.includes('409') || err?.status === 409\n        ? 'Permission key already exists'\n        : 'Failed to add action'\n      );\n    } finally { setSavingAct(false); }\n  }\n\n  async function handleUpdateAction(id, permissionName) {\n    try {\n      await updateMenuAction(id, { permissionName });\n      setActions((prev) => prev.map((a) => (a.permissionId === id ? { ...a, permissionName } : a)));\n    } catch { message.error('Failed to update action'); }\n  }\n\n  async function handleDeleteAction(id) {\n    try {\n      await deleteMenuAction(id);\n      setActions((prev) => prev.filter((a) => a.permissionId !== id));\n      message.success('Action deleted');\n    } catch { message.error('Failed to delete action'); }\n  }\n\n  const tabItems = [\n    {\n      key: 'modules',\n      label: 'Modules',\n      children: (\n        <Spin spinning={modLoading}>\n          <div className=\"perm-manage-add-row\">\n            <Input\n              placeholder=\"Module name\"\n              value={newModName}\n              onChange={(e) => setNewModName(e.target.value)}\n              onPressEnter={handleAddModule}\n              style={{ flex: 1 }}\n              size=\"small\"\n            />\n            <Button\n              type=\"primary\" size=\"small\" icon={<PlusOutlined />}\n              loading={savingMod} onClick={handleAddModule}\n            >\n              Add\n            </Button>\n          </div>\n          <div className=\"perm-manage-list\">\n            {modules.length === 0 && !modLoading && (\n              <div className=\"perm-empty\" style={{ paddingTop: 24 }}>No modules found</div>\n            )}\n            {modules.map((m) => (\n              <EditableRow\n                key={m.MENUID}\n                label={m.MENUNAME}\n                onSave={(v) => handleUpdateModule(m.MENUID, v)}\n                onDelete={() => handleDeleteModule(m.MENUID)}\n              />\n            ))}\n          </div>\n        </Spin>\n      ),\n    },\n    {\n      key: 'actions',\n      label: 'Actions',\n      children: (\n        <Spin spinning={actLoading}>\n          <div className=\"perm-manage-add-row\">\n            <Input\n              placeholder=\"Action name (e.g. Approve)\"\n              value={newActName}\n              onChange={(e) => setNewActName(e.target.value)}\n              style={{ flex: 1 }}\n              size=\"small\"\n            />\n            <Input\n              placeholder=\"Key (e.g. approve)\"\n              value={newActKey}\n              onChange={(e) => setNewActKey(e.target.value)}\n              onPressEnter={handleAddAction}\n              style={{ width: 140 }}\n              size=\"small\"\n            />\n            <Button\n              type=\"primary\" size=\"small\" icon={<PlusOutlined />}\n              loading={savingAct} onClick={handleAddAction}\n            >\n              Add\n            </Button>\n          </div>\n          <div className=\"perm-manage-list\">\n            {actions.length === 0 && !actLoading && (\n              <div className=\"perm-empty\" style={{ paddingTop: 24 }}>No actions found</div>\n            )}\n            {actions.map((a) => (\n              <EditableRow\n                key={a.permissionId}\n                label={`${a.permissionName} (${a.permissionKey})`}\n                onSave={(v) => handleUpdateAction(a.permissionId, v)}\n                onDelete={() => handleDeleteAction(a.permissionId)}\n              />\n            ))}\n          </div>\n        </Spin>\n      ),\n    },\n  ];\n\n  return (\n    <Modal\n      open={open}\n      onCancel={onClose}\n      title={\n        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n          <SettingOutlined style={{ color: 'var(--color-brand)' }} />\n          Manage Modules & Actions\n        </span>\n      }\n      width={520}\n      footer={null}\n      destroyOnClose\n    >\n      <Tabs activeKey={tab} onChange={setTab} size=\"small\" items={tabItems} />\n    </Modal>\n  );\n}\n\n// ── Main page ─────────────────────────────────────────────────────────────────\n\nexport default function PermissionsPage() {\n  const [roles,        setRoles]        = useState([]);\n  const [rolesLoading, setRolesLoading] = useState(false);\n  const [selectedRole, setSelectedRole] = useState(null);\n  const [search,       setSearch]       = useState('');\n  const [manageOpen,   setManageOpen]   = useState(false);\n\n  const [moduleLabels, setModuleLabels] = useState(() => readLS(LS_MODULE));\n  const [actionLabels, setActionLabels] = useState(() => readLS(LS_ACTION));\n\n  const saveModuleLabel = useCallback((rawName, label) => {\n    setModuleLabels((prev) => {\n      const next = { ...prev, [rawName]: label };\n      writeLS(LS_MODULE, next);\n      return next;\n    });\n  }, []);\n\n  const saveActionLabel = useCallback((key, label) => {\n    setActionLabels((prev) => {\n      const next = { ...prev, [key]: label };\n      writeLS(LS_ACTION, next);\n      return next;\n    });\n  }, []);\n\n  function resetLabels() {\n    setModuleLabels({});\n    setActionLabels({});\n    writeLS(LS_MODULE, {});\n    writeLS(LS_ACTION, {});\n    message.success('Labels reset to defaults');\n  }\n\n  const fetchRoles = useCallback(async () => {\n    setRolesLoading(true);\n    try {\n      const { roles: r } = await getAllRoles();\n      setRoles(r);\n      if (r.length > 0) setSelectedRole(r[0]);\n    } catch {\n      message.error('Failed to load roles');\n    } finally {\n      setRolesLoading(false);\n    }\n  }, []);\n\n  useEffect(() => { fetchRoles(); }, [fetchRoles]);\n\n  const filteredRoles = useMemo(() => {\n    const q = search.trim().toLowerCase();\n    return q ? roles.filter((r) => r.roleName.toLowerCase().includes(q)) : roles;\n  }, [roles, search]);\n\n  const hasCustomLabels = Object.keys(moduleLabels).length > 0 || Object.keys(actionLabels).length > 0;\n\n  return (\n    <div className=\"perm-page\">\n\n      {/* ── Left: Role list ── */}\n      <AppCard\n        className=\"perm-left-card\"\n        icon={<SafetyOutlined />}\n        title=\"Roles\"\n        bodyStyle={{ padding: 0 }}\n      >\n        <div className=\"perm-role-search\">\n          <Input\n            prefix={<SearchOutlined />}\n            placeholder=\"Search roles…\"\n            allowClear\n            size=\"small\"\n            value={search}\n            onChange={(e) => setSearch(e.target.value)}\n          />\n        </div>\n        <Spin spinning={rolesLoading}>\n          <div className=\"perm-role-list\">\n            {filteredRoles.length === 0 && !rolesLoading && (\n              <div className=\"perm-role-empty\">No roles found</div>\n            )}\n            {filteredRoles.map((role) => {\n              const active = selectedRole?.roleId === role.roleId;\n              const desc = role.description && role.description !== 'N/A'\n                ? role.description\n                : role.roleType === 0 ? 'Default role' : 'Custom role';\n              return (\n                <div\n                  key={role.roleId}\n                  className={`perm-role-item${active ? ' active' : ''}`}\n                  onClick={() => setSelectedRole(role)}\n                >\n                  <div className=\"perm-role-item-name\">{role.roleName}</div>\n                  <div className=\"perm-role-item-desc\">{desc}</div>\n                </div>\n              );\n            })}\n          </div>\n        </Spin>\n      </AppCard>\n\n      {/* ── Right: Module cards ── */}\n      <AppCard\n        className=\"perm-right-card\"\n        icon={<LockOutlined />}\n        title=\"Module Permissions\"\n        extra={\n          <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n            {hasCustomLabels && (\n              <button className=\"perm-reset-btn\" onClick={resetLabels}>\n                Reset labels\n              </button>\n            )}\n            <Button\n              size=\"small\"\n              icon={<SettingOutlined />}\n              onClick={() => setManageOpen(true)}\n            >\n              Manage\n            </Button>\n          </span>\n        }\n        bodyStyle={{ padding: '12px 16px' }}\n      >\n        {selectedRole ? (\n          <RolePermPanel\n            key={selectedRole.roleId}\n            role={selectedRole}\n            moduleLabels={moduleLabels}\n            actionLabels={actionLabels}\n            onModuleLabelSave={saveModuleLabel}\n            onActionLabelSave={saveActionLabel}\n          />\n        ) : (\n          <div className=\"perm-empty\">Select a role from the left to manage its permissions.</div>\n        )}\n      </AppCard>\n\n      <ManageModal open={manageOpen} onClose={() => setManageOpen(false)} />\n\n    </div>\n  );\n}\n","import { Button, Card, Row, Col, Statistic, Typography } from 'antd';\n\nconst { Title, Text } = Typography;\n\nconst defaultItems = [\n  { label: 'In Progress',       value: 107, sub: 'Under review',        color: 'blue'   },\n  { label: 'Hired',             value: 2,   sub: 'Onboarded',           color: 'green'  },\n  { label: 'Project Completed', value: 2,   sub: 'Project cycle closed', color: 'purple' },\n  { label: 'Archive',           value: 2,   sub: 'No longer active',    color: 'peach'  },\n];\n\nexport default function OnboardingCard({ items = defaultItems }) {\n  return (\n    <Card\n      className=\"onboarding-card\"\n      title={<Title level={5}>Onboarding</Title>}\n      extra={<Button type=\"link\">View all</Button>}\n    >\n      <Row gutter={[12, 12]}>\n        {items.map(it => (\n          <Col key={it.label} xs={12} sm={6} md={6} lg={12} xl={12}>\n            <div className={`onboarding-item ${it.color}`}>\n              <Text className=\"onboarding-item-label\">{it.label}</Text>\n              <Statistic value={it.value} className=\"onboarding-stat\" />\n              <div className=\"onboarding-item-footer\">\n                <Text className=\"onboarding-item-sub\">{it.sub}</Text>\n              </div>\n            </div>\n          </Col>\n        ))}\n      </Row>\n    </Card>\n  );\n}\n","import { useMemo, useState } from \"react\";\nimport {\n    Breadcrumb, Button, Col, Empty,\n    Input, Menu, Row, Statistic, Typography,\n} from \"antd\";\nimport {\n    AppstoreOutlined, AppstoreAddOutlined, BankOutlined, BellOutlined, BuildOutlined,\n    CheckCircleOutlined, DashboardOutlined, FileTextOutlined,\n    HomeOutlined, LockOutlined, RightOutlined, SafetyOutlined,\n    SearchOutlined, SettingOutlined, TeamOutlined, ThunderboltOutlined, ToolOutlined, UserOutlined,\n} from \"@ant-design/icons\";\n\nimport AppCard from \"../../components/cards/AppCard\";\nimport \"../../styles/AdminPage.css\";\nimport StatsCards from \"../../components/cards/StatsCards\";\nimport FormGroupsSection from \"./Admin/FormGroupsSection\";\nimport DetailGroupsSection from \"./Admin/DetailGroupsSection\";\nimport ActionsSection from \"./Admin/ActionsSection\";\nimport UsersSection from \"./Admin/UsersSection\";\nimport TeamsSection from \"./Admin/TeamsSection\";\nimport RolesSection from \"./Admin/RolesSection\";\nimport PermissionsPage from \"./Admin/PermissionsPage\";\nimport TemplatesSection from \"./Admin/TemplatesSection\";\nimport AiServiceSettingsSection from \"./Admin/AiServiceSettingsSection\";\nimport IntegrationSettingsSection from \"./Admin/IntegrationSettingsSection\";\nimport OnboardingCard from \"../../components/cards/OnboardingCard\";\n\nconst { Text, Title } = Typography;\n\n/* ─────────────────────────────────────────────\nDATA\n───────────────────────────────────────────── */\nconst adminSections = [\n    {\n        group: \"Dashboard\",\n        items: [\n            {\n                id: \"dashboard\",\n                label: \"Admin Dashboard\",\n                icon: <DashboardOutlined />,\n            },\n        ],\n    },\n    {\n        group: \"Settings\",\n        items: [\n            {\n                id: \"org\", label: \"Organization\", icon: <BankOutlined />,\n                heading: \"Organization Settings\",\n                desc: \"Manage your company profile and location details\",\n                cards: [\n                    { label: \"Company Information\", icon: <BankOutlined />, desc: \"Manage company profile, address and business details.\" },\n                    { label: \"Location\", icon: <BuildOutlined />, desc: \"Manage office locations, branches and regions.\" },\n                ],\n            },\n            {\n                id: \"users\", label: \"Users\", icon: <UserOutlined />,\n                heading: \"Users\",\n                desc: \"Manage platform users and configure their field views.\",\n                component: \"users\",\n            },\n            {\n                id: \"teams\", label: \"Teams\", icon: <TeamOutlined />,\n                heading: \"Teams\",\n                desc: \"Organize users into teams and configure field visibility per team.\",\n                component: \"teams\",\n            },\n            {\n                id: \"roles\", label: \"Roles\", icon: <SafetyOutlined />,\n                heading: \"Roles\",\n                desc: \"Control permissions and configure field visibility per role.\",\n                component: \"roles\",\n            },\n            {\n                id: \"permissions\", label: \"Permissions\", icon: <LockOutlined />,\n                heading: \"Permissions\",\n                desc: \"Manage module-wise action permissions (view, add, edit, delete, and more) per role.\",\n                component: \"permissions\",\n            },\n            {\n                id: \"templates\", label: \"Templates\", icon: <FileTextOutlined />,\n                heading: \"Templates\",\n                desc: \"Email and signature templates for communications\",\n                component: \"templates\",\n            },\n            {\n                id: \"ai-services\", label: \"AI Services\", icon: <ThunderboltOutlined />,\n                heading: \"AI Services\",\n                desc: \"Register the AI/automation backends (base URL + auth) that admin-configured AI Actions call.\",\n                component: \"ai-services\",\n            },\n            {\n                id: \"bgc-integration\", label: \"Integrations\", icon: <SafetyOutlined />,\n                heading: \"Integrations\",\n                desc: \"Manage manual and API integrations used across application workflows.\",\n                component: \"bgc-integration\",\n            },\n        ],\n    },\n    {\n        group: \"Clients\",\n        items: [\n            {\n                id: \"clients\", label: \"Clients\", icon: <BankOutlined />,\n                heading: \"Clients\",\n                desc: \"Manage client accounts and settings\",\n                cards: [\n                    { label: \"Clients\", icon: <BankOutlined />, desc: \"Manage client companies and account details.\" },\n                ],\n            },\n        ],\n    },\n    {\n        group: \"Forms\",\n        items: [\n            {\n                id: \"form-groups\",\n                label: \"Form Groups\",\n                icon: <AppstoreAddOutlined />,\n                heading: \"Form Groups\",\n                desc: \"Define field groups for module add/edit forms with validations and dropdown sources.\",\n                component: \"form-groups\",\n            },\n            {\n                id: \"detail-groups\",\n                label: \"Detail Groups\",\n                icon: <AppstoreOutlined />,\n                heading: \"Detail Groups\",\n                desc: \"Customize the detail view per module: labels, prefix/suffix, colour, capitalization, reference lookups and merged fields.\",\n                component: \"detail-groups\",\n            },\n            {\n                id: \"row-actions\",\n                label: \"Actions\",\n                icon: <ToolOutlined />,\n                heading: \"Actions\",\n                desc: \"Configure which action buttons appear per row in each module's list view, scoped per role.\",\n                component: \"row-actions\",\n            },\n        ],\n    },\n    {\n        group: \"Master\",\n        items: [\n            {\n                id: \"jobs\", label: \"Jobs\", icon: <AppstoreOutlined />,\n                heading: \"Jobs Master\",\n                desc: \"Configure job sources and status types\",\n                cards: [\n                    { label: \"Sources\", icon: <AppstoreOutlined />, desc: \"Manage job source master values.\" },\n                    { label: \"Job Status\", icon: <CheckCircleOutlined />, desc: \"Configure job workflow status.\" },\n                ],\n            },\n            {\n                id: \"candidates\", label: \"Candidates\", icon: <UserOutlined />,\n                heading: \"Candidates Master\",\n                desc: \"Skills, sources and work authorization settings\",\n                cards: [\n                    { label: \"Sources\", icon: <AppstoreOutlined />, desc: \"Manage candidate source values.\" },\n                    { label: \"Skills\", icon: <SettingOutlined />, desc: \"Manage skill master data.\" },\n                    { label: \"Work Authorization\", icon: <SafetyOutlined />, desc: \"Manage visa and authorization types.\" },\n                ],\n            },\n            {\n                id: \"submissions\", label: \"Submissions\", icon: <FileTextOutlined />,\n                heading: \"Submissions Master\",\n                desc: \"Rejection reasons and submission status configuration\",\n                cards: [\n                    { label: \"Rejection Reasons\", icon: <FileTextOutlined />, desc: \"Manage common rejection reasons.\" },\n                    { label: \"Client Submission Status\", icon: <CheckCircleOutlined />, desc: \"Manage client submission statuses.\" },\n                ],\n            },\n            {\n                id: \"clientmaster\", label: \"Client Master\", icon: <BankOutlined />,\n                heading: \"Client Master\",\n                desc: \"Payment terms, client types and contact types\",\n                cards: [\n                    { label: \"Payment Terms\", icon: <FileTextOutlined />, desc: \"Manage billing and payment terms.\" },\n                    { label: \"Client Type\", icon: <AppstoreOutlined />, desc: \"Classify client business types.\" },\n                    { label: \"Client Contact Type\", icon: <TeamOutlined />, desc: \"Manage client contact categories.\" },\n                ],\n            },\n        ],\n    },\n];\n\n/* ─────────────────────────────────────────────\nDASHBOARD STATIC DATA\n───────────────────────────────────────────── */\nconst dashboardStats = [\n    { label: \"Total Jobs\", value: 1697, sub: \"+12 this week\", icon: <FileTextOutlined /> },\n    { label: \"Active Jobs\", value: 1685, sub: \"99.3% active rate\", icon: <CheckCircleOutlined /> },\n    { label: \"My Jobs\", value: 600, sub: \"35% of total\", icon: <UserOutlined /> },\n    { label: \"Total Candidates\", value: 4320, sub: \"+84 this month\", icon: <TeamOutlined /> },\n    { label: \"Submissions\", value: 892, sub: \"312 pending\", icon: <FileTextOutlined /> },\n];\n\nconst onboardingItems = [\n    { label: \"In Progress\", value: 107, sub: \"Under review\", color: \"blue\" },\n    { label: \"Hired\", value: 2, sub: \"Onboarded\", color: \"green\" },\n    { label: \"Project Completed\", value: 2, sub: \"Project cycle closed\", color: \"purple\" },\n    { label: \"Archive\", value: 2, sub: \"No longer active\", color: \"peach\" },\n];\n\nconst pipelineStages = [\n    { label: \"Sourced\", count: 312, color: \"#378ADD\", pct: 35 },\n    { label: \"Screened\", count: 223, color: \"#7F77DD\", pct: 25 },\n    { label: \"Interview\", count: 161, color: \"#1D9E75\", pct: 18 },\n    { label: \"Offered\", count: 107, color: \"#EF9F27\", pct: 12 },\n    { label: \"Rejected\", count: 89, color: \"#E24B4A\", pct: 10 },\n];\n\nconst topClients = [\n    { name: \"Tcs\", jobs: 14, candidates: 86 },\n    { name: \"Empasis\", jobs: 9, candidates: 64 },\n    { name: \"NovaSystems\", jobs: 7, candidates: 51 },\n    { name: \"Brightwave\", jobs: 5, candidates: 38 },\n];\n\nconst recentActivity = [\n    { text: \"New candidate Ravi Kumar added to Java Developer role\", time: \"2 min ago\", color: \"#378ADD\" },\n    { text: \"Submission approved by Acme Corp for Sr. React Dev\", time: \"18 min ago\", color: \"#1D9E75\" },\n    { text: \"User Priya S. added to Recruiters team\", time: \"1 hr ago\", color: \"#7F77DD\" },\n    { text: \"Job Data Analyst — TechFlow moved to archived\", time: \"3 hr ago\", color: \"#EF9F27\" },\n    { text: \"Candidate rejected — work authorization mismatch\", time: \"5 hr ago\", color: \"#E24B4A\" },\n];\n\n/* ─────────────────────────────────────────────\nSUB-COMPONENTS\n───────────────────────────────────────────── */\n\n/** Full dashboard view rendered when activeId === \"dashboard\" */\nfunction DashboardContent() {\n    return (\n        <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n\n            {/* Header card */}\n            <AppCard icon={<DashboardOutlined />} title=\"Admin Dashboard\">\n                <div className=\"admin-accent-bar\" />\n                <Title level={5}>Admin Dashboard</Title>\n                <Text type=\"secondary\">\n                    Overview of jobs, candidates, onboarding and recent activity\n                </Text>\n            </AppCard>\n\n            {/* Stats row */}\n            <div className=\"admin-dashboard-stats\">\n                <StatsCards stats={[\n                    { label: \"Total Jobs\", value: 1697, icon: \"fileText\" },\n                    { label: \"Active Jobs\", value: 1685, icon: \"checkCircle\" },\n                    { label: \"My Jobs\", value: 600, icon: \"user\" },\n                    { label: \"Total Candidates\", value: 4320, icon: \"team\" },\n                    { label: \"Submissions\", value: 892, icon: \"fileText\" },\n                ]} />\n            </div>\n\n            {/* Onboarding + Pipeline */}\n            <div className=\"admin-dashboard-mid-row\">\n                <OnboardingCard />\n\n                <AppCard icon={<AppstoreOutlined />} title=\"Candidate Pipeline\">\n                    <Text type=\"secondary\" style={{ fontSize: 12 }}>By stage (892 total)</Text>\n                    <div className=\"admin-pipeline-bar\">\n                        {pipelineStages.map((s) => (\n                            <div key={s.label} className=\"admin-pipeline-seg\"\n                                style={{ width: `${s.pct}%`, background: s.color }} />\n                        ))}\n                    </div>\n                    <div className=\"admin-pipeline-legend\">\n                        {pipelineStages.map((s) => (\n                            <div key={s.label} className=\"admin-pipeline-legend-item\">\n                                <span className=\"admin-pipeline-dot\" style={{ background: s.color }} />\n                                {s.label} {s.count}\n                            </div>\n                        ))}\n                    </div>\n                    <div className=\"admin-divider\" />\n                    <Text strong style={{ fontSize: 12 }}>Submission status</Text>\n                    <div className=\"admin-sub-status-list\" style={{ marginTop: 6 }}>\n                        <div className=\"admin-sub-status-item\">\n                            <Text style={{ fontSize: 13 }}>Pending client review</Text>\n                            <span className=\"admin-badge warn\">312</span>\n                        </div>\n                        <div className=\"admin-sub-status-item\">\n                            <Text style={{ fontSize: 13 }}>Client approved</Text>\n                            <span className=\"admin-badge success\">248</span>\n                        </div>\n                        <div className=\"admin-sub-status-item\">\n                            <Text style={{ fontSize: 13 }}>Rejected</Text>\n                            <span className=\"admin-badge danger\">89</span>\n                        </div>\n                    </div>\n                </AppCard>\n            </div>\n\n            {/* Top Clients + Recent Activity */}\n            <div className=\"admin-dashboard-bottom-row\">\n                <AppCard\n                    icon={<BankOutlined />}\n                    title=\"Top Clients\"\n                    extra={<Button type=\"link\" size=\"small\">View all</Button>}\n                >\n                    {topClients.map((c) => (\n                        <div key={c.name} className=\"admin-client-row\">\n                            <div className=\"admin-client-left\">\n                                <div className=\"admin-client-icon\"><BankOutlined /></div>\n                                <div>\n                                    <div className=\"admin-client-name\">{c.name}</div>\n                                    <div className=\"admin-client-sub\">{c.jobs} open jobs</div>\n                                </div>\n                            </div>\n                            <div className=\"admin-client-right\">\n                                <div className=\"admin-client-val\">{c.candidates}</div>\n                                <div className=\"admin-client-sub\">candidates</div>\n                            </div>\n                        </div>\n                    ))}\n                </AppCard>\n\n                <AppCard icon={<BellOutlined />} title=\"Recent Activity\">\n                    {recentActivity.map((a, i) => (\n                        <div key={i} className=\"admin-activity-row\">\n                            <div className=\"admin-activity-dot\" style={{ background: a.color }} />\n                            <div>\n                                <div className=\"admin-activity-text\">{a.text}</div>\n                                <div className=\"admin-activity-time\">{a.time}</div>\n                            </div>\n                        </div>\n                    ))}\n                </AppCard>\n            </div>\n\n            {/* Config overview */}\n            <AppCard\n                icon={<SettingOutlined />}\n                title=\"Admin Configuration Overview\"\n                extra={<Button type=\"link\" size=\"small\">Manage</Button>}\n            >\n                <Row gutter={[24, 0]}>\n                    <Col span={8}>\n                        <Text type=\"secondary\" style={{ fontSize: 12, fontWeight: 500 }}>Settings</Text>\n                        {[[\"Organization\", 2], [\"User Settings\", 4], [\"Templates\", 2]].map(([k, v]) => (\n                            <div key={k} className=\"admin-cfg-overview-row\">\n                                <Text style={{ fontSize: 12 }}>{k}</Text>\n                                <span className=\"admin-badge info\">{v} items</span>\n                            </div>\n                        ))}\n                    </Col>\n                    <Col span={8}>\n                        <Text type=\"secondary\" style={{ fontSize: 12, fontWeight: 500 }}>Master</Text>\n                        {[[\"Jobs\", 2], [\"Candidates\", 3], [\"Submissions\", 2]].map(([k, v]) => (\n                            <div key={k} className=\"admin-cfg-overview-row\">\n                                <Text style={{ fontSize: 12 }}>{k}</Text>\n                                <span className=\"admin-badge info\">{v} items</span>\n                            </div>\n                        ))}\n                    </Col>\n                    <Col span={8}>\n                        <Text type=\"secondary\" style={{ fontSize: 12, fontWeight: 500 }}>System</Text>\n                        {[[\"Total Groups\", 4], [\"Total Modules\", 9], [\"Config Items\", 19]].map(([k, v]) => (\n                            <div key={k} className=\"admin-cfg-overview-row\">\n                                <Text style={{ fontSize: 12 }}>{k}</Text>\n                                <Text strong style={{ fontSize: 12 }}>{v}</Text>\n                            </div>\n                        ))}\n                    </Col>\n                </Row>\n            </AppCard>\n\n        </div>\n    );\n}\n\n/** Config items view for Settings / Master sections */\nfunction SettingsContent({ activeSection, activeGroup, filteredCards, searchText, setSearchText, allItems, handleNav }) {\n    return (\n        <Row gutter={[16, 16]}>\n\n            {/* Header */}\n            <Col span={24}>\n                <AppCard\n                    icon={activeSection?.icon}\n                    title={activeSection?.heading}\n                    extra={\n                        <Input\n                            className=\"admin-search\"\n                            prefix={<SearchOutlined />}\n                            placeholder=\"Search settings…\"\n                            allowClear\n                            value={searchText}\n                            onChange={(e) => setSearchText(e.target.value)}\n                        />\n                    }\n                >\n                    <div className=\"admin-accent-bar\" />\n                    <Title level={5}>{activeSection?.heading}</Title>\n                    <Text type=\"secondary\">{activeSection?.desc}</Text>\n                </AppCard>\n            </Col>\n\n            {/* Config items */}\n            <Col xs={24} xl={16} style={{ alignSelf: \"flex-start\" }}>\n                <AppCard\n                    icon={<AppstoreOutlined />}\n                    title=\"Configuration Items\"\n                    extra={\n                        <Text type=\"secondary\">\n                            {filteredCards.length} item{filteredCards.length !== 1 ? \"s\" : \"\"}\n                        </Text>\n                    }\n                >\n                    <Row gutter={[14, 14]}>\n                        {filteredCards.length > 0 ? (\n                            filteredCards.map((card) => (\n                                <Col xs={24} sm={12} xl={8} key={card.label}>\n                                    <div className=\"admin-config-item\">\n                                        <div className=\"admin-config-top-bar\" />\n                                        <div className=\"admin-config-body\">\n                                            <div className=\"admin-config-icon\">{card.icon}</div>\n                                            <div className=\"admin-config-text\">\n                                                <span className=\"admin-config-label\">{card.label}</span>\n                                                <span className=\"admin-config-desc\">{card.desc}</span>\n                                            </div>\n                                        </div>\n                                        <div className=\"admin-config-divider\" />\n                                        <Button\n                                            type=\"link\"\n                                            size=\"small\"\n                                            className=\"admin-config-manage\"\n                                            icon={<RightOutlined />}\n                                            iconPosition=\"end\"\n                                        >\n                                            Manage\n                                        </Button>\n                                    </div>\n                                </Col>\n                            ))\n                        ) : (\n                            <Col span={24}>\n                                <div className=\"admin-config-empty\">\n                                    <Empty\n                                        description=\"No settings found\"\n                                        image={Empty.PRESENTED_IMAGE_SIMPLE}\n                                    />\n                                </div>\n                            </Col>\n                        )}\n                    </Row>\n                </AppCard>\n            </Col>\n\n            {/* Section overview */}\n            <Col xs={24} xl={8} style={{ alignSelf: \"flex-start\" }}>\n                <AppCard icon={<FileTextOutlined />} title=\"Section Overview\">\n                    <div className=\"admin-overview-list\">\n                        {adminSections\n                            .filter((s) => s.group !== \"Dashboard\")\n                            .map((section) => {\n                                const isActive = section.group === activeGroup?.group;\n                                return (\n                                    <div\n                                        key={section.group}\n                                        className={`admin-overview-item${isActive ? \" active\" : \"\"}`}\n                                        onClick={() => {\n                                            const first = section.items[0];\n                                            if (first) handleNav(first.id);\n                                        }}\n                                    >\n                                        <div className=\"admin-overview-left\">\n                                            <div className=\"admin-overview-icon\">\n                                                {section.items[0]?.icon}\n                                            </div>\n                                            <div className=\"admin-overview-text\">\n                                                <span className=\"admin-overview-name\">{section.group}</span>\n                                                <span className=\"admin-overview-sub\">\n                                                    {section.items.length} module{section.items.length !== 1 ? \"s\" : \"\"}\n                                                </span>\n                                            </div>\n                                        </div>\n                                        <span className={`admin-overview-count${isActive ? \" active\" : \"\"}`}>\n                                            {section.items.length}\n                                        </span>\n                                    </div>\n                                );\n                            })}\n                    </div>\n                    <div className=\"admin-overview-footer\">\n                        <span className=\"admin-overview-footer-label\">Total configuration items</span>\n                        <span className=\"admin-overview-footer-value\">\n                            {allItems.filter((i) => i.cards).reduce((acc, i) => acc + i.cards.length, 0)}\n                        </span>\n                    </div>\n                </AppCard>\n            </Col>\n\n        </Row>\n    );\n}\n\n/* ─────────────────────────────────────────────\nMAIN PAGE\n───────────────────────────────────────────── */\nexport default function AdminPage() {\n    const [activeId, setActiveId] = useState(\"dashboard\");\n    const [searchText, setSearchText] = useState(\"\");\n\n    const allItems = useMemo(() => adminSections.flatMap((s) => s.items), []);\n\n    const activeSection = useMemo(\n        () => allItems.find((i) => i.id === activeId),\n        [allItems, activeId]\n    );\n\n    const activeGroup = useMemo(\n        () => adminSections.find((s) => s.items.some((i) => i.id === activeId)),\n        [activeId]\n    );\n\n    const filteredCards = useMemo(() => {\n        if (!activeSection?.cards) return [];\n        const q = searchText.trim().toLowerCase();\n        if (!q) return activeSection.cards;\n        return activeSection.cards.filter(\n            (c) => c.label.toLowerCase().includes(q) || c.desc.toLowerCase().includes(q)\n        );\n    }, [activeSection, searchText]);\n\n    const menuItems = useMemo(\n        () =>\n            adminSections.map((s) => ({\n                key: s.group,\n                type: \"group\",\n                label: s.group,\n                children: s.items.map((item) => ({\n                    key: item.id,\n                    icon: item.icon,\n                    label: item.label,\n                })),\n            })),\n        []\n    );\n\n    const handleNav = (id) => {\n        setActiveId(id);\n        setSearchText(\"\");\n    };\n\n    /* Breadcrumb last crumb */\n    const activeCrumb = activeId === \"dashboard\"\n        ? \"Admin Dashboard\"\n        : activeSection?.heading ?? \"Admin\";\n\n    return (\n        <main className=\"admin-page\">\n\n            {/* Breadcrumb */}\n            <div className=\"admin-breadcrumb\">\n                <Breadcrumb\n                    items={[\n                        { title: <><HomeOutlined /> Home</> },\n                        { title: \"Admin\" },\n                        // { title: activeCrumb },\n                    ]}\n                />\n            </div>\n\n            <Row gutter={[16, 16]} className=\"admin-wrapper\">\n\n                {/* ════ SIDEBAR ════ */}\n                <Col xs={24} lg={6} xl={5}>\n                    <AppCard title=\"Admin Console\" icon={<SettingOutlined />}>\n\n                        {/* Gradient banner */}\n                        <div className=\"admin-sidebar-banner\">\n                            <span className=\"admin-sidebar-banner-title\">Admin Panel</span>\n                            <span className=\"admin-sidebar-banner-sub\">Configuration Center</span>\n                            <Row gutter={[8, 0]}>\n                                <Col span={12}>\n                                    <div className=\"admin-sidebar-pill\">\n                                        <span className=\"admin-sidebar-pill-label\">Groups</span>\n                                        <span className=\"admin-sidebar-pill-value\">\n                                            {adminSections.length}\n                                        </span>\n                                    </div>\n                                </Col>\n                                <Col span={12}>\n                                    <div className=\"admin-sidebar-pill\">\n                                        <span className=\"admin-sidebar-pill-label\">Modules</span>\n                                        <span className=\"admin-sidebar-pill-value\">\n                                            {allItems.length}\n                                        </span>\n                                    </div>\n                                </Col>\n                            </Row>\n                        </div>\n\n                        {/* Menu */}\n                        <Menu\n                            mode=\"inline\"\n                            selectedKeys={[activeId]}\n                            items={menuItems}\n                            onClick={({ key }) => handleNav(key)}\n                            className=\"admin-sidebar-menu\"\n                        />\n                    </AppCard>\n                </Col>\n\n                {/* ════ CONTENT ════ */}\n                <Col xs={24} lg={18} xl={19}>\n                    {activeId === \"dashboard\" ? (\n                        <DashboardContent />\n                    ) : activeSection?.component === \"form-groups\" ? (\n                        <FormGroupsSection />\n                    ) : activeSection?.component === \"detail-groups\" ? (\n                        <DetailGroupsSection />\n                    ) : activeSection?.component === \"row-actions\" ? (\n                        <ActionsSection />\n                    ) : activeSection?.component === \"users\" ? (\n                        <UsersSection />\n                    ) : activeSection?.component === \"teams\" ? (\n                        <TeamsSection />\n                    ) : activeSection?.component === \"roles\" ? (\n                        <RolesSection />\n                    ) : activeSection?.component === \"permissions\" ? (\n                        <PermissionsPage />\n                    ) : activeSection?.component === \"templates\" ? (\n                        <TemplatesSection />\n                    ) : activeSection?.component === \"ai-services\" ? (\n                        <AiServiceSettingsSection />\n                    ) : activeSection?.component === \"bgc-integration\" ? (\n                        <IntegrationSettingsSection />\n                    ) : (\n                        <SettingsContent\n                            activeSection={activeSection}\n                            activeGroup={activeGroup}\n                            filteredCards={filteredCards}\n                            searchText={searchText}\n                            setSearchText={setSearchText}\n                            allItems={allItems}\n                            handleNav={handleNav}\n                        />\n                    )}\n                </Col>\n\n            </Row>\n        </main>\n    );\n}\n","import { Typography, Button } from \"antd\";\nimport { ArrowLeftOutlined } from \"@ant-design/icons\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport DynamicCards from \"../components/cards/DynamicCards\";\n\nconst { Title } = Typography;\n\n/*\n  Full \"View all\" page for the dashboard Sticky Notes card.\n\n  The dashboard card (see pages/DynamicCards/index.jsx) renders the notes with a\n  display limit (layout=\"2x2\" -> 4 cards). When the user clicks \"View all\", the\n  sticky card navigates here and passes — via router state — the moduleName and\n  the exact API request it used. We re-render the SAME sticky list, but:\n    • drop the dashboard's display cap (no layout/maxCount) so every note shows\n    • bump the request limit so the API returns the full list, not just a page\n    • hide the \"View all\" link (this IS the full page)\n*/\nexport default function StickyNotesFullPage() {\n  const navigate = useNavigate();\n  const { state } = useLocation();\n\n  // Falls back to sensible defaults if the page is opened directly (no state).\n  const moduleName = state?.moduleName || \"stickyNotes\";\n  const title = state?.title || \"Sticky Notes\";\n\n  // Reuse the dashboard's API call values, but lift the limit so we fetch all.\n  const request = {\n    ...state?.request,\n    params: { ...state?.request?.params, limit: 200, offset: 0 },\n  };\n\n  return (\n    <div>\n      <Button\n        type=\"text\"\n        icon={<ArrowLeftOutlined />}\n        onClick={() => navigate(-1)}\n        style={{ marginBottom: 12 }}\n      >\n        Back\n      </Button>\n\n\n      {/* No layout/maxCount -> the full list; viewAll={false} -> no self-link. */}\n      <DynamicCards\n        moduleName={moduleName}\n        title={title}\n        columns={4}\n        request={request}\n        viewAll={false}\n      />\n    </div>\n  );\n}","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n  Alert,\n  Badge,\n  Button,\n  Card,\n  Col,\n  Progress,\n  Row,\n  Tooltip,\n  Select,\n  Space,\n  Tag,\n  Typography,\n  message,\n} from 'antd';\nimport {\n  CheckCircleOutlined,\n  CloudUploadOutlined,\n  DownloadOutlined,\n  ExclamationCircleOutlined,\n  InfoCircleOutlined,\n  ReloadOutlined,\n  SaveOutlined,\n} from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport { bulkInsertTestSteps, getCTModules, validateTestSteps } from '../../services/testingApi';\nimport { getSelectedProject } from '../../services/authApi';\nimport '../../styles/test-page.css';\n\nconst { Text, Title } = Typography;\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024;\nconst TEMPLATE_BASE64_URL = '/templates/test_cases_flow_template.base64.txt';\nconst TEMPLATE_FILENAME = 'test_cases_flow_template.xlsx';\nconst HEADERS_HINT = 'module | subModule | step_order | description | actions | key | value | expected | scenario';\nconst STEP_INDEX = {\n  idle: 0,\n  module_set: 1,\n  encoding: 1,\n  validating: 2,\n  preview: 3,\n  inserting: 3,\n  done: 4,\n  error: 1,\n};\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/addTestCase' },\n  { label: 'Bulk upload', href: '/bulk-upload' },\n];\n\nfunction fileToBase64(file) {\n  return new Promise((resolve, reject) => {\n    const reader = new FileReader();\n    reader.onload = () => resolve(String(reader.result).split(',')[1]);\n    reader.onerror = reject;\n    reader.readAsDataURL(file);\n  });\n}\n\nfunction cleanRowsForInsert(rows) {\n  return rows\n    .filter((row) => row.row_status === 'valid')\n    .map((row) => {\n      const cleanRow = { ...row };\n      delete cleanRow.row_status;\n      delete cleanRow.errors;\n      return cleanRow;\n    });\n}\n\nfunction collectErrors(rows) {\n  return rows.flatMap((row) =>\n    (row.errors ?? []).map((error) => ({\n      id: row.id,\n      ...error,\n    })),\n  );\n}\n\nfunction ErrorTooltipContent({ errors }) {\n  return (\n    <div className=\"bulk-tooltip-errors\">\n      {(errors ?? []).map((error, index) => (\n        <div key={`${error.field}-${index}`}>{error.message}</div>\n      ))}\n    </div>\n  );\n}\n\nfunction BulkErrorBanner({ errors, expanded, onToggle, onSummaryClick }) {\n  if (errors.length === 0) return null;\n\n  return (\n    <div className=\"bulk-error-banner\">\n      <div className=\"bulk-error-summary\">\n        <button\n          type=\"button\"\n          className=\"bulk-error-summary-main\"\n          onClick={onSummaryClick}\n          aria-label=\"Scroll to first invalid row\"\n        >\n          <ExclamationCircleOutlined className=\"bulk-error-icon\" />\n          <span>{errors.length} validation error(s) found</span>\n        </button>\n        <Button type=\"link\" onClick={onToggle} aria-expanded={expanded}>\n          {expanded ? 'Hide Errors' : 'View Errors'}\n        </Button>\n      </div>\n      {expanded && (\n        <div className=\"bulk-error-list\" role=\"region\" aria-label=\"Validation error details\">\n          {errors.map((error, index) => (\n            <div key={`${error.id}-${error.field}-${index}`} className=\"bulk-error-line\">\n              <span className=\"bulk-row-chip\">Row {error.id}</span>\n              <span>{error.message}</span>\n            </div>\n          ))}\n        </div>\n      )}\n    </div>\n  );\n}\n\nfunction RowPreviewTable({ rows, view, onViewChange, onConfirm, onReset, saving, firstInvalidRowId, firstInvalidRowRef }) {\n  const invalidRows = rows.filter((row) => row.row_status === 'invalid');\n  const visibleRows = view === 'errors' ? invalidRows : rows;\n  const disableSave = invalidRows.length > 0 || saving;\n\n  return (\n    <>\n      <Row justify=\"space-between\" align=\"middle\" gutter={[16, 16]} className=\"bulk-table-toolbar\">\n        <Col>\n          <Space.Compact>\n            <Button type={view === 'all' ? 'primary' : 'default'} onClick={() => onViewChange('all')}>\n              All rows\n            </Button>\n            <Button type={view === 'errors' ? 'primary' : 'default'} onClick={() => onViewChange('errors')}>\n              Errors only\n            </Button>\n          </Space.Compact>\n        </Col>\n        <Col>\n          <Text type=\"secondary\">{rows.length} row(s)</Text>\n        </Col>\n      </Row>\n\n      <div className=\"bulk-table-wrap\">\n        <table className=\"bulk-preview-table\">\n          <thead>\n            <tr>\n              <th className=\"bulk-col-row\">Row</th>\n              <th className=\"bulk-col-flow\">Submodule</th>\n              <th className=\"bulk-col-description\">Description</th>\n              <th className=\"bulk-col-keyword\">Action</th>\n              <th className=\"bulk-col-target\">Key</th>\n              <th className=\"bulk-col-status\">Status</th>\n              <th className=\"bulk-col-error\">Error</th>\n            </tr>\n          </thead>\n          <tbody>\n            {visibleRows.map((row) => {\n              const rowErrors = row.errors ?? [];\n              const isInvalid = row.row_status === 'invalid';\n              return (\n                <tr\n                  key={`${row.id}-${row.step_order}`}\n                  ref={isInvalid && row.id === firstInvalidRowId ? firstInvalidRowRef : null}\n                  className={isInvalid ? 'bulk-row-invalid' : ''}\n                >\n                  <td>{row.id}</td>\n                  <td title={row.submodule}>{row.submodule}</td>\n                  <td title={row.description}>\n                    {row.description ? row.description : <span className=\"bulk-empty-text\">-empty-</span>}\n                  </td>\n                  <td><code className=\"bulk-code-chip\">{row.actions}</code></td>\n                  <td title={row.key}>{row.key}</td>\n                  <td>\n                    {isInvalid\n                      ? <Tag color=\"red\">Error</Tag>\n                      : <Tag color=\"green\">Valid</Tag>}\n                  </td>\n                  <td>\n                    {isInvalid ? (\n                      <Tooltip title={<ErrorTooltipContent errors={rowErrors} />} placement=\"left\">\n                        <button type=\"button\" className=\"bulk-error-info\" aria-label={`View ${rowErrors.length} error(s) for row ${row.id}`}>\n                          <InfoCircleOutlined />\n                          <Badge count={rowErrors.length} size=\"small\" />\n                        </button>\n                      </Tooltip>\n                    ) : (\n                      <span className=\"bulk-error-none\">-</span>\n                    )}\n                  </td>\n                </tr>\n              );\n            })}\n          </tbody>\n        </table>\n      </div>\n\n      <Space className=\"bulk-actions\">\n        <Button icon={<ReloadOutlined />} onClick={onReset}>Reset</Button>\n        <Button\n          type=\"primary\"\n          icon={<SaveOutlined />}\n          loading={saving}\n          disabled={disableSave}\n          onClick={onConfirm}\n        >\n          {invalidRows.length > 0 ? `Fix ${invalidRows.length} error(s) to proceed` : 'Save to database'}\n        </Button>\n      </Space>\n    </>\n  );\n}\n\nexport default function BulkUploadPage() {\n  const navigate = useNavigate();\n  const project = useMemo(() => getSelectedProject(), []);\n  const fileInputRef = useRef(null);\n  const firstInvalidRowRef = useRef(null);\n  const [modules, setModules] = useState([]);\n  const [selectedModule, setSelectedModule] = useState('');\n  const [status, setStatus] = useState('idle');\n  const [dragging, setDragging] = useState(false);\n  const [fileInfo, setFileInfo] = useState(null);\n  const [rows, setRows] = useState([]);\n  const [view, setView] = useState('all');\n  const [apiError, setApiError] = useState(null);\n  const [summary, setSummary] = useState(null);\n  const [errorsExpanded, setErrorsExpanded] = useState(false);\n\n  const moduleOptions = modules.map((item) => ({ value: item.modulename, label: item.modulename }));\n  const errors = collectErrors(rows);\n  const busy = status === 'encoding' || status === 'validating';\n  const canChooseFile = Boolean(selectedModule) && !busy;\n  const activeStep = STEP_INDEX[status] ?? 0;\n  const firstInvalidRowId = rows.find((row) => row.row_status === 'invalid')?.id;\n\n  const reset = useCallback(() => {\n    setSelectedModule('');\n    setStatus('idle');\n    setDragging(false);\n    setFileInfo(null);\n    setRows([]);\n    setView('all');\n    setApiError(null);\n    setSummary(null);\n    if (fileInputRef.current) fileInputRef.current.value = '';\n  }, []);\n\n  useEffect(() => {\n    async function loadModules() {\n      try {\n        const res = await getCTModules({ project: project?.name ?? '', activeOnly: true });\n        setModules(res?.items ?? []);\n      } catch (error) {\n        console.error(error);\n        message.error('Unable to load modules.');\n      }\n    }\n    loadModules();\n  }, [project?.name]);\n\n  const handleModuleChange = (value) => {\n    setSelectedModule(value ?? '');\n    setRows([]);\n    setSummary(null);\n    setApiError(null);\n    setFileInfo(null);\n    setErrorsExpanded(false);\n    setStatus(value ? 'module_set' : 'idle');\n  };\n\n  const validateFile = async (file) => {\n    if (!file || !canChooseFile) return;\n\n    const extension = file.name.split('.').pop()?.toLowerCase();\n    if (!['xlsx', 'csv'].includes(extension)) {\n      setStatus('module_set');\n      setApiError({ message: 'Invalid file type. Please upload an Excel .xlsx or CSV .csv file.' });\n      return;\n    }\n    if (file.size > MAX_FILE_SIZE) {\n      setStatus('module_set');\n      setApiError({ message: 'File must be 10 MB or smaller.' });\n      return;\n    }\n\n    setApiError(null);\n    setRows([]);\n    setSummary(null);\n    setFileInfo({ name: file.name, size: file.size });\n    setStatus('encoding');\n\n    try {\n      const fileBase64 = await fileToBase64(file);\n      setStatus('validating');\n      const data = await validateTestSteps({\n        filename: file.name,\n        project: project?.name ?? '',\n        module: selectedModule,\n        file_base64: fileBase64,\n        file_type: extension,\n      });\n      setRows(data?.rows ?? []);\n      setView('all');\n      setStatus('preview');\n    } catch (error) {\n      console.error(error);\n      setApiError(error.payload ?? { code: 'NETWORK_ERROR', message: error.message || 'Could not reach the server.' });\n      setStatus('error');\n    }\n  };\n\n  const handleTemplateDownload = async () => {\n    try {\n      const response = await fetch(TEMPLATE_BASE64_URL);\n      if (!response.ok) throw new Error(`Template file not found (${response.status})`);\n\n      const base64 = (await response.text()).trim();\n      const binary = atob(base64);\n      const bytes = new Uint8Array(binary.length);\n      for (let index = 0; index < binary.length; index += 1) {\n        bytes[index] = binary.charCodeAt(index);\n      }\n\n      const blob = new Blob([bytes], {\n        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n      });\n      const url = URL.createObjectURL(blob);\n      const link = document.createElement('a');\n      link.href = url;\n      link.download = TEMPLATE_FILENAME;\n      document.body.appendChild(link);\n      link.click();\n      link.remove();\n      URL.revokeObjectURL(url);\n      message.success('Sample template downloaded.');\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to download sample template.');\n    }\n  };\n\n  const confirmInsert = async () => {\n    setStatus('inserting');\n    setApiError(null);\n    try {\n      const data = await bulkInsertTestSteps({\n        project: project?.name ?? '',\n        module: selectedModule,\n        uploaded_by: localStorage.getItem('user_Email') ?? '',\n        rows: cleanRowsForInsert(rows),\n      });\n      setSummary(data);\n      setStatus('done');\n      message.success('Bulk upload saved. Redirecting to view test cases...');\n      window.setTimeout(() => navigate('/viewTestCase'), 900);\n    } catch (error) {\n      console.error(error);\n      setApiError(error.payload ?? { code: 'NETWORK_ERROR', message: error.message || 'Could not reach the server.' });\n      setStatus('preview');\n    }\n  };\n\n  const scrollToFirstInvalidRow = useCallback(() => {\n    firstInvalidRowRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n  }, []);\n\n  const dropzoneClass = [\n    'bulk-dropzone',\n    dragging ? 'bulk-dropzone-dragging' : '',\n    fileInfo ? 'bulk-dropzone-has-file' : '',\n    apiError && status !== 'preview' ? 'bulk-dropzone-error' : '',\n    !selectedModule ? 'bulk-dropzone-disabled' : '',\n  ].filter(Boolean).join(' ');\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col><AppBreadcrumb items={breadcrumbItems} /></Col>\n        {project?.name && (\n          <Col><Text strong>{project.name}</Text></Col>\n        )}\n      </Row>\n\n      <div className=\"zt-page zt-page-wide bulk-page\">\n        <div className=\"bulk-header\">\n          <Title level={3}>Bulk upload test cases</Title>\n          <Space direction=\"vertical\" size={4}>\n            <Text type=\"secondary\">{HEADERS_HINT}</Text>\n            <Text type=\"secondary\">Use the sample template for the required columns. Uploaded rows are saved as Active by default.</Text>\n          </Space>\n        </div>\n\n        <div className=\"bulk-stepbar\">\n          {['Select', 'Upload', 'Validate', 'Save'].map((label, index) => (\n            <span\n              key={label}\n              className={index < activeStep ? 'bulk-step-active' : ''}\n            >\n              {index + 1} {label}\n            </span>\n          ))}\n        </div>\n\n        <Card className=\"v1-card zt-fall\" title=\"1. Module selector\">\n          <Select\n            allowClear\n            showSearch\n            optionFilterProp=\"label\"\n            className=\"bulk-module-select\"\n            placeholder=\"Choose a module\"\n            options={moduleOptions}\n            value={selectedModule || undefined}\n            onChange={handleModuleChange}\n          />\n        </Card>\n\n        {selectedModule && (\n          <Card\n            className=\"v1-card zt-fall\"\n            title=\"2. File upload\"\n            extra={(\n              <Button\n                icon={<DownloadOutlined />}\n                onClick={handleTemplateDownload}\n              >\n                Download Sample Template\n              </Button>\n            )}\n          >\n            <Alert\n              type=\"info\"\n              showIcon\n              message=\"First time uploading?\"\n              description=\"Download the sample template, keep the column names unchanged, fill your test steps, and upload either .xlsx or .csv.\"\n              className=\"bulk-inline-alert\"\n            />\n            <button\n              type=\"button\"\n              className={dropzoneClass}\n              disabled={!canChooseFile}\n              onClick={() => fileInputRef.current?.click()}\n              onDragOver={(event) => {\n                event.preventDefault();\n                if (canChooseFile) setDragging(true);\n              }}\n              onDragLeave={() => setDragging(false)}\n              onDrop={(event) => {\n                event.preventDefault();\n                setDragging(false);\n                validateFile(event.dataTransfer.files?.[0]);\n              }}\n            >\n              <CloudUploadOutlined className=\"bulk-upload-icon\" />\n              {fileInfo ? (\n                <span className=\"bulk-file-chip\">\n                  {fileInfo.name} - {Math.ceil(fileInfo.size / 1024)} KB\n                </span>\n              ) : (\n                <span>Drag &amp; drop here, or click to browse</span>\n              )}\n            </button>\n            <input\n              ref={fileInputRef}\n              hidden\n              type=\"file\"\n              accept=\".xlsx,.csv\"\n              onChange={(event) => validateFile(event.target.files?.[0])}\n            />\n            {busy && <Progress percent={status === 'encoding' ? 45 : 82} showInfo={false} size=\"small\" />}\n            {apiError && status !== 'preview' && <Alert type=\"error\" showIcon message={apiError.message} className=\"bulk-inline-alert\" />}\n          </Card>\n        )}\n\n        {rows.length > 0 && (\n          <Card className=\"v1-card zt-fall\" title=\"3. Validation result\">\n            <BulkErrorBanner\n              errors={errors}\n              expanded={errorsExpanded}\n              onToggle={() => setErrorsExpanded((value) => !value)}\n              onSummaryClick={scrollToFirstInvalidRow}\n            />\n            {apiError && status === 'preview' && <Alert type=\"error\" showIcon message={apiError.message} className=\"bulk-inline-alert\" />}\n            <RowPreviewTable\n              rows={rows}\n              view={view}\n              onViewChange={setView}\n              onConfirm={confirmInsert}\n              onReset={reset}\n              saving={status === 'inserting'}\n              firstInvalidRowId={firstInvalidRowId}\n              firstInvalidRowRef={firstInvalidRowRef}\n            />\n          </Card>\n        )}\n\n        {summary && status === 'done' && (\n          <Card className=\"v1-card zt-fall\" title=\"4. Upload complete\">\n            <Row gutter={[16, 16]} className=\"bulk-metrics\">\n              <Col xs={24} md={8}><div><Text>Total</Text><strong>{rows.length}</strong></div></Col>\n              <Col xs={24} md={8}><div><Text>Inserted</Text><strong>{summary.inserted ?? 0}</strong></div></Col>\n              <Col xs={24} md={8}><div><Text>Failed</Text><strong>{summary.failed ?? 0}</strong></div></Col>\n            </Row>\n            <Alert\n              type=\"success\"\n              showIcon\n              icon={<CheckCircleOutlined />}\n              message={`${summary.inserted ?? 0} test cases saved to database - module: ${selectedModule}`}\n              className=\"bulk-inline-alert\"\n            />\n            <Button icon={<ReloadOutlined />} onClick={reset}>Upload another file</Button>\n          </Card>\n        )}\n      </div>\n    </main>\n  );\n}\n\n\n\n\n\n\n\n","export const zinnextActionOptions = [\n  // Navigation & Interactions\n  { value: 'navigate', label: 'Navigate' },\n  { value: 'fill', label: 'Fill' },\n  { value: 'click', label: 'Click' },\n  { value: 'select', label: 'Select' },\n  { value: 'press_key', label: 'Press Key' },\n  { value: 'type_and_select', label: 'Type and Select' },\n  { value: 'type_and_select_modal', label: 'Type and Select (Modal)' },\n  { value: 'upload_file', label: 'Upload File' },\n  { value: 'check_checkbox', label: 'Check Checkbox' },\n  { value: 'check_filter_checkbox', label: 'Check Filter Checkbox' },\n  { value: 'select_page_size', label: 'Select Page Size' },\n  { value: 'check_n_checkboxes', label: 'Check N Checkboxes' },\n\n  // Session & Tab Actions\n  { value: 'store_text', label: 'Store Text' },\n  { value: 'reset_session', label: 'Reset Session' },\n  { value: 'switch_to_new_tab', label: 'Switch To New Tab' },\n  { value: 'close_tab', label: 'Close Tab' },\n\n  // Assertions\n  { value: 'assert_visible', label: 'Assert Visible' },\n  { value: 'assert_hidden', label: 'Assert Hidden' },\n  { value: 'assert_text', label: 'Assert Text' },\n  { value: 'assert_url', label: 'Assert URL' },\n  { value: 'assert_body_contains', label: 'Assert Body Contains' },\n  { value: 'assert_button_disabled', label: 'Assert Button Disabled' },\n  { value: 'assert_field_error', label: 'Assert Field Error' },\n  { value: 'assert_field_accepted', label: 'Assert Field Accepted' },\n  { value: 'assert_children_disabled', label: 'Assert Children Disabled' },\n  { value: 'assert_children_visible', label: 'Assert Children Visible' },\n  { value: 'assert_element_count', label: 'Assert Element Count' },\n\n  // Toast Assertions\n  { value: 'assert_toast', label: 'Assert Toast' },\n  { value: 'assert_toast_success', label: 'Assert Toast Success' },\n  { value: 'assert_toast_error', label: 'Assert Toast Error' },\n\n  // Wait Actions\n  { value: 'wait_for_visible', label: 'Wait For Visible' },\n  { value: 'wait_for_hidden', label: 'Wait For Hidden' },\n  { value: 'wait_for_text', label: 'Wait For Text' },\n];","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AutoComplete, Button, Card, Col, Form, Input, Modal, Row, Select, Space, Typography, message } from 'antd';\nimport {\n  FileTextOutlined,\n  PlusOutlined,\n  ProfileOutlined,\n  TagsOutlined,\n} from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport AppCard from '../../components/cards/AppCard';\nimport { addTestFlow, addTestingOption, getTestFlows, getTestingOptions } from '../../services/testingApi';\nimport { zinnextActionOptions } from '../../services/dropdownValues/testPageValues';\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/test-cases' },\n];\n\nconst initialValues = {\n  tags: 'regression',\n  active: 1,\n};\n\nconst testingOptionTypes = {\n  module: {\n    dbName: 'Modules',\n    formField: 'module',\n    label: 'Module',\n  },\n};\n\nfunction toSelectOptions(items = []) {\n  return items.map((item) => ({\n    value: item,\n    label: item,\n  }));\n}\n\nfunction normalizeText(value = '') {\n  return String(value ?? '').trim();\n}\n\nfunction normalizeLowerText(value = '') {\n  return normalizeText(value).toLowerCase();\n}\n\nfunction getUniqueFlowOptions(rows = []) {\n  const flowMap = new Map();\n\n  rows.forEach((row) => {\n    const flow = normalizeText(row?.flow);\n    const key = flow.toLowerCase();\n\n    if (flow && !flowMap.has(key)) {\n      flowMap.set(key, flow);\n    }\n  });\n\n  return Array.from(flowMap.values()).map((flow) => ({\n    value: flow,\n    label: flow,\n  }));\n}\n\nfunction getNextStepOrder(rows = [], module, flow) {\n  const selectedModule = normalizeText(module).toLowerCase();\n  const selectedFlow = normalizeText(flow).toLowerCase();\n  const lastStepOrder = rows.reduce((maxStepOrder, row) => {\n    const rowModule = normalizeText(row?.module).toLowerCase();\n    const rowFlow = normalizeText(row?.flow).toLowerCase();\n\n    if (rowModule !== selectedModule || rowFlow !== selectedFlow) {\n      return maxStepOrder;\n    }\n\n    const stepOrder = Number(row?.step_order) || 0;\n    return Math.max(maxStepOrder, stepOrder);\n  }, 0);\n\n  return lastStepOrder + 1;\n}\n\nfunction SectionTitle({ icon, title }) {\n  return (\n    <Space size={10} align=\"center\">\n      <div className=\"v1-section-icon-box\">{icon}</div>\n      <Text strong className=\"v1-section-label\">{title}</Text>\n    </Space>\n  );\n}\n\nexport default function TestForm() {\n  const [form] = Form.useForm();\n  const [optionForm] = Form.useForm();\n  const [moduleItems, setModuleItems] = useState([]);\n  const [flowRows, setFlowRows] = useState([]);\n  const [flowOptions, setFlowOptions] = useState([]);\n  const [optionsLoading, setOptionsLoading] = useState(false);\n  const [flowsLoading, setFlowsLoading] = useState(false);\n  const [optionModal, setOptionModal] = useState({ open: false, typeKey: 'module' });\n  const [optionSaving, setOptionSaving] = useState(false);\n  const [stepOrderLoading, setStepOrderLoading] = useState(false);\n  const [submitting, setSubmitting] = useState(false);\n  const navigate = useNavigate();\n\n  const selectedOptionType = testingOptionTypes[optionModal.typeKey];\n  const moduleOptions = useMemo(() => toSelectOptions(moduleItems), [moduleItems]);\n  const selectedModule = Form.useWatch('module', form);\n  const selectedFlow = Form.useWatch('flow', form);\n  const hasSelectedModule = Boolean(normalizeText(selectedModule));\n  const hasSelectedFlow = Boolean(normalizeText(selectedFlow));\n  const areFlowFieldsDisabled = !hasSelectedModule;\n  const areDetailsDisabled = !hasSelectedModule || !hasSelectedFlow;\n\n  const setItemsByType = (typeKey, items = []) => {\n    if (typeKey === 'module') {\n      setModuleItems(items);\n    }\n  };\n\n  const loadTestingOptions = async () => {\n    setOptionsLoading(true);\n\n    try {\n      const modulesResponse = await getTestingOptions(testingOptionTypes.module.dbName);\n\n      setModuleItems(modulesResponse?.items ?? []);\n    } catch (error) {\n      console.error('Unable to load testing options:', error);\n      message.error('Unable to load testing options.');\n    } finally {\n      setOptionsLoading(false);\n    }\n  };\n\n  const loadModuleFlows = useCallback(async (module) => {\n    const normalizedModule = normalizeText(module);\n\n    setFlowRows([]);\n    setFlowOptions([]);\n    form.setFieldsValue({ step_order: undefined });\n\n    if (!normalizedModule) return;\n\n    setFlowsLoading(true);\n\n    try {\n      const response = await getTestFlows({ limit: 10000, offset: 0, module: normalizedModule });\n      const rows = Array.isArray(response?.items) ? response.items : [];\n\n      setFlowRows(rows);\n      setFlowOptions(getUniqueFlowOptions(rows));\n    } catch (error) {\n      console.error('Unable to load flows:', error);\n      message.error('Unable to load flows.');\n    } finally {\n      setFlowsLoading(false);\n    }\n  }, [form]);\n\n  const loadNextStepOrder = useCallback(async (module, flow, rows) => {\n    const normalizedModule = normalizeText(module);\n    const normalizedFlow = normalizeText(flow);\n\n    if (!normalizedModule || !normalizedFlow) {\n      form.setFieldsValue({ step_order: undefined });\n      return;\n    }\n\n    setStepOrderLoading(true);\n\n    try {\n      form.setFieldsValue({ step_order: getNextStepOrder(rows, normalizedModule, normalizedFlow) });\n    } catch (error) {\n      console.error('Unable to load step order:', error);\n      message.error('Unable to load step order.');\n    } finally {\n      setStepOrderLoading(false);\n    }\n  }, [form]);\n\n  useEffect(() => {\n    Promise.resolve().then(loadTestingOptions);\n  }, []);\n\n  useEffect(() => {\n    Promise.resolve().then(() => loadModuleFlows(selectedModule));\n  }, [loadModuleFlows, selectedModule]);\n\n  useEffect(() => {\n    Promise.resolve().then(() => loadNextStepOrder(selectedModule, selectedFlow, flowRows));\n  }, [flowRows, loadNextStepOrder, selectedFlow, selectedModule]);\n\n  const onFinish = async (values) => {\n    const payload = {\n      module: normalizeText(values.module),\n      flow: normalizeText(values.flow),\n      step_order: Number(values.step_order),\n      description: normalizeText(values.description),\n      keyword: normalizeLowerText(values.keyword),\n      target: normalizeText(values.target),\n      value: normalizeText(values.value),\n      expected: normalizeText(values.expected),\n      tags: values.tags ? normalizeText(values.tags) : initialValues.tags,\n      active: Number(values.active),\n    };\n\n    setSubmitting(true);\n    try {\n      await addTestFlow(payload);\n      message.success('Test case details saved successfully.');\n      form.resetFields();\n      setFlowRows([]);\n      setFlowOptions([]);\n    } catch (error) {\n      console.error('Unable to save test case:', error);\n      message.error('Unable to save test case.');\n    } finally {\n      setSubmitting(false);\n    }\n  };\n\n  const removeExtraSpaces = (fieldName, value) => {\n    form.setFieldsValue({\n      [fieldName]: normalizeText(value),\n    });\n  };\n\n  const handleModuleChange = (value) => {\n    form.setFieldsValue({\n      module: normalizeText(value),\n      flow: undefined,\n      step_order: undefined,\n      keyword: undefined,\n      description: undefined,\n      target: undefined,\n      tags: initialValues.tags,\n      value: undefined,\n      expected: undefined,\n    });\n  };\n\n  const handleFlowChange = (value) => {\n    form.setFieldsValue({\n      flow: normalizeText(value),\n      step_order: undefined,\n    });\n  };\n\n  const openOptionModal = (typeKey) => {\n    const optionType = testingOptionTypes[typeKey];\n\n    setOptionModal({ open: true, typeKey });\n    optionForm.setFieldsValue({\n      name: '',\n      type: optionType.label,\n    });\n  };\n\n  const closeOptionModal = () => {\n    setOptionModal((current) => ({ ...current, open: false }));\n    optionForm.resetFields();\n  };\n\n  const saveTestingOption = async () => {\n    try {\n      const values = await optionForm.validateFields();\n      const name = normalizeText(values.name);\n      const response = await addTestingOption({\n        name,\n        type: selectedOptionType.dbName,\n      });\n\n      setItemsByType(optionModal.typeKey, response?.items ?? []);\n      form.setFieldsValue({ [selectedOptionType.formField]: name });\n      message.success(`${selectedOptionType.label} added successfully.`);\n      closeOptionModal();\n    } catch (error) {\n      if (error?.errorFields) return;\n\n      console.error('Unable to save testing option:', error);\n      message.error(`Unable to add ${selectedOptionType.label.toLowerCase()}.`);\n    } finally {\n      setOptionSaving(false);\n    }\n  };\n\n  const submitTestingOption = () => {\n    setOptionSaving(true);\n    saveTestingOption();\n  };\n\n  return (\n    <main className=\"jobs-list-page\">\n<Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n  <Col>\n    <AppBreadcrumb items={breadcrumbItems} />\n  </Col>\n\n  <Col>\n    <Button type=\"link\" onClick={() => navigate('/zinnext-home')}>\n      View Table\n    </Button>\n  </Col>\n</Row>\n\n      <div className=\"v1-page\">\n        <div className=\"v1-page-inner\">\n          <div className=\"v1-page-header\">\n            <Space align=\"center\" size={10}>\n              <ProfileOutlined className=\"v1-outer-icon\" />\n              <div>\n                <Text strong style={{ fontSize: 16 }}>Add Test Case</Text>\n              </div>\n            </Space>\n          </div>\n\n          <AppCard>\n            <Form\n              form={form}\n              className=\"v1-form\"\n              layout=\"vertical\"\n              colon={false}\n              requiredMark={(label, { required }) => (\n                <>\n                  {label}\n                  {required && <span className=\"v1-required-mark\"> *</span>}\n                </>\n              )}\n              initialValues={initialValues}\n              onFinish={onFinish}\n              autoComplete=\"off\"\n            >\n              <Card\n                className=\"v1-card\"\n                title={<SectionTitle icon={<FileTextOutlined />} title=\"Test Case Details\" />}\n                extra={\n                  <Text type=\"secondary\" className=\"v1-card-subtitle\">\n                    Module, flow, step order and execution data\n                  </Text>\n                }\n              >\n                <Row gutter={[24, 0]}>\n                  <Col xs={24} md={12}>\n                    <Space.Compact style={{ width: '100%' }}>\n                      <Form.Item\n                        label=\"Module\"\n                        name=\"module\"\n                        style={{ flex: 1 }}\n                      >\n                        <Select\n                          allowClear\n                          showSearch\n                          loading={optionsLoading}\n                          optionFilterProp=\"label\"\n                          placeholder=\"Select module\"\n                          options={moduleOptions}\n                          onChange={handleModuleChange}\n                        />\n                      </Form.Item>\n                      <Button\n                        aria-label=\"Add module\"\n                        icon={<PlusOutlined />}\n                        style={{ marginTop: 30 }}\n                        onClick={() => openOptionModal('module')}\n                      />\n                    </Space.Compact>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Flow\"\n                      name=\"flow\"\n                    >\n                      <AutoComplete\n                        maxLength={100}\n                        allowClear\n                        disabled={areFlowFieldsDisabled}\n                        options={flowOptions}\n                        placeholder={flowsLoading ? 'Loading flows' : 'Enter flow'}\n                        onChange={handleFlowChange}\n                        filterOption={(inputValue, option) =>\n                          option?.value?.toLowerCase().includes(inputValue.toLowerCase())\n                        }\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Step Order\"\n                      name=\"step_order\"\n                      validateTrigger={['onBlur', 'onChange']}\n                    >\n                      <Input\n                        maxLength={10}\n                        disabled\n                        placeholder={stepOrderLoading ? 'Loading step order' : 'Step order'}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Action\"\n                      name=\"keyword\"\n                    >\n                      <Select\n                        allowClear\n                        showSearch\n                        disabled={areDetailsDisabled}\n                        optionFilterProp=\"label\"\n                        placeholder=\"Select action\"\n                        options={zinnextActionOptions}\n                        onChange={(value) => form.setFieldsValue({ keyword: normalizeLowerText(value) })}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24}>\n                    <Form.Item\n                      label=\"Description\"\n                      name=\"description\"\n                    >\n                      <Input.TextArea\n                        rows={3}\n                        maxLength={255}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter description\"\n                        showCount\n                        onBlur={(e) => removeExtraSpaces('description', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Key\"\n                      name=\"target\"\n                    >\n                      <Input\n                        maxLength={255}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter target\"\n                        onBlur={(e) => removeExtraSpaces('target', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Tags\"\n                      name=\"tags\"\n                    >\n                      <Input\n                        maxLength={200}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter tags\"\n                        prefix={<TagsOutlined className=\"v1-input-icon\" />}\n                        onBlur={(e) => removeExtraSpaces('tags', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Value\"\n                      name=\"value\"\n                    >\n                      <Input.TextArea\n                        rows={4}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter value\"\n                        onBlur={(e) => removeExtraSpaces('value', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Expected\"\n                      name=\"expected\"\n                    >\n                      <Input.TextArea\n                        rows={4}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter expected result\"\n                        onBlur={(e) => removeExtraSpaces('expected', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* <Col xs={24} md={12}>\n                    <Form.Item label=\"Active\" name=\"active\">\n                      <Select\n                        suffixIcon={<CheckCircleOutlined />}\n                        options={[\n                          { value: 1, label: 'Active' },\n                          { value: 0, label: 'Inactive' },\n                        ]}\n                      />\n                    </Form.Item>\n                  </Col> */}\n                </Row>\n              </Card>\n                <div className=\"v1-form-actions\">\n                    <Form.Item>\n                        <Space>\n                        <Button type=\"primary\" htmlType=\"submit\" loading={submitting} disabled={areDetailsDisabled}>\n                            Submit\n                        </Button>\n                        <Button onClick={() => {\n                          form.resetFields();\n                          setFlowRows([]);\n                          setFlowOptions([]);\n                        }}\n                        >\n                            Reset\n                        </Button>\n                        </Space>\n                    </Form.Item>\n                </div>\n            </Form>\n          </AppCard>\n\n          <Modal\n            title={`Add ${selectedOptionType.label}`}\n            open={optionModal.open}\n            confirmLoading={optionSaving}\n            okText=\"Add\"\n            onCancel={closeOptionModal}\n            onOk={submitTestingOption}\n            destroyOnHidden\n          >\n            <Form\n              form={optionForm}\n              layout=\"vertical\"\n              colon={false}\n              className=\"v1-form\"\n              requiredMark={(label, { required }) => (\n                <>\n                  {label}\n                  {required && <span className=\"v1-required-mark\"> *</span>}\n                </>\n              )}\n            >\n              <Form.Item\n                label=\"Name\"\n                name=\"name\"\n              >\n                <Input\n                  maxLength={100}\n                  placeholder={`Enter ${selectedOptionType.label.toLowerCase()} name`}\n                  onBlur={(e) => {\n                    optionForm.setFieldsValue({\n                      name: normalizeText(e.target.value),\n                    });\n                  }}\n                />\n              </Form.Item>\n\n              <Form.Item label=\"Type\" name=\"type\">\n                <Input disabled />\n              </Form.Item>\n            </Form>\n          </Modal>\n        </div>\n      </div>\n    </main>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n  Button,\n  Card,\n  Col,\n  Form,\n  Input,\n  Row,\n  Select,\n  Space,\n  Switch,\n  Tag,\n  Typography,\n  message,\n} from 'antd';\nimport {\n  FileTextOutlined,\n  ProjectOutlined,\n  TableOutlined,\n} from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport ParamListView from '../../components/ParamListView';\nimport { addCTFlow, getActionFieldRules, getCTFlow, getCTFlows, getCTModules, getCTNextStep, getCTSubmodules, updateCTFlow } from '../../services/testingApi';\nimport { getSelectedProject } from '../../services/authApi';\nimport { zinnextActionOptions } from '../../services/dropdownValues/testPageValues';\n\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/addTestCase' },\n];\n\nfunction normalizeText(value = '') {\n  return String(value ?? '').trim();\n}\n\nfunction toOptions(items = [], key) {\n  return items.map((item) => ({ value: item.id, label: item[key] }));\n}\n\nconst flowFields = [\n  { label: 'Step', value: 'step_order', width: 70 },\n  { label: 'Action', value: 'actions', width: 140 },\n  { label: 'Key', value: 'key', width: 160, ellipsis: true },\n  { label: 'Value', value: 'value', ellipsis: true },\n  { label: 'Description', value: 'description', ellipsis: true },\n  {\n    label: 'Scenario',\n    value: 'scenario',\n    width: 110,\n    render: (v) =>\n      v === 1 ? <Tag color=\"green\">Positive</Tag> : <Tag color=\"red\">Negative</Tag>,\n  },\n];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CHANGE 1 — Action-based field validation matrix\n// true  = field is MANDATORY for this action\n// false = field is NOT needed (will be disabled + placeholder updated)\n// ─────────────────────────────────────────────────────────────────────────────\nconst EMPTY_FIELD_RULES = { key: false, value: false, expected: false };\n\n// Returns the rules for the selected action.\n// If no action is selected yet, nothing is mandatory and nothing is disabled.\nfunction getFieldRules(actionFieldRules, action) {\n  if (!action) return EMPTY_FIELD_RULES;\n  return actionFieldRules[action] ?? EMPTY_FIELD_RULES;\n}\n\nfunction clearFieldErrors(form, fieldNames) {\n  form.setFields(fieldNames.map((name) => ({ name, errors: [] })));\n}\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport default function ZinnextTestForm() {\n  const [form] = Form.useForm();\n  const navigate = useNavigate();\n  const [searchParams] = useSearchParams();\n  const editId = searchParams.get('edit');\n  const isEditing = Boolean(editId);\n\n  const project = useMemo(() => getSelectedProject(), []);\n\n  const [modules, setModules] = useState([]);\n  const [submodules, setSubmodules] = useState([]);\n  const [flowRows, setFlowRows] = useState([]);\n  const [actionOptions, setActionOptions] = useState(zinnextActionOptions);\n  const [actionFieldRules, setActionFieldRules] = useState({});\n\n  const [modulesLoading, setModulesLoading] = useState(false);\n  const [submodulesLoading, setSubmodulesLoading] = useState(false);\n  const [flowsLoading, setFlowsLoading] = useState(false);\n  const [submitting, setSubmitting] = useState(false);\n  const [editLoading, setEditLoading] = useState(false);\n\n  const selectedModule = Form.useWatch('module', form);\n  const selectedSubmodule = Form.useWatch('submodule', form);\n  const selectedAction = Form.useWatch('actions', form);\n\n  const hasModule = Boolean(selectedModule);\n  const hasSubmodule = Boolean(selectedSubmodule);\n\n  // ─────────────────────────────────────────────────────────────────────────\n  // CHANGE 2 — Derive live field rules from the currently selected action.\n  // This automatically updates whenever the user picks a different action.\n  // ─────────────────────────────────────────────────────────────────────────\n  const fieldRules = useMemo(() => getFieldRules(actionFieldRules, selectedAction), [actionFieldRules, selectedAction]);\n  // ─────────────────────────────────────────────────────────────────────────\n\n  const moduleOptions = useMemo(() => toOptions(modules, 'modulename'), [modules]);\n  const submoduleOptions = useMemo(() => toOptions(submodules, 'submodulename'), [submodules]);\n  const selectedModuleName = useMemo(\n    () => modules.find((item) => item.id === selectedModule)?.modulename ?? '',\n    [modules, selectedModule],\n  );\n  const selectedSubmoduleName = useMemo(\n    () => submodules.find((item) => item.id === selectedSubmodule)?.submodulename ?? '',\n    [selectedSubmodule, submodules],\n  );\n\n  // ---- loaders ----\n  const loadActionFieldRules = useCallback(async () => {\n    try {\n      const res = await getActionFieldRules();\n      if (Array.isArray(res?.options) && res.options.length > 0) {\n        setActionOptions(res.options);\n      }\n      if (res?.rules && typeof res.rules === 'object') {\n        setActionFieldRules(res.rules);\n      }\n    } catch (error) {\n      console.error('Unable to load action field rules:', error);\n      message.error('Unable to load action validation rules.');\n    }\n  }, []);\n\n  const loadModules = useCallback(async (projectName) => {\n    if (!projectName) {\n      setModules([]);\n      return;\n    }\n    setModulesLoading(true);\n    try {\n      const res = await getCTModules({ project: projectName, activeOnly: true });\n      setModules(res?.items ?? []);\n    } catch (error) {\n      console.error('Unable to load modules:', error);\n      message.error('Unable to load modules.');\n    } finally {\n      setModulesLoading(false);\n    }\n  }, []);\n\n  const loadSubmodules = useCallback(async (projectName, moduleName) => {\n    if (!projectName || !moduleName) {\n      setSubmodules([]);\n      return;\n    }\n    setSubmodulesLoading(true);\n    try {\n      const res = await getCTSubmodules({ project: projectName, module: moduleName, activeOnly: true });\n      setSubmodules(res?.items ?? []);\n    } catch (error) {\n      console.error('Unable to load submodules:', error);\n      message.error('Unable to load submodules.');\n    } finally {\n      setSubmodulesLoading(false);\n    }\n  }, []);\n\n  const loadFlowsAndStep = useCallback(async (productId, moduleId, submoduleId, actions = '') => {\n    if (!productId || !moduleId || !submoduleId) {\n      setFlowRows([]);\n      form.setFieldsValue({ step_order: undefined });\n      return;\n    }\n    setFlowsLoading(true);\n    try {\n      const [flowsRes, stepRes] = await Promise.all([\n        getCTFlows({\n          product_parent_ID: productId,\n          module_parent_ID: moduleId,\n          submodule_parent_ID: submoduleId,\n          actions,\n          limit: 1000,\n        }),\n        getCTNextStep({ product_parent_ID: productId, module_parent_ID: moduleId, submodule_parent_ID: submoduleId }),\n      ]);\n      setFlowRows(flowsRes?.items ?? []);\n      form.setFieldsValue({ step_order: stepRes?.step_order ?? 1 });\n    } catch (error) {\n      console.error('Unable to load flows:', error);\n      message.error('Unable to load flows.');\n    } finally {\n      setFlowsLoading(false);\n    }\n  }, [form]);\n\n  const loadActionFlows = useCallback(async (actions = '') => {\n    if (!project?.id || !selectedModule || !selectedSubmodule) return;\n\n    setFlowsLoading(true);\n    try {\n      const flowsRes = await getCTFlows({\n        product_parent_ID: project.id,\n        module_parent_ID: selectedModule,\n        submodule_parent_ID: selectedSubmodule,\n        actions,\n        limit: 1000,\n      });\n      setFlowRows(flowsRes?.items ?? []);\n    } catch (error) {\n      console.error('Unable to load action flows:', error);\n      message.error('Unable to load action steps.');\n    } finally {\n      setFlowsLoading(false);\n    }\n  }, [project?.id, selectedModule, selectedSubmodule]);\n\n  const loadEditFlow = useCallback(async () => {\n    if (!editId || !project?.name) return;\n\n    setEditLoading(true);\n    try {\n      const flow = await getCTFlow(editId);\n      await loadSubmodules(project.name, flow.module);\n      const flowsRes = await getCTFlows({\n        product_parent_ID: flow.product_parent_ID,\n        module_parent_ID: flow.module_parent_ID,\n        submodule_parent_ID: flow.submodule_parent_ID,\n        limit: 1000,\n      });\n      setFlowRows(flowsRes?.items ?? []);\n      form.setFieldsValue({\n        module: flow.module_parent_ID,\n        submodule: flow.submodule_parent_ID,\n        step_order: flow.step_order,\n        actions: flow.actions,\n        key: flow.key,\n        value: flow.value,\n        expected: flow.expected,\n        description: flow.description,\n        scenario: flow.scenario === 1,\n        active: Number(flow.active) !== 0,\n      });\n    } catch (error) {\n      console.error('Unable to load test flow:', error);\n      message.error('Unable to load test flow for edit.');\n      navigate('/viewTestCase');\n    } finally {\n      setEditLoading(false);\n    }\n  }, [editId, form, loadSubmodules, navigate, project?.name]);\n\n  useEffect(() => {\n    if (!project) {\n      navigate('/select-project', { replace: true });\n      return;\n    }\n    Promise.resolve().then(async () => {\n      await loadActionFieldRules();\n      await loadModules(project.name);\n      if (editId) await loadEditFlow();\n    });\n  }, [project, navigate, loadActionFieldRules, loadModules, editId, loadEditFlow]);\n\n  // ---- change handlers ----\n  const handleModuleChange = (value) => {\n    const moduleName = modules.find((item) => item.id === value)?.modulename ?? '';\n    form.setFieldsValue({\n      module: value,\n      submodule: undefined,\n      step_order: undefined,\n      actions: undefined,\n      key: undefined,\n      value: undefined,\n      expected: undefined,\n    });\n    clearFieldErrors(form, ['actions', 'key', 'value', 'expected']);\n    setSubmodules([]);\n    setFlowRows([]);\n    loadSubmodules(project?.name, moduleName);\n  };\n\n  const handleSubmoduleChange = (value) => {\n    form.setFieldsValue({ submodule: value, actions: undefined, key: undefined, value: undefined, expected: undefined });\n    clearFieldErrors(form, ['actions', 'key', 'value', 'expected']);\n    loadFlowsAndStep(project?.id, selectedModule, value);\n  };\n\n  // ─────────────────────────────────────────────────────────────────────────\n  // CHANGE 3 — When action changes, clear fields that are NOT needed for the\n  // newly selected action so stale data is never saved to the DB.\n  // ─────────────────────────────────────────────────────────────────────────\n  const handleActionChange = (value) => {\n    const rules = getFieldRules(actionFieldRules, value);\n    form.setFieldsValue({\n      actions: value,\n      key:      rules.key      ? form.getFieldValue('key')      : undefined,\n      value:    rules.value    ? form.getFieldValue('value')    : undefined,\n      expected: rules.expected ? form.getFieldValue('expected') : undefined,\n    });\n    clearFieldErrors(form, ['key', 'value', 'expected']);\n    loadActionFlows(value || '');\n  };\n  // ─────────────────────────────────────────────────────────────────────────\n\n  // ---- save & add ----\n  const onSaveAndAdd = async (values) => {\n    const payload = {\n      product_parent_ID: Number(project?.id),\n      module_parent_ID: Number(values.module),\n      submodule_parent_ID: Number(values.submodule),\n      description: normalizeText(values.description),\n      actions: normalizeText(values.actions),\n      key: normalizeText(values.key),\n      value: normalizeText(values.value),\n      expected: normalizeText(values.expected),\n      scenario: values.scenario ? 1 : 0,\n      active: values.active ? 1 : 0,\n    };\n\n    setSubmitting(true);\n    try {\n      if (isEditing) {\n        await updateCTFlow(editId, {\n          ...payload,\n          step_order: Number(values.step_order),\n        });\n        message.success('Test case updated successfully.');\n        navigate('/viewTestCase');\n        return;\n      }\n\n      await addCTFlow(payload);\n      message.success(`Step saved (#${values.step_order}).`);\n      form.setFieldsValue({\n        actions: undefined,\n        key: undefined,\n        value: undefined,\n        expected: undefined,\n        description: undefined,\n      });\n      await loadFlowsAndStep(payload.product_parent_ID, payload.module_parent_ID, payload.submodule_parent_ID);\n    } catch (error) {\n      console.error('Unable to save test case:', error);\n      message.error(isEditing ? 'Unable to update test case.' : 'Unable to save step.');\n    } finally {\n      setSubmitting(false);\n    }\n  };\n\n  const clearStepFields = () => {\n    if (isEditing) {\n      navigate('/viewTestCase');\n      return;\n    }\n    form.resetFields();\n    setSubmodules([]);\n    setFlowRows([]);\n    setSubmodulesLoading(false);\n    setFlowsLoading(false);\n  };\n\n  if (!project) return null;\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col>\n          <AppBreadcrumb items={breadcrumbItems} />\n        </Col>\n        <Col>\n          <Space size={6} className=\"zt-section-title\">\n            <ProjectOutlined />\n            <Text strong>{project.name}</Text>\n          </Space>\n        </Col>\n      </Row>\n\n      <div className=\"zt-page\">\n        <Form\n          form={form}\n          layout=\"vertical\"\n          colon={false}\n          className=\"v1-form\"\n          initialValues={{ scenario: true, active: true }}\n          onFinish={onSaveAndAdd}\n          autoComplete=\"off\"\n          disabled={editLoading}\n        >\n          {/* ---------- CARD 1: Module / Submodule / Scenario ---------- */}\n          <Card\n            className=\"v1-card zt-fall\"\n            title={(\n              <Space size={8} className=\"zt-section-title\">\n                <span className=\"zt-step-tag\">1</span>\n                <span>Module &amp; Submodule</span>\n              </Space>\n            )}\n          >\n            <Row gutter={[24, 0]} align=\"bottom\">\n              <Col xs={24} md={6}>\n                <Form.Item label=\"Module\" name=\"module\">\n                  <Select\n                    allowClear\n                    showSearch\n                    optionFilterProp=\"label\"\n                    loading={modulesLoading}\n                    placeholder=\"Select module\"\n                    options={moduleOptions}\n                    onChange={handleModuleChange}\n                  />\n                </Form.Item>\n              </Col>\n              <Col xs={24} md={6}>\n                <Form.Item label=\"Submodule\" name=\"submodule\">\n                  <Select\n                    allowClear\n                    showSearch\n                    optionFilterProp=\"label\"\n                    disabled={!hasModule}\n                    loading={submodulesLoading}\n                    placeholder={hasModule ? 'Select submodule' : 'Select module first'}\n                    options={submoduleOptions}\n                    onChange={handleSubmoduleChange}\n                  />\n                </Form.Item>\n              </Col>\n              <Col xs={24} md={6}>\n                <Form.Item label=\"Scenario\" name=\"scenario\" valuePropName=\"checked\">\n                  <Switch\n                    disabled={!hasSubmodule}\n                    checkedChildren=\"Positive\"\n                    unCheckedChildren=\"Negative\"\n                  />\n                </Form.Item>\n              </Col>\n              <Col xs={24} md={6}>\n                {/* Active toggle — no disabled, always editable, defaults ON */}\n                <Form.Item label=\"Active\" name=\"active\" valuePropName=\"checked\">\n                  <Switch\n                    checkedChildren=\"Active\"\n                    unCheckedChildren=\"Inactive\"\n                  />\n                </Form.Item>\n              </Col>\n            </Row>\n          </Card>\n\n          {/* ---------- CARD 2: Step fields ---------- */}\n          {hasSubmodule && (\n            <Card\n              key={`${selectedModule}-${selectedSubmodule}`}\n              className=\"v1-card zt-fall\"\n              title={(\n                <Space size={8} className=\"zt-section-title\">\n                  <span className=\"zt-step-tag\">2</span>\n                  <FileTextOutlined />\n                  <span>Step Details</span>\n                </Space>\n              )}\n              extra={<Text type=\"secondary\">{selectedModuleName} / {selectedSubmoduleName}</Text>}\n            >\n              <Row gutter={[24, 0]}>\n                <Col xs={24} md={6}>\n                  <Form.Item label=\"Step Order\" name=\"step_order\">\n                    <Input disabled placeholder={flowsLoading ? 'Loading…' : 'Auto'} />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={18}>\n                  <Form.Item\n                    label=\"Action\"\n                    name=\"actions\"\n                    rules={[{ required: true, message: 'Mandatory Field' }]}\n                  >\n                    <Select\n                      allowClear\n                      showSearch\n                      optionFilterProp=\"label\"\n                      placeholder=\"Select action\"\n                      options={actionOptions}\n                      onChange={handleActionChange}\n                    />\n                  </Form.Item>\n                </Col>\n\n                {/* ───────────────────────────────────────────────────────────\n                    CHANGE 4 — Key, Value, Expected now have dynamic rules:\n                      • required   → red * label + blocks save if empty\n                      • !required  → disabled input + \"Not needed\" placeholder\n                    ─────────────────────────────────────────────────────────── */}\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"Key\"\n                    name=\"key\"\n                    rules={[\n                      {\n                        required: fieldRules.key,\n                        message: 'Key is required for this action',\n                      },\n                    ]}\n                  >\n                    <Input\n                      maxLength={255}\n                      disabled={selectedAction && !fieldRules.key}\n                      placeholder={\n                        !selectedAction\n                          ? 'Select an action first'\n                          : fieldRules.key\n                          ? 'Required — Enter selector / locator'\n                          : 'Not needed for this action'\n                      }\n                    />\n                  </Form.Item>\n                </Col>\n\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"Value\"\n                    name=\"value\"\n                    rules={[\n                      {\n                        required: fieldRules.value,\n                        message: 'Value is required for this action',\n                      },\n                    ]}\n                  >\n                    <Input.TextArea\n                      rows={1}\n                      autoSize={{ minRows: 1, maxRows: 4 }}\n                      disabled={selectedAction && !fieldRules.value}\n                      placeholder={\n                        !selectedAction\n                          ? 'Select an action first'\n                          : fieldRules.value\n                          ? 'Required — Enter value'\n                          : 'Not needed for this action'\n                      }\n                    />\n                  </Form.Item>\n                </Col>\n\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"Expected\"\n                    name=\"expected\"\n                    rules={[\n                      {\n                        required: fieldRules.expected,\n                        message: 'Expected result is required for this action',\n                      },\n                    ]}\n                  >\n                    <Input.TextArea\n                      rows={2}\n                      disabled={selectedAction && !fieldRules.expected}\n                      placeholder={\n                        !selectedAction\n                          ? 'Select an action first'\n                          : fieldRules.expected\n                          ? 'Required — Enter expected result'\n                          : 'Not needed for this action'\n                      }\n                    />\n                  </Form.Item>\n                </Col>\n                {/* ─────────────────────────────────────────────────────────── */}\n\n                <Col xs={24} md={12}>\n                  <Form.Item label=\"Description\" name=\"description\">\n                    <Input.TextArea rows={2} maxLength={255} showCount placeholder=\"Enter description\" />\n                  </Form.Item>\n                </Col>\n              </Row>\n\n              <Space className=\"zt-actions\">\n                <Button onClick={clearStepFields}>Cancel</Button>\n                <Button type=\"primary\" htmlType=\"submit\" loading={submitting || editLoading}>\n                  {isEditing ? 'Update Test Case' : 'Save & Continue'}\n                </Button>\n              </Space>\n            </Card>\n          )}\n\n          {/* ---------- Added steps table ---------- */}\n          {hasSubmodule && (\n            <Card\n              className=\"v1-card zt-fall\"\n              title={(\n                <Space size={6} className=\"zt-section-title\">\n                  <TableOutlined />\n                  <span>Added Steps</span>\n                </Space>\n              )}\n              extra={<Tag>{selectedAction ? `${flowRows.length} ${selectedAction} step(s)` : `${flowRows.length} step(s)`}</Tag>}\n            >\n              <ParamListView\n                listName=\"Added Steps\"\n                loading={flowsLoading}\n                fields={flowFields}\n                dataSource={flowRows}\n                current={1}\n                pageSize={Math.max(flowRows.length, 1)}\n                total={flowRows.length}\n                rowSelection={false}\n                className=\"zt-list-plain zt-list-static\"\n              />\n            </Card>\n          )}\n        </Form>\n      </div>\n    </main>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n  Button,\n  Card,\n  Col,\n  Input,\n  Modal,\n  Row,\n  Space,\n  Switch,\n  Typography,\n  message,\n} from 'antd';\nimport { AppstoreOutlined, PlusOutlined, ProjectOutlined } from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport ParamListView from '../../components/ParamListView';\nimport { addCTModule, getCTModules, getCTSubmodules, setCTModuleStatus } from '../../services/testingApi';\nimport { getSelectedProject } from '../../services/authApi';\n\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/addTestCase' },\n  { label: 'Manage Modules', href: '/manageModules' },\n];\n\nexport default function ManageModules() {\n  const navigate = useNavigate();\n  const project = useMemo(() => getSelectedProject(), []);\n\n  const [modules, setModules] = useState([]);\n  const [counts, setCounts] = useState({});\n  const [modulesLoading, setModulesLoading] = useState(false);\n  const [addOpen, setAddOpen] = useState(false);\n  const [moduleName, setModuleName] = useState('');\n  const [saving, setSaving] = useState(false);\n  const [listPage, setListPage] = useState(1);\n  const [listPageSize, setListPageSize] = useState(10);\n\n  const loadModules = useCallback(async (projectName) => {\n    if (!projectName) {\n      setModules([]);\n      return;\n    }\n    setModulesLoading(true);\n    try {\n      const [modulesRes, submodulesRes] = await Promise.all([\n        getCTModules({ project: projectName }),\n        getCTSubmodules({ project: projectName }),\n      ]);\n      setModules(modulesRes?.items ?? []);\n\n      // count submodules per module name\n      const countMap = {};\n      (submodulesRes?.items ?? []).forEach((sub) => {\n        const key = sub.modulename;\n        countMap[key] = (countMap[key] ?? 0) + 1;\n      });\n      setCounts(countMap);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to load modules.');\n    } finally {\n      setModulesLoading(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    if (!project) {\n      navigate('/select-project', { replace: true });\n      return;\n    }\n    Promise.resolve().then(() => loadModules(project.name));\n  }, [project, navigate, loadModules]);\n\n  const handleToggle = async (record, checked) => {\n    try {\n      await setCTModuleStatus(record.id, checked ? 1 : 0);\n      setModules((rows) =>\n        rows.map((r) => (r.id === record.id ? { ...r, active: checked ? 1 : 0 } : r)),\n      );\n      message.success(`Module ${checked ? 'activated' : 'deactivated'}.`);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to update module status.');\n    }\n  };\n\n  const handleAdd = async () => {\n    const name = moduleName.trim();\n    if (!name) {\n      message.warning('Enter a module name.');\n      return;\n    }\n    setSaving(true);\n    try {\n      await addCTModule({ project: project.name, modulename: name });\n      message.success('Module added.');\n      setAddOpen(false);\n      setModuleName('');\n      setListPage(1);\n      loadModules(project.name);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to add module (maybe it already exists).');\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  const goToSubmodules = (record) => {\n    navigate(`/test-cases/zinnext/submodules?module=${encodeURIComponent(record.modulename)}`);\n  };\n\n  const fields = [\n    { label: 'Module', value: 'modulename' },\n    {\n      label: 'Submodules',\n      value: 'submoduleCount',\n      width: 140,\n      render: (_value, record) => (\n        <Button type=\"link\" className=\"zt-count-link\" onClick={() => goToSubmodules(record)}>\n          {counts[record.modulename] ?? 0} submodule(s)\n        </Button>\n      ),\n    },\n    {\n      label: 'Active',\n      value: 'active',\n      width: 120,\n      render: (value, record) => (\n        <Switch\n          checked={value === 1}\n          checkedChildren=\"On\"\n          unCheckedChildren=\"Off\"\n          onChange={(checked) => handleToggle(record, checked)}\n        />\n      ),\n    },\n  ];\n\n  if (!project) return null;\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col>\n          <AppBreadcrumb items={breadcrumbItems} />\n        </Col>\n        <Col>\n          <Button type=\"link\" onClick={() => navigate('/addTestCase')}>\n            Back to Form\n          </Button>\n        </Col>\n      </Row>\n\n      <div className=\"zt-page\">\n        <Card className=\"v1-card zt-bar\">\n          <Row gutter={[16, 16]} align=\"middle\" justify=\"space-between\">\n            <Col>\n              <Space size={6} className=\"zt-section-title\">\n                <ProjectOutlined />\n                <span>Project:</span>\n                <Text strong>{project.name}</Text>\n              </Space>\n            </Col>\n            <Col>\n              <Button\n                type=\"primary\"\n                icon={<PlusOutlined />}\n                onClick={() => setAddOpen(true)}\n              >\n                Add Module\n              </Button>\n            </Col>\n          </Row>\n        </Card>\n\n        <Card\n          className=\"v1-card zt-fall\"\n          title={(\n            <Space size={6} className=\"zt-section-title\">\n              <AppstoreOutlined />\n              <span>Modules</span>\n            </Space>\n          )}\n        >\n          <ParamListView\n            listName=\"Modules\"\n            loading={modulesLoading}\n            fields={fields}\n            dataSource={modules}\n            current={listPage}\n            pageSize={listPageSize}\n            total={modules.length}\n            onPageChange={setListPage}\n            onPageSizeChange={(size) => {\n              setListPage(1);\n              setListPageSize(size);\n            }}\n            rowSelection={false}\n            className=\"zt-list-plain\"\n          />\n        </Card>\n      </div>\n\n      <Modal\n        title=\"Add Module\"\n        open={addOpen}\n        confirmLoading={saving}\n        okText=\"Add\"\n        onOk={handleAdd}\n        onCancel={() => { setAddOpen(false); setModuleName(''); }}\n        destroyOnHidden\n      >\n        <Space direction=\"vertical\" className=\"zt-modal-stack\">\n          <Text type=\"secondary\">Project: <b>{project.name}</b></Text>\n          <Input\n            placeholder=\"Enter module name\"\n            maxLength={100}\n            value={moduleName}\n            onChange={(e) => setModuleName(e.target.value)}\n            onPressEnter={handleAdd}\n          />\n        </Space>\n      </Modal>\n    </main>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n  Button,\n  Card,\n  Col,\n  Input,\n  Modal,\n  Row,\n  Space,\n  Switch,\n  Typography,\n  message,\n} from 'antd';\nimport { AppstoreOutlined, PlusOutlined, ProjectOutlined } from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport ParamListView from '../../components/ParamListView';\nimport { addCTSubmodule, getCTSubmodules, setCTSubmoduleStatus } from '../../services/testingApi';\nimport { getSelectedProject } from '../../services/authApi';\n\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/addTestCase' },\n  { label: 'Manage Modules', href: '/manageModules' },\n  { label: 'Manage Submodules', href: '/test-cases/zinnext/submodules' },\n];\n\nexport default function ManageSubmodules() {\n  const navigate = useNavigate();\n  const [searchParams] = useSearchParams();\n  const project = useMemo(() => getSelectedProject(), []);\n  const moduleName = searchParams.get('module') ?? '';\n\n  const [submodules, setSubmodules] = useState([]);\n  const [submodulesLoading, setSubmodulesLoading] = useState(false);\n  const [addOpen, setAddOpen] = useState(false);\n  const [submoduleName, setSubmoduleName] = useState('');\n  const [saving, setSaving] = useState(false);\n  const [listPage, setListPage] = useState(1);\n  const [listPageSize, setListPageSize] = useState(10);\n\n  const loadSubmodules = useCallback(async (projectName, module) => {\n    if (!projectName || !module) {\n      setSubmodules([]);\n      return;\n    }\n    setSubmodulesLoading(true);\n    try {\n      const res = await getCTSubmodules({ project: projectName, module });\n      setSubmodules(res?.items ?? []);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to load submodules.');\n    } finally {\n      setSubmodulesLoading(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    if (!project) {\n      navigate('/select-project', { replace: true });\n      return;\n    }\n    if (!moduleName) {\n      // no module context -> go pick one from Manage Modules\n      navigate('/manageModules', { replace: true });\n      return;\n    }\n    Promise.resolve().then(() => loadSubmodules(project.name, moduleName));\n  }, [project, moduleName, navigate, loadSubmodules]);\n\n  const handleToggle = async (record, checked) => {\n    try {\n      await setCTSubmoduleStatus(record.id, checked ? 1 : 0);\n      setSubmodules((rows) =>\n        rows.map((r) => (r.id === record.id ? { ...r, active: checked ? 1 : 0 } : r)),\n      );\n      message.success(`Submodule ${checked ? 'activated' : 'deactivated'}.`);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to update submodule status.');\n    }\n  };\n\n  const handleAdd = async () => {\n    const name = submoduleName.trim();\n    if (!name) {\n      message.warning('Enter a submodule name.');\n      return;\n    }\n    setSaving(true);\n    try {\n      await addCTSubmodule({ project: project.name, modulename: moduleName, submodulename: name });\n      message.success('Submodule added.');\n      setAddOpen(false);\n      setSubmoduleName('');\n      setListPage(1);\n      loadSubmodules(project.name, moduleName);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to add submodule (maybe it already exists).');\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  const fields = [\n    { label: 'Submodule', value: 'submodulename' },\n    {\n      label: 'Active',\n      value: 'active',\n      width: 120,\n      render: (value, record) => (\n        <Switch\n          checked={value === 1}\n          checkedChildren=\"On\"\n          unCheckedChildren=\"Off\"\n          onChange={(checked) => handleToggle(record, checked)}\n        />\n      ),\n    },\n  ];\n\n  if (!project || !moduleName) return null;\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col>\n          <AppBreadcrumb items={breadcrumbItems} />\n        </Col>\n        <Col>\n          <Button type=\"link\" onClick={() => navigate('/manageModules')}>\n            Back to Modules\n          </Button>\n        </Col>\n      </Row>\n\n      <div className=\"zt-page\">\n        <Card className=\"v1-card zt-bar\">\n          <Row gutter={[16, 16]} align=\"middle\" justify=\"space-between\">\n            <Col>\n              <Space size={16} wrap className=\"zt-section-title\">\n                <Space size={6}>\n                  <ProjectOutlined />\n                  <span>Project:</span>\n                  <Text strong>{project.name}</Text>\n                </Space>\n                <Space size={6}>\n                  <AppstoreOutlined />\n                  <span>Module:</span>\n                  <Text strong>{moduleName}</Text>\n                </Space>\n              </Space>\n            </Col>\n            <Col>\n              <Button\n                type=\"primary\"\n                icon={<PlusOutlined />}\n                onClick={() => setAddOpen(true)}\n              >\n                Add Submodule\n              </Button>\n            </Col>\n          </Row>\n        </Card>\n\n        <Card\n          className=\"v1-card zt-fall\"\n          title={(\n            <Space size={6} className=\"zt-section-title\">\n              <AppstoreOutlined />\n              <span>Submodules</span>\n            </Space>\n          )}\n        >\n          <ParamListView\n            listName=\"Submodules\"\n            loading={submodulesLoading}\n            fields={fields}\n            dataSource={submodules}\n            current={listPage}\n            pageSize={listPageSize}\n            total={submodules.length}\n            onPageChange={setListPage}\n            onPageSizeChange={(size) => {\n              setListPage(1);\n              setListPageSize(size);\n            }}\n            rowSelection={false}\n            className=\"zt-list-plain\"\n          />\n        </Card>\n      </div>\n\n      <Modal\n        title=\"Add Submodule\"\n        open={addOpen}\n        confirmLoading={saving}\n        okText=\"Add\"\n        onOk={handleAdd}\n        onCancel={() => { setAddOpen(false); setSubmoduleName(''); }}\n        destroyOnHidden\n      >\n        <Space direction=\"vertical\" className=\"zt-modal-stack\">\n          <Text type=\"secondary\">Project: <b>{project.name}</b> &nbsp;|&nbsp; Module: <b>{moduleName}</b></Text>\n          <Input\n            placeholder=\"Enter submodule name\"\n            maxLength={100}\n            value={submoduleName}\n            onChange={(e) => setSubmoduleName(e.target.value)}\n            onPressEnter={handleAdd}\n          />\n        </Space>\n      </Modal>\n    </main>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n  Button,\n  Card,\n  Col,\n  Input,\n  Modal,\n  Row,\n  Space,\n  Tag,\n  Tooltip,\n  Typography,\n  message,\n} from 'antd';\nimport { DeleteOutlined, EditOutlined, ExclamationCircleOutlined, ReloadOutlined, TableOutlined } from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport ParamListView from '../../components/ParamListView';\nimport { deleteCTFlow, getCTFlows } from '../../services/testingApi';\nimport { getSelectedProject } from '../../services/authApi';\n\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/addTestCase' },\n  { label: 'Table', href: '/viewTestCase' },\n];\n\nexport default function ZinnextTableView() {\n  const navigate = useNavigate();\n  const [rows, setRows] = useState([]);\n  const [total, setTotal] = useState(0);\n  const [loading, setLoading] = useState(false);\n  const project = useMemo(() => getSelectedProject(), []);\n  const [search, setSearch] = useState('');\n  const [page, setPage] = useState(1);\n  const [pageSize, setPageSize] = useState(20);\n  const [deletingId, setDeletingId] = useState(null);\n\n\n  const loadFlows = useCallback(async (opts = {}) => {\n    setLoading(true);\n    try {\n      const res = await getCTFlows({\n        product_parent_ID: opts.project ?? project?.id ?? '',\n        search: opts.search ?? search ?? '',\n        limit: opts.pageSize ?? pageSize,\n        offset: ((opts.page ?? page) - 1) * (opts.pageSize ?? pageSize),\n      });\n      setRows(res?.items ?? []);\n      setTotal(res?.total ?? 0);\n    } catch (error) {\n      console.error(error);\n      message.error('Unable to load test flows.');\n    } finally {\n      setLoading(false);\n    }\n  }, [project?.id, search, page, pageSize]);\n\n  const handleDelete = (record) => {\n    Modal.confirm({\n      title: 'Delete Test Case',\n      icon: <ExclamationCircleOutlined />,\n      content: 'Are you sure you want to delete this test case?',\n      okText: 'Delete',\n      okButtonProps: { danger: true, loading: deletingId === record.id },\n      cancelText: 'Cancel',\n      async onOk() {\n        setDeletingId(record.id);\n        try {\n          await deleteCTFlow(record.id);\n          message.success('Test case deleted successfully.');\n          const nextPage = rows.length === 1 && page > 1 ? page - 1 : page;\n          setPage(nextPage);\n          await loadFlows({ page: nextPage });\n        } catch (error) {\n          console.error('Unable to delete test flow:', error);\n          message.error('Unable to delete test case.');\n          throw error;\n        } finally {\n          setDeletingId(null);\n        }\n      },\n    });\n  };\n\n  useEffect(() => {\n    Promise.resolve().then(() => {\n      if (!project?.id) {\n        navigate('/select-project', { replace: true });\n        return;\n      }\n      loadFlows({ page: 1 });\n    });\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  const fields = [\n    {\n      label: 'Actions',\n      value: 'rowActions',\n      width: 112,\n      fixed: 'left',\n      sorter: false,\n      render: (_value, record) => (\n        <Space size={4} className=\"zt-row-actions\">\n          <Tooltip title=\"Edit\">\n            <Button\n              type=\"text\"\n              size=\"small\"\n              icon={<EditOutlined />}\n              onClick={() => navigate(`/addTestCase?edit=${record.id}`)}\n            />\n          </Tooltip>\n          <Tooltip title=\"Delete\">\n            <Button\n              danger\n              type=\"text\"\n              size=\"small\"\n              icon={<DeleteOutlined />}\n              loading={deletingId === record.id}\n              onClick={() => handleDelete(record)}\n            />\n          </Tooltip>\n        </Space>\n      ),\n    },\n    { label: 'ID', value: 'id', width: 70, fixed: 'left' },\n    { label: 'Project', value: 'project', width: 130 },\n    { label: 'Module', value: 'module', width: 130 },\n    { label: 'Submodule', value: 'submodule', width: 140 },\n    { label: 'Step', value: 'step_order', width: 70 },\n    { label: 'Action', value: 'actions', width: 140 },\n    { label: 'Key', value: 'key', width: 160, ellipsis: true },\n    { label: 'Value', value: 'value', width: 200, ellipsis: true },\n    { label: 'Expected', value: 'expected', width: 180, ellipsis: true },\n    { label: 'Description', value: 'description', width: 180, ellipsis: true },\n    {\n      label: 'Scenario',\n      value: 'scenario',\n      width: 110,\n      render: (v) => (v === 1 ? <Tag color=\"green\">Positive</Tag> : <Tag color=\"red\">Negative</Tag>),\n    },\n    {\n      label: 'Active',\n      value: 'active',\n      width: 90,\n      render: (v) => (v === 1 ? <Tag color=\"blue\">Active</Tag> : <Tag>Inactive</Tag>),\n    },\n  ];\n\n  const handleSearch = () => {\n    setPage(1);\n    loadFlows({ page: 1 });\n  };\n\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col>\n          <AppBreadcrumb items={breadcrumbItems} />\n        </Col>\n        <Col>\n          <Button type=\"link\" onClick={() => navigate('/addTestCase')}>\n            Back to Form\n          </Button>\n        </Col>\n      </Row>\n\n      <div className=\"zt-page zt-page-wide\">\n        <Card\n          className=\"v1-card\"\n          title={(\n            <Space size={6} className=\"zt-section-title\">\n              <TableOutlined />\n              <span>Test Flows</span>\n            </Space>\n          )}\n          extra={<Text type=\"secondary\">{total} row(s)</Text>}\n        >\n          <Space wrap className=\"zt-toolbar\">\n            <Input.Search\n              allowClear\n              className=\"zt-search-filter\"\n              placeholder=\"Search module / key / description\"\n              value={search}\n              onChange={(e) => setSearch(e.target.value)}\n              onSearch={handleSearch}\n            />\n            <Button icon={<ReloadOutlined />} onClick={() => loadFlows()}>\n              Refresh\n            </Button>\n          </Space>\n\n          <ParamListView\n            listName=\"Test Flows\"\n            loading={loading}\n            fields={fields}\n            dataSource={rows}\n            current={page}\n            pageSize={pageSize}\n            total={total}\n            onPageChange={(nextPage) => {\n              setPage(nextPage);\n              loadFlows({ page: nextPage });\n            }}\n            onPageSizeChange={(nextSize) => {\n              setPage(1);\n              setPageSize(nextSize);\n              loadFlows({ page: 1, pageSize: nextSize });\n            }}\n            rowSelection={false}\n            className=\"zt-list-plain\"\n          />\n        </Card>\n      </div>\n    </main>\n  );\n}\n\n\n","import AppBreadcrumb from '../../components/Breadcrumb';\nimport ListView from '../../components/ListView';\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'Test Cases', href: '/test-cases' },\n];\n\nexport default function TestHomePage() {\n  return (\n    <main className=\"jobs-list-page\">\n      <AppBreadcrumb items={breadcrumbItems} />\n      <ListView moduleName={'test-flows'} rowKey=\"id\" />\n    </main>\n  );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AutoComplete, Button, Card, Col, Form, Input, Modal, Row, Select, Space, Typography, message } from 'antd';\nimport {\n  FileTextOutlined,\n  PlusOutlined,\n  ProfileOutlined,\n  TagsOutlined,\n} from '@ant-design/icons';\nimport AppBreadcrumb from '../../components/Breadcrumb';\nimport AppCard from '../../components/cards/AppCard';\nimport { addLmsFlow, addTestingOption, getActionFieldRules, getLmsFlows, getTestingOptions } from '../../services/testingApi';\nimport { zinnextActionOptions } from '../../services/dropdownValues/testPageValues';\n\nconst { Text } = Typography;\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'LMS Cases', href: '/lms-cases' },\n];\n\nconst initialValues = {\n  tags: 'regression',\n  active: 1,\n};\n\nconst testingOptionTypes = {\n  module: {\n    dbName: 'Modules',\n    formField: 'module',\n    label: 'Module',\n  },\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CHANGE 1 — Action-based field validation matrix (same as ZinnextTestForm)\n// true  = field is MANDATORY for this action\n// false = field is NOT needed (will be disabled + placeholder updated)\n// ─────────────────────────────────────────────────────────────────────────────\nconst EMPTY_FIELD_RULES = { key: false, value: false, expected: false };\n\nfunction getFieldRules(actionFieldRules, action) {\n  if (!action) return EMPTY_FIELD_RULES;\n  return actionFieldRules[action] ?? EMPTY_FIELD_RULES;\n}\n\nfunction clearFieldErrors(form, fieldNames) {\n  form.setFields(fieldNames.map((name) => ({ name, errors: [] })));\n}\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction toSelectOptions(items = []) {\n  return items.map((item) => ({\n    value: item,\n    label: item,\n  }));\n}\n\nfunction normalizeText(value = '') {\n  return String(value ?? '').trim();\n}\n\nfunction getUniqueFlowOptions(rows = []) {\n  const flowMap = new Map();\n\n  rows.forEach((row) => {\n    const flow = normalizeText(row?.flow);\n    const key = flow.toLowerCase();\n\n    if (flow && !flowMap.has(key)) {\n      flowMap.set(key, flow);\n    }\n  });\n\n  return Array.from(flowMap.values()).map((flow) => ({\n    value: flow,\n    label: flow,\n  }));\n}\n\nfunction getNextStepOrder(rows = [], module, flow) {\n  const selectedModule = normalizeText(module).toLowerCase();\n  const selectedFlow = normalizeText(flow).toLowerCase();\n  const lastStepOrder = rows.reduce((maxStepOrder, row) => {\n    const rowModule = normalizeText(row?.module).toLowerCase();\n    const rowFlow = normalizeText(row?.flow).toLowerCase();\n\n    if (rowModule !== selectedModule || rowFlow !== selectedFlow) {\n      return maxStepOrder;\n    }\n\n    const stepOrder = Number(row?.step_order) || 0;\n    return Math.max(maxStepOrder, stepOrder);\n  }, 0);\n\n  return lastStepOrder + 1;\n}\n\nfunction SectionTitle({ icon, title }) {\n  return (\n    <Space size={10} align=\"center\">\n      <div className=\"v1-section-icon-box\">{icon}</div>\n      <Text strong className=\"v1-section-label\">{title}</Text>\n    </Space>\n  );\n}\n\nexport default function LmsTestForm() {\n  const [form] = Form.useForm();\n  const [optionForm] = Form.useForm();\n  const [moduleItems, setModuleItems] = useState([]);\n  const [flowRows, setFlowRows] = useState([]);\n  const [flowOptions, setFlowOptions] = useState([]);\n  const [actionOptions, setActionOptions] = useState(zinnextActionOptions);\n  const [actionFieldRules, setActionFieldRules] = useState({});\n  const [optionsLoading, setOptionsLoading] = useState(false);\n  const [flowsLoading, setFlowsLoading] = useState(false);\n  const [optionModal, setOptionModal] = useState({ open: false, typeKey: 'module' });\n  const [optionSaving, setOptionSaving] = useState(false);\n  const [stepOrderLoading, setStepOrderLoading] = useState(false);\n  const [submitting, setSubmitting] = useState(false);\n  const navigate = useNavigate();\n\n  const selectedOptionType = testingOptionTypes[optionModal.typeKey];\n  const moduleOptions = useMemo(() => toSelectOptions(moduleItems), [moduleItems]);\n\n  const selectedModule   = Form.useWatch('module',  form);\n  const selectedFlow     = Form.useWatch('flow',    form);\n  // CHANGE 2 — watch the action field so validation matrix can react\n  const selectedAction   = Form.useWatch('keyword', form);\n\n  const hasSelectedModule = Boolean(normalizeText(selectedModule));\n  const hasSelectedFlow   = Boolean(normalizeText(selectedFlow));\n  const areFlowFieldsDisabled = !hasSelectedModule;\n  const areDetailsDisabled    = !hasSelectedModule || !hasSelectedFlow;\n\n  // CHANGE 3 — derive live rules from currently selected action\n  const fieldRules = useMemo(() => getFieldRules(actionFieldRules, selectedAction), [actionFieldRules, selectedAction]);\n\n  const setItemsByType = (typeKey, items = []) => {\n    if (typeKey === 'module') {\n      setModuleItems(items);\n    }\n  };\n\n  const loadTestingOptions = async () => {\n    setOptionsLoading(true);\n\n    try {\n      const modulesResponse = await getTestingOptions(testingOptionTypes.module.dbName);\n      setModuleItems(modulesResponse?.items ?? []);\n    } catch (error) {\n      console.error('Unable to load testing options:', error);\n      message.error('Unable to load testing options.');\n    } finally {\n      setOptionsLoading(false);\n    }\n  };\n\n  const loadActionFieldRules = async () => {\n    try {\n      const res = await getActionFieldRules();\n      if (Array.isArray(res?.options) && res.options.length > 0) {\n        setActionOptions(res.options);\n      }\n      if (res?.rules && typeof res.rules === 'object') {\n        setActionFieldRules(res.rules);\n      }\n    } catch (error) {\n      console.error('Unable to load action field rules:', error);\n      message.error('Unable to load action validation rules.');\n    }\n  };\n\n  const loadModuleFlows = useCallback(async (module) => {\n    const normalizedModule = normalizeText(module);\n\n    setFlowRows([]);\n    setFlowOptions([]);\n    form.setFieldsValue({ step_order: undefined });\n\n    if (!normalizedModule) return;\n\n    setFlowsLoading(true);\n\n    try {\n      const response = await getLmsFlows({ limit: 10000, offset: 0, module: normalizedModule });\n      const rows = Array.isArray(response?.items) ? response.items : [];\n\n      setFlowRows(rows);\n      setFlowOptions(getUniqueFlowOptions(rows));\n    } catch (error) {\n      console.error('Unable to load flows:', error);\n      message.error('Unable to load flows.');\n    } finally {\n      setFlowsLoading(false);\n    }\n  }, [form]);\n\n  const loadNextStepOrder = useCallback(async (module, flow, rows) => {\n    const normalizedModule = normalizeText(module);\n    const normalizedFlow   = normalizeText(flow);\n\n    if (!normalizedModule || !normalizedFlow) {\n      form.setFieldsValue({ step_order: undefined });\n      return;\n    }\n\n    setStepOrderLoading(true);\n\n    try {\n      form.setFieldsValue({ step_order: getNextStepOrder(rows, normalizedModule, normalizedFlow) });\n    } catch (error) {\n      console.error('Unable to load step order:', error);\n      message.error('Unable to load step order.');\n    } finally {\n      setStepOrderLoading(false);\n    }\n  }, [form]);\n\n  useEffect(() => {\n    Promise.resolve().then(async () => {\n      await Promise.all([loadTestingOptions(), loadActionFieldRules()]);\n    });\n  }, []);\n\n  useEffect(() => {\n    Promise.resolve().then(() => loadModuleFlows(selectedModule));\n  }, [loadModuleFlows, selectedModule]);\n\n  useEffect(() => {\n    Promise.resolve().then(() => loadNextStepOrder(selectedModule, selectedFlow, flowRows));\n  }, [flowRows, loadNextStepOrder, selectedFlow, selectedModule]);\n\n  const onFinish = async (values) => {\n    const payload = {\n      module:      normalizeText(values.module),\n      flow:        normalizeText(values.flow),\n      step_order:  Number(values.step_order),\n      description: normalizeText(values.description),\n      keyword:     normalizeText(values.keyword),\n      target:      normalizeText(values.target),\n      value:       normalizeText(values.value),\n      expected:    normalizeText(values.expected),\n      tags:        values.tags ? normalizeText(values.tags) : initialValues.tags,\n      active:      Number(values.active),\n    };\n\n    setSubmitting(true);\n    try {\n      await addLmsFlow(payload);\n      message.success('LMS case details saved successfully.');\n      form.resetFields();\n      setFlowRows([]);\n      setFlowOptions([]);\n    } catch (error) {\n      console.error('Unable to save LMS case:', error);\n      message.error('Unable to save LMS case.');\n    } finally {\n      setSubmitting(false);\n    }\n  };\n\n  const removeExtraSpaces = (fieldName, value) => {\n    form.setFieldsValue({ [fieldName]: normalizeText(value) });\n  };\n\n  const handleModuleChange = (value) => {\n    form.setFieldsValue({\n      module:      normalizeText(value),\n      flow:        undefined,\n      step_order:  undefined,\n      keyword:     undefined,\n      description: undefined,\n      target:      undefined,\n      tags:        initialValues.tags,\n      value:       undefined,\n      expected:    undefined,\n    });\n    clearFieldErrors(form, ['keyword', 'target', 'value', 'expected']);\n  };\n\n  const handleFlowChange = (value) => {\n    form.setFieldsValue({\n      flow: normalizeText(value),\n      step_order: undefined,\n      keyword: undefined,\n      target: undefined,\n      value: undefined,\n      expected: undefined,\n    });\n    clearFieldErrors(form, ['keyword', 'target', 'value', 'expected']);\n  };\n\n  // CHANGE 4 — when action changes, clear fields not needed for the new action\n  const handleActionChange = (value) => {\n    const rules = getFieldRules(actionFieldRules, value);\n    form.setFieldsValue({\n      keyword:  normalizeText(value),\n      target:   rules.key      ? form.getFieldValue('target')   : undefined,\n      value:    rules.value    ? form.getFieldValue('value')    : undefined,\n      expected: rules.expected ? form.getFieldValue('expected') : undefined,\n    });\n    clearFieldErrors(form, ['target', 'value', 'expected']);\n  };\n\n  const openOptionModal = (typeKey) => {\n    const optionType = testingOptionTypes[typeKey];\n    setOptionModal({ open: true, typeKey });\n    optionForm.setFieldsValue({ name: '', type: optionType.label });\n  };\n\n  const closeOptionModal = () => {\n    setOptionModal((current) => ({ ...current, open: false }));\n    optionForm.resetFields();\n  };\n\n  const saveTestingOption = async () => {\n    try {\n      const values  = await optionForm.validateFields();\n      const name    = normalizeText(values.name);\n      const response = await addTestingOption({ name, type: selectedOptionType.dbName });\n\n      setItemsByType(optionModal.typeKey, response?.items ?? []);\n      form.setFieldsValue({ [selectedOptionType.formField]: name });\n      message.success(`${selectedOptionType.label} added successfully.`);\n      closeOptionModal();\n    } catch (error) {\n      if (error?.errorFields) return;\n      console.error('Unable to save testing option:', error);\n      message.error(`Unable to add ${selectedOptionType.label.toLowerCase()}.`);\n    } finally {\n      setOptionSaving(false);\n    }\n  };\n\n  const submitTestingOption = () => {\n    setOptionSaving(true);\n    saveTestingOption();\n  };\n\n  return (\n    <main className=\"jobs-list-page\">\n      <Row align=\"middle\" justify=\"space-between\" className=\"breadcrumb-action-wrapper\">\n        <Col>\n          <AppBreadcrumb items={breadcrumbItems} />\n        </Col>\n        <Col>\n          <Button type=\"link\" onClick={() => navigate('/lms-home')}>\n            View Table\n          </Button>\n        </Col>\n      </Row>\n\n      <div className=\"v1-page\">\n        <div className=\"v1-page-inner\">\n          <div className=\"v1-page-header\">\n            <Space align=\"center\" size={10}>\n              <ProfileOutlined className=\"v1-outer-icon\" />\n              <div>\n                <Text strong style={{ fontSize: 16 }}>Add LMS Case</Text>\n              </div>\n            </Space>\n          </div>\n\n          <AppCard>\n            <Form\n              form={form}\n              className=\"v1-form\"\n              layout=\"vertical\"\n              colon={false}\n              requiredMark={(label, { required }) => (\n                <>\n                  {label}\n                  {required && <span className=\"v1-required-mark\"> *</span>}\n                </>\n              )}\n              initialValues={initialValues}\n              onFinish={onFinish}\n              autoComplete=\"off\"\n            >\n              <Card\n                className=\"v1-card\"\n                title={<SectionTitle icon={<FileTextOutlined />} title=\"LMS Case Details\" />}\n                extra={\n                  <Text type=\"secondary\" className=\"v1-card-subtitle\">\n                    Module, flow, step order and execution data\n                  </Text>\n                }\n              >\n                <Row gutter={[24, 0]}>\n                  {/* Module */}\n                  <Col xs={24} md={12}>\n                    <Space.Compact style={{ width: '100%' }}>\n                      <Form.Item label=\"Module\" name=\"module\" style={{ flex: 1 }}>\n                        <Select\n                          allowClear\n                          showSearch\n                          loading={optionsLoading}\n                          optionFilterProp=\"label\"\n                          placeholder=\"Select module\"\n                          options={moduleOptions}\n                          onChange={handleModuleChange}\n                        />\n                      </Form.Item>\n                      <Button\n                        aria-label=\"Add module\"\n                        icon={<PlusOutlined />}\n                        style={{ marginTop: 30 }}\n                        onClick={() => openOptionModal('module')}\n                      />\n                    </Space.Compact>\n                  </Col>\n\n                  {/* Flow */}\n                  <Col xs={24} md={12}>\n                    <Form.Item label=\"Flow\" name=\"flow\">\n                      <AutoComplete\n                        maxLength={100}\n                        allowClear\n                        disabled={areFlowFieldsDisabled}\n                        options={flowOptions}\n                        placeholder={flowsLoading ? 'Loading flows' : 'Enter flow'}\n                        onChange={handleFlowChange}\n                        filterOption={(inputValue, option) =>\n                          option?.value?.toLowerCase().includes(inputValue.toLowerCase())\n                        }\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Step Order */}\n                  <Col xs={24} md={12}>\n                    <Form.Item label=\"Step Order\" name=\"step_order\" validateTrigger={['onBlur', 'onChange']}>\n                      <Input\n                        maxLength={10}\n                        disabled\n                        placeholder={stepOrderLoading ? 'Loading step order' : 'Step order'}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Action — unchanged, just wired to handleActionChange */}\n                  <Col xs={24} md={12}>\n                    <Form.Item label=\"Action\" name=\"keyword\">\n                      <Select\n                        allowClear\n                        showSearch\n                        disabled={areDetailsDisabled}\n                        optionFilterProp=\"label\"\n                        placeholder=\"Select action\"\n                        options={actionOptions}\n                        onChange={handleActionChange}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Description — not in validation matrix, always editable */}\n                  <Col xs={24}>\n                    <Form.Item label=\"Description\" name=\"description\">\n                      <Input.TextArea\n                        rows={3}\n                        maxLength={255}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter description\"\n                        showCount\n                        onBlur={(e) => removeExtraSpaces('description', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* ─────────────────────────────────────────────────────────\n                      CHANGE 5 — Key (target), Value, Expected now have\n                      dynamic required rules + disabled + placeholder\n                      based on the selected action keyword.\n                      ───────────────────────────────────────────────────────── */}\n\n                  {/* Key (stored as \"target\" in this form) */}\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Key\"\n                      name=\"target\"\n                      rules={[\n                        {\n                          required: fieldRules.key,\n                          message: 'Key is required for this action',\n                        },\n                      ]}\n                    >\n                      <Input\n                        maxLength={255}\n                        disabled={areDetailsDisabled || (Boolean(selectedAction) && !fieldRules.key)}\n                        placeholder={\n                          areDetailsDisabled\n                            ? 'Select module and flow first'\n                            : !selectedAction\n                            ? 'Select an action first'\n                            : fieldRules.key\n                            ? 'Required — Enter selector / locator'\n                            : 'Not needed for this action'\n                        }\n                        onBlur={(e) => removeExtraSpaces('target', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Tags — not in validation matrix, always editable when details enabled */}\n                  <Col xs={24} md={12}>\n                    <Form.Item label=\"Tags\" name=\"tags\">\n                      <Input\n                        maxLength={200}\n                        disabled={areDetailsDisabled}\n                        placeholder=\"Enter tags\"\n                        prefix={<TagsOutlined className=\"v1-input-icon\" />}\n                        onBlur={(e) => removeExtraSpaces('tags', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Value */}\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Value\"\n                      name=\"value\"\n                      rules={[\n                        {\n                          required: fieldRules.value,\n                          message: 'Value is required for this action',\n                        },\n                      ]}\n                    >\n                      <Input.TextArea\n                        rows={4}\n                        disabled={areDetailsDisabled || (Boolean(selectedAction) && !fieldRules.value)}\n                        placeholder={\n                          areDetailsDisabled\n                            ? 'Select module and flow first'\n                            : !selectedAction\n                            ? 'Select an action first'\n                            : fieldRules.value\n                            ? 'Required — Enter value'\n                            : 'Not needed for this action'\n                        }\n                        onBlur={(e) => removeExtraSpaces('value', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n\n                  {/* Expected */}\n                  <Col xs={24} md={12}>\n                    <Form.Item\n                      label=\"Expected\"\n                      name=\"expected\"\n                      rules={[\n                        {\n                          required: fieldRules.expected,\n                          message: 'Expected result is required for this action',\n                        },\n                      ]}\n                    >\n                      <Input.TextArea\n                        rows={4}\n                        disabled={areDetailsDisabled || (Boolean(selectedAction) && !fieldRules.expected)}\n                        placeholder={\n                          areDetailsDisabled\n                            ? 'Select module and flow first'\n                            : !selectedAction\n                            ? 'Select an action first'\n                            : fieldRules.expected\n                            ? 'Required — Enter expected result'\n                            : 'Not needed for this action'\n                        }\n                        onBlur={(e) => removeExtraSpaces('expected', e.target.value)}\n                      />\n                    </Form.Item>\n                  </Col>\n                  {/* ───────────────────────────────────────────────────────── */}\n                </Row>\n              </Card>\n\n              <div className=\"v1-form-actions\">\n                <Form.Item>\n                  <Space>\n                    <Button\n                      type=\"primary\"\n                      htmlType=\"submit\"\n                      loading={submitting}\n                      disabled={areDetailsDisabled}\n                    >\n                      Submit\n                    </Button>\n                    <Button\n                      onClick={() => {\n                        form.resetFields();\n                        setFlowRows([]);\n                        setFlowOptions([]);\n                      }}\n                    >\n                      Reset\n                    </Button>\n                  </Space>\n                </Form.Item>\n              </div>\n            </Form>\n          </AppCard>\n\n          <Modal\n            title={`Add ${selectedOptionType.label}`}\n            open={optionModal.open}\n            confirmLoading={optionSaving}\n            okText=\"Add\"\n            onCancel={closeOptionModal}\n            onOk={submitTestingOption}\n            destroyOnHidden\n          >\n            <Form\n              form={optionForm}\n              layout=\"vertical\"\n              colon={false}\n              className=\"v1-form\"\n              requiredMark={(label, { required }) => (\n                <>\n                  {label}\n                  {required && <span className=\"v1-required-mark\"> *</span>}\n                </>\n              )}\n            >\n              <Form.Item label=\"Name\" name=\"name\">\n                <Input\n                  maxLength={100}\n                  placeholder={`Enter ${selectedOptionType.label.toLowerCase()} name`}\n                  onBlur={(e) => {\n                    optionForm.setFieldsValue({ name: normalizeText(e.target.value) });\n                  }}\n                />\n              </Form.Item>\n              <Form.Item label=\"Type\" name=\"type\">\n                <Input disabled />\n              </Form.Item>\n            </Form>\n          </Modal>\n        </div>\n      </div>\n    </main>\n  );\n}\n","import AppBreadcrumb from '../../components/Breadcrumb';\nimport ListView from '../../components/ListView';\n\nconst breadcrumbItems = [\n  { label: 'Home', href: '/' },\n  { label: 'LMS Cases', href: '/lms-cases' },\n];\n\nexport default function LmsHomePage() {\n  return (\n    <main className=\"jobs-list-page\">\n      <AppBreadcrumb items={breadcrumbItems} />\n      <ListView moduleName={'lms-flows'} rowKey=\"id\" />\n    </main>\n  );\n}\n","import { mapListResponse } from './responseMapping/mapListResponse';\n\n// Keys tried, in order, to find the shared identifier on either side of a\n// merge when no explicit key is configured.\nconst DEFAULT_MERGE_KEYS = [\n  'referenceId', 'ReferenceId',\n  'candidateId', 'CandidateId',\n  'entityId', 'EntityId',\n  'id', 'Id', '_id',\n];\n\nexport function createKeyResolver(keys = DEFAULT_MERGE_KEYS) {\n  return function resolveKey(record) {\n    if (!record || typeof record !== 'object') return '';\n    for (const key of keys) {\n      const value = record[key];\n      if (value !== undefined && value !== null && value !== '') return String(value);\n    }\n    return '';\n  };\n}\n\n// Every merge-key value a record carries — not just the first. The two sides\n// of a merge often name their shared id differently, so indexing a join side\n// under a single \"best\" key can miss matches the data actually supports.\nfunction collectKeys(record, keys = DEFAULT_MERGE_KEYS) {\n  if (!record || typeof record !== 'object') return [];\n  const values = [];\n  for (const key of keys) {\n    const value = record[key];\n    if (value !== undefined && value !== null && value !== '') values.push(String(value));\n  }\n  return values;\n}\n\nexport const resolveMergeKey = createKeyResolver();\n\n// Accepts a field name ('referenceId'), a priority list of field names, or a\n// custom (record) => key function.\nfunction normalizeKeyResolver(key) {\n  if (typeof key === 'function') return key;\n  if (typeof key === 'string') return createKeyResolver([key]);\n  if (Array.isArray(key)) return createKeyResolver(key);\n  return resolveMergeKey;\n}\n\n// Primary fields win over joined fields on name collisions; the row id stays\n// stable for existing row navigation and detail routes.\nexport function defaultMergeRow(primaryRow, secondaryRow, key) {\n  if (!secondaryRow || typeof secondaryRow !== 'object') return primaryRow;\n  return {\n    ...secondaryRow,\n    ...primaryRow,\n    id: primaryRow?.id ?? secondaryRow?.id ?? key,\n  };\n}\n\n// The same envelope /module-data-list responds with, so mapListResponse\n// resolves rows via payload.data and total via response.total unchanged.\nexport function toModuleListResponse(rows, total, meta = {}) {\n  return { status: 'success', total, data: { data: rows, ...meta } };\n}\n\n/**\n * Generic merge helper for two arbitrary APIs.\n */\nexport async function mergeApiResponses({\n  fetchPrimary,\n  fetchSecondary,\n  primaryArgs = [],\n  secondaryArgs = [],\n  extractPrimaryItems = (response) => response,\n  extractSecondaryItems = (response) => response,\n  primaryKey,\n  secondaryKey,\n  mergeItem = defaultMergeRow,\n  combineResponse = ({ mergedItems }) => mergedItems,\n}) {\n  const [primaryResponse, secondaryResponse] = await Promise.all([\n    fetchPrimary(...(typeof primaryArgs === 'function' ? primaryArgs() : primaryArgs)),\n    fetchSecondary(...(typeof secondaryArgs === 'function' ? secondaryArgs() : secondaryArgs)),\n  ]);\n\n  const primaryItems = extractPrimaryItems(primaryResponse) ?? [];\n  const secondaryItems = extractSecondaryItems(secondaryResponse) ?? [];\n  const resolvePrimary = normalizeKeyResolver(primaryKey);\n  const resolveSecondary = normalizeKeyResolver(secondaryKey);\n\n  const secondaryByKey = new Map();\n  secondaryItems.forEach((item) => {\n    const key = resolveSecondary(item);\n    if (key && !secondaryByKey.has(key)) secondaryByKey.set(key, item);\n  });\n\n  const mergedItems = primaryItems.map((item) => {\n    const key = resolvePrimary(item);\n    return mergeItem(item, secondaryByKey.get(key), key);\n  });\n\n  return combineResponse({\n    primaryResponse,\n    secondaryResponse,\n    primaryItems,\n    secondaryItems,\n    mergedItems,\n  });\n}\n\nconst META_KEYS = ['fields', 'fieldConfig', 'tabs', 'tabField', 'actionRules', 'actions', 'columnActions'];\n\nexport function extractListMeta(response) {\n  const payload = response?.data ?? response;\n  const meta = {};\n  for (const key of META_KEYS) {\n    const value = response?.[key] ?? payload?.[key];\n    const isEmpty = value == null || (Array.isArray(value) && value.length === 0);\n    if (!isEmpty) meta[key] = value;\n  }\n  return meta;\n}\n\nconst normalizeFieldName = (name) => String(name ?? '').replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n\nfunction insertFieldsAfter(fields, extraFields, anchor) {\n  const anchors = (Array.isArray(anchor) ? anchor : [anchor])\n    .map(normalizeFieldName)\n    .filter(Boolean);\n  const index = anchors.length\n    ? fields.findIndex((field) =>\n        anchors.includes(normalizeFieldName(field?.value))\n        || anchors.includes(normalizeFieldName(field?.label)))\n    : -1;\n  if (index === -1) return [...fields, ...extraFields];\n\n  const anchorOrder = Number(fields[index]?.order);\n  const positioned = Number.isFinite(anchorOrder)\n    ? extraFields.map((field, i) =>\n        field.order == null || field.order === ''\n          ? { ...field, order: anchorOrder + (i + 1) / (extraFields.length + 1) }\n          : field)\n    : extraFields;\n  return [...fields.slice(0, index + 1), ...positioned, ...fields.slice(index + 1)];\n}\n\nconst mapRows = (response, moduleName) => mapListResponse(response, moduleName).rows;\n\nconst mapPage = (response, moduleName) => {\n  const { rows, total } = mapListResponse(response, moduleName);\n  return { rows, total };\n};\n\nexport function createModuleListFetchAdapter(fetcher, fixedModuleName) {\n  return function fetchModuleList(moduleName, limit, offset, options = {}) {\n    return fetcher(fixedModuleName ?? moduleName, limit, offset, options);\n  };\n}\n\nfunction normalizeJoinSource(source) {\n  if (!source || typeof source !== 'object') return null;\n  const fetcher = source.fetchByKeys ?? source.fetch ?? source.function;\n  if (typeof fetcher !== 'function') return null;\n  return {\n    ...source,\n    fetchByKeys: typeof source.fetchByKeys === 'function' ? source.fetchByKeys : null,\n    fetch: typeof source.fetch === 'function' ? source.fetch : null,\n    function: typeof source.function === 'function' ? source.function : null,\n    extractRows: typeof source.extractRows === 'function' ? source.extractRows : mapRows,\n    mergeRow: typeof source.mergeRow === 'function' ? source.mergeRow : defaultMergeRow,\n    fetchById: typeof source.fetchById === 'function' ? source.fetchById : null,\n  };\n}\n\nfunction createLegacyJoinSources({\n  fetchSecondaryByKeys,\n  fetchSecondary,\n  extractSecondaryRows,\n  fetchSecondaryById,\n  secondaryKey,\n  mergeRow,\n  secondaryFetchLimit,\n}) {\n  if (!fetchSecondaryByKeys && !fetchSecondary && !fetchSecondaryById) return [];\n  return [normalizeJoinSource({\n    key: secondaryKey,\n    fetchByKeys: fetchSecondaryByKeys\n      ? (moduleName, keys, options) => fetchSecondaryByKeys(moduleName, keys, options)\n      : null,\n    function: fetchSecondary\n      ? ({ moduleName, options }) => fetchSecondary(moduleName, secondaryFetchLimit, 0, options)\n      : null,\n    extractRows: extractSecondaryRows,\n    fetchById: fetchSecondaryById,\n    mergeRow,\n  })].filter(Boolean);\n}\n\nfunction createSourceKeyCollector(key) {\n  if (typeof key === 'function') {\n    return (record) => {\n      const value = key(record);\n      return value === undefined || value === null || value === '' ? [] : [String(value)];\n    };\n  }\n\n  const keys = typeof key === 'string'\n    ? [key]\n    : (Array.isArray(key) && key.length ? key : DEFAULT_MERGE_KEYS);\n\n  return (record) => collectKeys(record, keys);\n}\n\nfunction indexJoinRows(rows, collectSourceKeys) {\n  const byKey = new Map();\n  rows.forEach((row) => {\n    for (const key of collectSourceKeys(row)) {\n      if (!byKey.has(key)) byKey.set(key, row);\n    }\n  });\n  return byKey;\n}\n\nfunction buildJoinContext({ moduleName, limit, offset, options, keys, primaryResponse, primaryRows, pageRows, total, source }) {\n  return {\n    moduleName,\n    limit,\n    offset,\n    options,\n    keys,\n    primaryResponse,\n    primaryRows,\n    pageRows,\n    total,\n    source,\n  };\n}\n\nasync function invokeJoinSource(source, context) {\n  if (typeof source.args === 'function') {\n    const args = source.args(context);\n    return (source.fetch ?? source.function ?? source.fetchByKeys)(...(Array.isArray(args) ? args : [args]));\n  }\n  if (Array.isArray(source.args)) {\n    return (source.fetch ?? source.function ?? source.fetchByKeys)(...source.args);\n  }\n  if (source.fetchByKeys && Array.isArray(context.keys)) {\n    return source.fetchByKeys(context.moduleName, context.keys, context.options, context);\n  }\n  const fetcher = source.fetch ?? source.function;\n  if (typeof fetcher !== 'function') return null;\n  return fetcher(context);\n}\n\n/**\n * @param {object} config\n *\n * Server-paginated mode (preferred):\n * @param {Function} [config.fetchPrimaryPage] async (moduleName, limit, offset, options) => response.\n * @param {Function} [config.extractPrimaryPage] (response, moduleName) => { rows, total }.\n * @param {Function} [config.fetchSecondaryByKeys] legacy single-join keyed fetch.\n *\n * Legacy full-set mode:\n * @param {Function} [config.fetchPrimary] async (moduleName, limit, offset, options) => response.\n * @param {Function} [config.extractPrimaryRows] (response, moduleName) => rows.\n * @param {Function} [config.fetchSecondary] legacy single-join full fetch.\n *\n * Shared:\n * @param {object[]} [config.joinSources] One or more join sources. A minimal\n *   source is `{ function: apiCall, key: 'id' }`. `function`/`fetch` receives\n *   a single context object. `fetchByKeys`, when provided, receives\n *   `(moduleName, keys, options, context)`.\n */\nexport function createMergedListFetcher({\n  fetchPrimaryPage,\n  extractPrimaryPage = mapPage,\n  fetchSecondaryByKeys,\n  joinSources = [],\n  fetchPrimary,\n  extractPrimaryRows = mapRows,\n  fetchSecondary,\n  extractSecondaryRows = mapRows,\n  fetchSecondaryById,\n  primaryKey,\n  secondaryKey,\n  mergeRow = defaultMergeRow,\n  secondaryFetchLimit = 200,\n  extraFields = [],\n  extraFieldsAfter,\n}) {\n  const normalizedJoinSources = (\n    Array.isArray(joinSources) && joinSources.length\n      ? joinSources.map(normalizeJoinSource).filter(Boolean)\n      : createLegacyJoinSources({\n          fetchSecondaryByKeys,\n          fetchSecondary,\n          extractSecondaryRows,\n          fetchSecondaryById,\n          secondaryKey,\n          mergeRow,\n          secondaryFetchLimit,\n        })\n  );\n\n  let callSeq = 0;\n\n  async function lookupJoinRowById(source, collectSourceKeys, moduleName, key) {\n    if (!source.fetchById || !key) return null;\n    try {\n      const record = await source.fetchById(moduleName, key);\n      return record && collectSourceKeys(record).includes(String(key)) ? record : null;\n    } catch (error) {\n      console.error(`[mergedListApi] per-id join lookup failed for \"${key}\"`, error);\n      return null;\n    }\n  }\n\n  function warnOnNoMatch(pageRows, joinRows, joinByKey, resolvePageKey, collectSourceKeys) {\n    if (import.meta.env?.DEV && joinRows.length && pageRows.length\n        && !pageRows.some((row) => joinByKey.has(resolvePageKey(row)))) {\n      console.warn('[mergedListApi] no merge-key match between primary and join rows', {\n        samplePrimaryKey: resolvePageKey(pageRows[0]),\n        sampleJoinKeys: collectSourceKeys(joinRows[0]),\n        samplePrimaryRow: pageRows[0],\n        sampleJoinRow: joinRows[0],\n      });\n    }\n  }\n\n  async function applyJoinSourceToRows(rows, source, response, moduleName, isStale) {\n    if (!response) return rows;\n\n    const joinRows = source.extractRows(response, moduleName) ?? [];\n    const resolvePageKey = normalizeKeyResolver(source.primaryKey ?? primaryKey);\n    const collectSourceKeys = createSourceKeyCollector(source.key);\n    const joinByKey = indexJoinRows(joinRows, collectSourceKeys);\n\n    warnOnNoMatch(rows, joinRows, joinByKey, resolvePageKey, collectSourceKeys);\n\n    return Promise.all(\n      rows.map(async (row) => {\n        const key = resolvePageKey(row);\n        const match = joinByKey.get(key)\n          ?? (isStale() ? null : await lookupJoinRowById(source, collectSourceKeys, moduleName, key));\n        return source.mergeRow(row, match, key);\n      }),\n    );\n  }\n\n  async function mergeRows(pageRows, joinResults, moduleName, isStale) {\n    let mergedRows = pageRows;\n    for (const result of joinResults) {\n      mergedRows = await applyJoinSourceToRows(mergedRows, result.source, result.response, moduleName, isStale);\n    }\n    return mergedRows;\n  }\n\n  function buildResponse(mergedRows, total, responses) {\n    const meta = {};\n    for (const response of responses) {\n      if (!response) continue;\n      const extracted = extractListMeta(response);\n      for (const key of Object.keys(extracted)) {\n        if (meta[key] == null) meta[key] = extracted[key];\n      }\n    }\n    if (extraFields.length) {\n      meta.fields = insertFieldsAfter(meta.fields ?? [], extraFields, extraFieldsAfter);\n    }\n    return toModuleListResponse(mergedRows, total, meta);\n  }\n\n  async function fetchJoinResults({ moduleName, limit, offset, options, primaryResponse, primaryRows, pageRows, total }) {\n    return Promise.all(\n      normalizedJoinSources.map(async (source) => {\n        try {\n          const resolvePageKey = normalizeKeyResolver(source.primaryKey ?? primaryKey);\n          const keys = [...new Set(pageRows.map(resolvePageKey).filter(Boolean))];\n          if (source.fetchByKeys && keys.length === 0) return { source, response: null };\n          const context = buildJoinContext({\n            moduleName,\n            limit,\n            offset,\n            options,\n            keys,\n            primaryResponse,\n            primaryRows,\n            pageRows,\n            total,\n            source,\n          });\n          const response = await invokeJoinSource(source, context);\n          return { source, response };\n        } catch (error) {\n          console.error('[mergedListApi] join fetch failed — rendering page without that join', error);\n          return { source, response: null };\n        }\n      }),\n    );\n  }\n\n  async function fetchPaginated(moduleName, limit, offset, options, isStale) {\n    const primaryResponse = await fetchPrimaryPage(moduleName, limit, offset, options);\n    const page = extractPrimaryPage(primaryResponse, moduleName) ?? {};\n    const pageRows = Array.isArray(page.rows) ? page.rows : [];\n    const total = Number.isFinite(Number(page.total)) ? Number(page.total) : pageRows.length;\n\n    const joinResults = await fetchJoinResults({\n      moduleName,\n      limit,\n      offset,\n      options,\n      primaryResponse,\n      primaryRows: pageRows,\n      pageRows,\n      total,\n    });\n\n    const mergedRows = await mergeRows(pageRows, joinResults, moduleName, isStale);\n    return buildResponse(mergedRows, total, [primaryResponse, ...joinResults.map((result) => result.response)]);\n  }\n\n  async function fetchFullSet(moduleName, limit, offset, options, isStale) {\n    const primaryResponse = await fetchPrimary(moduleName, limit, offset, options);\n    const primaryRows = extractPrimaryRows(primaryResponse, moduleName) ?? [];\n    const total = primaryRows.length;\n    const pageRows = primaryRows.slice(offset, offset + limit);\n\n    const joinResults = await fetchJoinResults({\n      moduleName,\n      limit,\n      offset,\n      options,\n      primaryResponse,\n      primaryRows,\n      pageRows,\n      total,\n    });\n\n    const mergedRows = await mergeRows(pageRows, joinResults, moduleName, isStale);\n    return buildResponse(mergedRows, total, [primaryResponse, ...joinResults.map((result) => result.response)]);\n  }\n\n  return async function fetchMergedList(moduleName, limit = 10, offset = 0, options = {}) {\n    const seq = ++callSeq;\n    const isStale = () => seq !== callSeq;\n\n    return fetchPrimaryPage\n      ? fetchPaginated(moduleName, limit, offset, options, isStale)\n      : fetchFullSet(moduleName, limit, offset, options, isStale);\n  };\n}\n","/**\n * workflowModuleListApi.js\n *\n * Concrete instances of the generic two-API merge engine (mergedListApi.js):\n * workflow records enriched with their full module records, served in the\n * shape ListView already consumes.\n *\n * For the next \"merge API X + API Y into ListView\" requirement, do NOT write\n * a new merge implementation — write a small config like these against\n * createMergedListFetcher().\n *\n * Usage with the existing ListView component:\n *\n *   const fetchData = useMemo(\n *     () => createWorkflowStageListFetcher(workflowId, stageName),\n *     [workflowId, stageName],\n *   );\n *   <ListView moduleName=\"candidate\" fetchData={fetchData} />\n */\n\nimport {\n  getWorkflowStage,\n  extractStageCandidates,\n  getModuleRecordById,\n  getAllWorkflows,\n} from './workflowApi';\nimport { getModuleDataList } from './dropdownApi';\nimport { mapListResponse } from './responseMapping/mapListResponse';\nimport { createMergedListFetcher, defaultMergeRow, resolveMergeKey } from './mergedListApi';\n\nexport { resolveMergeKey };\n\n/**\n * Builds a ListView-compatible fetchData function bound to one workflow stage.\n *\n * Legacy full-set mode: the stage endpoint returns the whole stage data array\n * (no server paging exists for it), so the engine paginates it client-side.\n *\n * @param {string} workflowId\n * @param {string} stageName\n * @param {object} [config]\n * @param {number} [config.moduleFetchLimit=200] bulk /module-data-list fetch\n *   size for merging; uncovered entries fall back to a per-id lookup.\n */\nexport function createWorkflowStageListFetcher(workflowId, stageName, config = {}) {\n  return createMergedListFetcher({\n    fetchPrimary: () => getWorkflowStage(workflowId, stageName),\n    extractPrimaryRows: extractStageCandidates,\n    fetchSecondary: getModuleDataList,\n    fetchSecondaryById: getModuleRecordById,\n    secondaryFetchLimit: config.moduleFetchLimit ?? 200,\n  });\n}\n\n// \"Pipeline\" -> pipelineCount, \"Client Submitted\" -> clientSubmittedCount.\nexport function stageCountKey(stageName) {\n  const words = String(stageName ?? '').trim().split(/[^a-zA-Z0-9]+/).filter(Boolean);\n  if (!words.length) return '';\n  const camel = words\n    .map((word, i) => (i === 0 ? word.toLowerCase() : word[0].toUpperCase() + word.slice(1).toLowerCase()))\n    .join('');\n  return `${camel}Count`;\n}\n\n// Workflow entries carry per-stage counts as a nested array\n// (stages: [{ stageName, count }]) which ListView columns can't read —\n// flatten each stage onto the row as <stageName>Count.\nfunction withStageCounts(workflow) {\n  const stages = Array.isArray(workflow?.stages) ? workflow.stages : [];\n  if (!stages.length) return workflow;\n  const counts = {};\n  for (const stage of stages) {\n    const key = stageCountKey(stage?.stageName);\n    if (key) counts[key] = Number(stage?.count) || 0;\n  }\n  return { ...counts, ...workflow };\n}\n\n// \"1 of 2\" — submitted-so-far (workflow side) against the job record's\n// admin-entered target. Blank when the job has no positive target set.\nconst readTargetSubmission = (row) => {\n  const target = Number(row?.targetSubmission ?? row?.targetSubmissions);\n  return Number.isFinite(target) && target > 0 ? target : null;\n};\n\nfunction createTargetSubmissionMergeRow({\n  submittedCountField = 'submittedCount',\n  progressField = 'targetSubmissionProgress',\n} = {}) {\n  return function mergeJobWorkflowRow(primaryRow, secondaryRow, key) {\n    const merged = defaultMergeRow(primaryRow, secondaryRow, key);\n    const target = readTargetSubmission(merged);\n    if (target != null) {\n      merged[progressField] = `${Number(merged?.[submittedCountField]) || 0} of ${target}`;\n    }\n    return merged;\n  };\n}\n\n/**\n * Builds a ListView-compatible fetchData function for the merged module +\n * workflow list (e.g. the Jobs page): module record _id <- workflow.entityId.\n *\n * PRIMARY: /module-data-list — drives membership, order and the pager, and\n * receives ListView's options untouched, so tabs (My Jobs / All Jobs),\n * scope, field filters, sort and search all keep working exactly as on a\n * plain module list.\n * SECONDARY: /workflow/list/all — each job page is enriched with the matching\n * workflow page (stage counts flattened to <stage>Count, plus workflowId and\n * the computed targetSubmissionProgress).\n *\n * @param {object} [config]\n * @param {object[]} [config.extraFields] static ListView column configs\n *   appended after the admin-configured fields.\n * @param {string|string[]} [config.extraFieldsAfter] admin field anchor used\n *   to place the extra fields.\n */\nexport function createAllWorkflowsListFetcher(config = {}) {\n  const mergeTargetSubmission = createTargetSubmissionMergeRow();\n\n  const fetchMergedList = createMergedListFetcher({\n    primaryKey: '_id',\n    extraFields: config.extraFields,\n    extraFieldsAfter: config.extraFieldsAfter,\n    fetchPrimaryPage: getModuleDataList,\n    joinSources: [\n      {\n        key: 'entityId',\n        fetchByKeys: (_moduleName, _keys, _options, context) => {\n          const pageSize = Math.max(1, Number(context?.limit) || 10);\n          const page = Math.floor((Number(context?.offset) || 0) / pageSize) + 1;\n          return getAllWorkflows(page, pageSize);\n        },\n        extractRows: (response) => (response?.items ?? []).map(withStageCounts),\n        mergeRow: (primaryRow, secondaryRow, key) => {\n          const merged = mergeTargetSubmission(primaryRow, secondaryRow, key);\n          if (secondaryRow?._id) merged.workflowId = secondaryRow._id;\n          return merged;\n        },\n      },\n    ],\n  });\n\n  return fetchMergedList;\n}\n\n/**\n * One-shot convenience wrapper: merged workflows + module records in the\n * ListView-shaped model ({ rows, total, fields, ... }).\n */\nexport async function getAllWorkflowsModuleList(\n  moduleName,\n  limit = 10,\n  offset = 0,\n  options = {},\n  config = {},\n) {\n  const fetchList = createAllWorkflowsListFetcher(config);\n  const response = await fetchList(moduleName, limit, offset, options);\n  return mapListResponse(response, moduleName);\n}\n\n/**\n * One-shot convenience wrapper for callers outside ListView that just want\n * the merged, ListView-shaped model ({ rows, total, fields, ... }).\n */\nexport async function getWorkflowStageModuleList(\n  workflowId,\n  stageName,\n  moduleName,\n  limit = 10,\n  offset = 0,\n  options = {},\n) {\n  const fetchList = createWorkflowStageListFetcher(workflowId, stageName);\n  const response = await fetchList(moduleName, limit, offset, options);\n  return mapListResponse(response, moduleName);\n}\n","\n// Build stamp — see vite.lib.config.js. Read it in the browser console with:\n//   window.__CORE_THEME_BUILD__\n// A value OLDER than your last rebuild means the page is running a cached\n// bundle, not your change. No console output: this is a value to query, not\n// noise on every load.\nif (typeof window !== 'undefined') {\n  window.__CORE_THEME_BUILD__ = typeof __CORE_THEME_BUILD__ === 'string'\n    ? __CORE_THEME_BUILD__\n    : 'dev';\n}\n// ─────────────────────────────────────────────────────────────────────────\n// @realtek/core-theme — public entry point (barrel export)\n//\n// Consumer apps import components from the package name, e.g.:\n//     import { AddFormV1 } from '@realtek/core-theme';\n//     import '@realtek/core-theme/style.css';\n//\n// Anything exported here becomes part of the library's public API.\n// ─────────────────────────────────────────────────────────────────────────\n\n// All component + theme styles, bundled into a single dist-lib/style.css\nimport './styles/library.css';\n\n// ── Cards ──────────────────────────────────────────────────────────────────\nexport { default as CalendarCard } from './components/cards/CalendarCard.jsx';\nexport { default as DynamicCards } from './components/cards/DynamicCards.jsx';\nexport { default as HierarchyUserFilter } from './components/cards/HierarchyUserFilter.jsx';\n\n// ── Components ─────────────────────────────────────────────────────────────\nexport { default as AddFormV1 } from './components/AddFormV1.jsx';\n\n// The application clock. Exported so a CONSUMER APP formats a timestamp the\n// same way the package does — jobConfig had written its own toLocaleDateString\n// helper precisely because these were unreachable, and it rendered in the\n// BROWSER's zone with no zone label, so the header read \"Aug 06, 2026 | 08:02AM\"\n// while the activity beside it read the tenant's time. Two clocks on one screen.\nexport {\n  formatApp,\n  formatAppDateTime,\n  toApp,\n  appNow,\n  tzShortLabel,\n  tzLabel,\n  getAppTimeZone,\n} from './services/timezone';\nexport { default as AppAlert } from './components/AppAlert.jsx';\n\nexport { default as ActivityTab } from './components/detail/ActivityTab.jsx';\nexport { default as ActivityNotesCard } from './components/detail/ActivityNotesCard.jsx';\nexport { default as NotesTab } from './components/detail/NotesTab.jsx';\nexport { resolveActivityMeta } from './components/detail/activityMeta.jsx';\nexport { default as TimelineGroups } from './components/detail/timeline.jsx';\nexport { default as AppButton } from './components/AppButton.jsx';\nexport { default as AssigneeAvatars } from './components/AssigneeAvatars.jsx';\nexport { default as Breadcrumb } from './components/Breadcrumb.jsx';\nexport { default as BulkUploadPanel } from './components/upload/BulkUploadPanel.jsx';\nexport {\n  validateBulkFile,\n  buildAcceptAttr,\n  formatFileSize,\n  getFileExtension,\n  DEFAULT_ACCEPT as BULK_UPLOAD_DEFAULT_ACCEPT,\n  DEFAULT_MAX_SIZE_MB as BULK_UPLOAD_DEFAULT_MAX_SIZE_MB,\n} from './components/upload/bulkUploadValidation.js';\nexport { default as CustomPagination } from './components/CustomPagination.jsx';\nexport { default as DescriptionBlock } from './components/DescriptionBlock.jsx';\nexport { default as DetailHeaderCard } from './components/detail/DetailHeaderCard.jsx';\nexport { default as DetailViewPage } from './components/DetailViewPage.jsx';\nexport { default as DetailViewV1 } from './components/DetailViewV1.jsx';\nexport { default as DocumentViewer } from './components/DocumentViewer.jsx';\nexport { default as DynamicTabs } from './components/DynamicTabs.jsx';\nexport { default as EditFormV1 } from './components/EditFormV1.jsx';\nexport { default as ListView } from './components/ListView.jsx';\nexport { default as ModuleRowActions } from './components/actions/ModuleRowActions.jsx';\nexport { useModuleActions } from './hooks/useModuleActions.js';\nexport { default as ParamCardView } from './components/ParamCardView.jsx';\nexport { default as ParamListView } from './components/ParamListView.jsx';\nexport { default as SearchBuilderV1 } from './components/SearchBuilderV1.jsx';\n// Consuming apps can add a project-specific search input type without a\n// core-theme release.\nexport {\n  registerFieldType,\n  getFieldType,\n  isBooleanEligible,\n  getBooleanEligibleTypes,\n  FIELD_TYPE_REGISTRY,\n} from './components/searchBuilder/fieldTypeRegistry.jsx';\nexport {\n  validateBooleanQuery,\n  insertTokenAtCursor,\n  isBooleanParsable,\n  BOOLEAN_PARSEABLE_API_KEYS,\n} from './components/searchBuilder/booleanQueryUtils.js';\nexport { buildBooleanRequest, BOOLEAN_API_KEYS } from './components/searchBuilder/buildBooleanRequest.js';\nexport { default as StatusBadge } from './components/StatusBadge.jsx';\nexport { default as StylishDynamicTabs } from './components/StylishDynamicTabs.jsx';\nexport { default as TemplateEditor } from './components/TemplateEditor.jsx';\nexport { default as TipTapEditor } from './components/TipTapEditor.jsx';\nexport { default as ViewSummaryWidget } from './components/ViewSummaryWidget.jsx';\nexport {\n  FinanceHoursGrid,\n  FinanceKpiRow,\n  FinanceStatusPill,\n  FinanceEmptyState,\n  FinanceSection,\n  FinanceLine,\n  FinanceDivider,\n  FinanceEquation,\n  FinanceWorkflowSteps,\n  FinanceHistoryTimeline,\n} from './components/finance/FinanceComponents.jsx';\nexport { default as FinanceListToolbar } from './components/finance/FinanceListToolbar.jsx';\nexport {\n  default as FinanceRecordsTable,\n  FinanceAvatar,\n  FinanceEmployeeCell,\n  FinanceTextCell,\n  FinanceMoneyCell,\n  FinanceBadge,\n  FinanceMarginBadge,\n  FinanceRowChevron,\n} from './components/finance/FinanceRecordsTable.jsx';\nexport { default as FinanceTimesheetAnalysis, FinanceDayCell } from './components/finance/FinanceTimesheetAnalysis.jsx';\nexport * from './components/finance/financeUtils.js';\n// Config-driven Finance Approval flow (submissionManager / onboardingManager / cfo)\nexport { default as FinanceApprovalPanel } from './components/finance/FinanceApprovalPanel.jsx';\nexport {\n  FINANCE_APPROVAL_CONFIG,\n  getFinanceApprovalConfig,\n  marginIncludesReferral,\n  resolveRejectionReason,\n  FINANCE_TYPE_SUBMISSION_MANAGER,\n  FINANCE_TYPE_ONBOARDING_MANAGER,\n  FINANCE_TYPE_CFO,\n  FINANCE_TYPE_ONLY_FINANCE,\n  FINANCE_TYPE_SUBMISSION_MANAGER_REAPPROVE,\n  FINANCE_TYPE_ONBOARDING_MANAGER_REAPPROVE,\n} from './components/finance/financeApprovalConfig.js';\nexport {\n  resolveSubmissionFinance,\n  getFormGroupsRaw,\n  flattenGroups,\n  findEmployerRow,\n} from './components/finance/financeApprovalData.js';\nexport {\n  resolveFinanceInputs,\n  computeFinance,\n  resolveAndCompute,\n  buildRateHistoryEntries,\n  matchLocationTax,\n  normalizeContract,\n  formatMoney as formatFinanceMoney,\n  CONTRACT_W2,\n  CONTRACT_C2C,\n} from './components/finance/financeApprovalEngine.js';\nexport {\n  ApprovalActionBar,\n  buildDayGradient,\n  DayLogModal,\n  NotesPanel,\n  PeriodBadgeTag,\n  ProofUploadPreview,\n  QuickLogBar,\n  QuickLogSelectionBar,\n  RejectionReasonModal,\n  StatusBadgeTag,\n  TimesheetDayCell,\n} from './components/timesheet/TimesheetComponents.jsx';\nexport {\n  computeHoursPolicy,\n  reconcileHours,\n  resolveDayKind,\n  describeCapacity,\n  DEFAULT_HOURS_POLICY,\n  HOURS_MESSAGES,\n} from './components/timesheet/timesheetHoursPolicy.js';\nexport { default as FileListCard } from './components/detail/FileListCard.jsx';\n\n// ── Hooks (all named exports) ──────────────────────────────────────────────\nexport { useRecordRefresh } from './hooks/useRecordRefresh.js';\nexport * from './hooks/useMenuPermission.js';\nexport * from './hooks/useDropdownFields.js';\nexport * from './hooks/useDropdownValues.js';\nexport * from './hooks/useEditForm.js';\n\n// ── App infrastructure (layout / auth / popups / form) ─────────────────────\nexport { AppShell, Header, Sidebar } from './components/layouts/index.js';\nexport {\n  Login,\n  ProjectSelect,\n  AuthGuard,\n  withAuthGuard,\n  CoreThemeAdminApp,\n  CoreThemeAdminRoutes,\n} from './components/auth/index.js';\nexport { MailPopup, PreviewPopup, WizardPopup, DynamicPopup, DynamicPopupRoute, AddBatchCandidatePopup, POPUP_CONFIGS, VendorShareDrawer } from './components/popups/index.js';\nexport { default as UserForm } from './components/form/forms.jsx';\n// Public admin page exports include the global application shell so consumers\n// always receive the main menu and top header. Use AdminDashboardContent only\n// when the host application already renders AppShell itself.\nexport { default as AdminDashboard } from './pages/admin/AdminPageWithShell.jsx';\nexport {\n  getBgcIntegrationConfig,\n  getBgcIntegrationSummary,\n  getIntegrationConfig,\n  getIntegrationConfigs,\n  getIntegrationSummary,\n  applyIntegrationStatus,\n  saveBgcIntegrationConfig,\n  saveIntegrationConfig,\n  deleteIntegrationConfig,\n  testIntegrationConnection,\n} from './services/adminApi';\nexport { default as AdminDashboardContent } from './pages/admin/AdminDashboard.jsx';\n\n// ── Pages (drop straight into the host app's <Route element={...}>) ─────────\n// Only git-TRACKED pages are exported. The flat job/candidate/submission page\n// wrappers (src/pages/jobPage.jsx, candidatePage.jsx, submissoin.jsx, ...) are\n// intentionally NOT in the repo (kept out of main by the block-src-pages\n// policy), so they cannot be bundled. The host app keeps those thin route\n// wrappers itself and composes them from the building blocks below\n// (AddFormV1 / EditFormV1 / ListView / DetailViewV1 / JobsListPage / ...).\n//\n// EVERY page exported below is wrapped in withAuthGuard(), so a host app can\n// drop <AdminPage /> straight onto a route and — if it's opened without a\n// session — it shows the \"you haven't logged in\" screen automatically. The\n// host never has to add an <AuthGuard> wrapper itself; the guard ships baked\n// into the page. (This is centralized here, in ONE place, not per page file.)\nimport withAuthGuard from './components/auth/withAuthGuard.jsx';\n\nimport AdminPageWithShell from './pages/admin/AdminPageWithShell.jsx';\nimport RawLegacyAdminPage from './pages/Modules/LegacyAdminPage.jsx';\nimport RawStickyNotesFullPage from './pages/stickyNotesFullPage.jsx';\nimport RawBulkUploadPage from './pages/BulkUpload/index.jsx';\n\nimport RawTestForm from './pages/TestingPage/test-form.jsx';\nimport RawZinnextTestForm from './pages/TestingPage/ZinnextTestForm.jsx';\nimport RawManageModules from './pages/TestingPage/ManageModules.jsx';\nimport RawManageSubmodules from './pages/TestingPage/ManageSubmodules.jsx';\nimport RawZinnextTableView from './pages/TestingPage/ZinnextTableView.jsx';\nimport RawTestingHomePage from './pages/TestingPage/testHomePage.jsx';\nimport RawLmsTestForm from './pages/TestingPage/lms-test-form.jsx';\nimport RawLmsHomePage from './pages/TestingPage/lmsHomePage.jsx';\n\nexport const AdminPage = AdminPageWithShell;\nexport const LegacyAdminPage = withAuthGuard(RawLegacyAdminPage);\nexport const StickyNotesFullPage = withAuthGuard(RawStickyNotesFullPage);\nexport const BulkUploadPage = withAuthGuard(RawBulkUploadPage);\n\n// Testing-flow pages\nexport const TestForm = withAuthGuard(RawTestForm);\nexport const ZinnextTestForm = withAuthGuard(RawZinnextTestForm);\nexport const ManageModules = withAuthGuard(RawManageModules);\nexport const ManageSubmodules = withAuthGuard(RawManageSubmodules);\nexport const ZinnextTableView = withAuthGuard(RawZinnextTableView);\nexport const TestingHomePage = withAuthGuard(RawTestingHomePage);\nexport const LmsTestForm = withAuthGuard(RawLmsTestForm);\nexport const LmsHomePage = withAuthGuard(RawLmsHomePage);\nexport {\n  createWorkflowStageListFetcher,\n  createAllWorkflowsListFetcher,\n  getAllWorkflowsModuleList,\n  getWorkflowStageModuleList,\n  stageCountKey,\n  resolveMergeKey,\n} from './services/workflowModuleListApi.js';\nexport {\n  createMergedListFetcher,\n  createModuleListFetchAdapter,\n  defaultMergeRow,\n  resolveMergeKey as resolveMergedListKey,\n} from './services/mergedListApi.js';\n\n// ── Services / config / theme (host app uses these in App.jsx) ──────────────\nexport {\n  getStoredToken,\n  getStoredUser,\n  logout,\n  getCurrentRoleName,\n  getUserRoles,\n  isTester,\n  setSelectedProject,\n  getSelectedProject,\n  clearSelectedProject,\n} from './services/authApi.js';\nexport {\n  configureCoreTheme,\n  AUTH_URL,\n  ADMIN_API_URL,\n  ADMIN_APP_ID,\n  APP_ID,\n  withAppId,\n  withAdminAppId,\n  SUBMISSIONS_URL,\n  JOBS_URL,\n  CANDIDATES_URL,\n} from './services/apiConfig.js';\nexport { getActivity, getModuleDataDetail } from './services/detailedViewApi.js';\n// Native submission approve/reject (schema-free gateway) — reused by the host's\n// Finance Approval submissionManager handlers so the edited proposed rate is\n// appended to proposedRate history by the same verified path the popup uses.\nexport { approveSubmission, rejectSubmission, getVMSApprove } from './services/popupApi.js';\nexport { getModuleConfig, getPeriodBadgeConfig } from './components/cards/cardConfig.js';\nexport { colors } from './theme/colors/colors.js';\n\n// Shared formatting + condition helpers. Exported so a HOST app's detail/header\n// config formats money, rate units and conditional labels through exactly the\n// same rules the package's own surfaces use — before this, each host kept its\n// own copy and the two drifted (see configUtils.js in ZINNEXT-V2).\nexport {\n  CURRENCY_SYMBOLS,\n  currencySymbol,\n  rateUnitLabel,\n  rateUnitShort,\n  toNumber,\n  formatAmount,\n  formatMoney,\n  formatRate,\n} from './utils/currency.js';\nexport {\n  conditionMatches,\n  configuredFieldLabel,\n  showIfConditions,\n  evaluateShowIfWith,\n} from './components/form/conditionalFieldLabel.js';\n"],"mappings":"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"}