@elevasis/ui 2.17.2 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.js +5 -5
  3. package/dist/charts/index.js +3 -3
  4. package/dist/chunk-3JCMO7SD.js +14 -0
  5. package/dist/{chunk-TP5NMF6K.js → chunk-46Z2VHY3.js} +4 -4
  6. package/dist/{chunk-FNWWVX5N.js → chunk-5SCVXZPM.js} +358 -188
  7. package/dist/{chunk-TTP62HWW.js → chunk-BHR7IV72.js} +10 -15
  8. package/dist/{chunk-MJ6YV2B5.js → chunk-CTTY6FUT.js} +2 -2
  9. package/dist/{chunk-P3TFNFZS.js → chunk-EUWBY43Z.js} +2 -2
  10. package/dist/{chunk-MDO4UCEJ.js → chunk-IBOX2M24.js} +47 -82
  11. package/dist/{chunk-HH3RNG2O.js → chunk-JEQM67SO.js} +307 -173
  12. package/dist/{chunk-2TDZBYXI.js → chunk-LR5CRY5A.js} +1 -1
  13. package/dist/{chunk-JU6UB4YA.js → chunk-LVCJ2H2T.js} +4 -4
  14. package/dist/{chunk-GRGRBWIO.js → chunk-M7W7CGPL.js} +1 -1
  15. package/dist/{chunk-34NQLV2W.js → chunk-MJAKU2WA.js} +3 -3
  16. package/dist/{chunk-OCCZRPER.js → chunk-Q4QJOSVS.js} +1 -1
  17. package/dist/{chunk-R73EHHPN.js → chunk-Q5HC6ENG.js} +18 -2
  18. package/dist/{chunk-VDM6DQES.js → chunk-R7OJCNL3.js} +1 -1
  19. package/dist/{chunk-6RWMRQN5.js → chunk-TIIPYB2Z.js} +1 -1
  20. package/dist/{chunk-ABUDMATM.js → chunk-TKEKYPZA.js} +6 -6
  21. package/dist/{chunk-R7GKX4HW.js → chunk-UU6PJ4EJ.js} +192 -82
  22. package/dist/{chunk-7L42RRHZ.js → chunk-Y7TDUZEH.js} +221 -514
  23. package/dist/{chunk-7GCWOUFT.js → chunk-YVAXWM3W.js} +73 -121
  24. package/dist/components/index.d.ts +219 -2810
  25. package/dist/components/index.js +41 -27
  26. package/dist/features/crm/index.d.ts +54 -53
  27. package/dist/features/crm/index.js +11 -11
  28. package/dist/features/dashboard/index.js +12 -12
  29. package/dist/features/delivery/index.d.ts +2642 -2605
  30. package/dist/features/delivery/index.js +11 -11
  31. package/dist/features/lead-gen/index.d.ts +152 -16
  32. package/dist/features/lead-gen/index.js +11 -22
  33. package/dist/features/monitoring/index.js +13 -13
  34. package/dist/features/monitoring/requests/index.d.ts +38 -27
  35. package/dist/features/monitoring/requests/index.js +212 -106
  36. package/dist/features/operations/index.d.ts +9 -26
  37. package/dist/features/operations/index.js +15 -15
  38. package/dist/features/settings/index.d.ts +36 -37
  39. package/dist/features/settings/index.js +12 -12
  40. package/dist/hooks/delivery/index.d.ts +2712 -2699
  41. package/dist/hooks/delivery/index.js +2 -2
  42. package/dist/hooks/index.d.ts +1997 -4627
  43. package/dist/hooks/index.js +10 -10
  44. package/dist/hooks/published.d.ts +1997 -4627
  45. package/dist/hooks/published.js +10 -10
  46. package/dist/index.d.ts +1124 -3673
  47. package/dist/index.js +11 -11
  48. package/dist/layout/index.d.ts +14 -2
  49. package/dist/layout/index.js +1 -1
  50. package/dist/provider/index.d.ts +320 -249
  51. package/dist/provider/index.js +8 -8
  52. package/dist/provider/published.d.ts +320 -249
  53. package/dist/provider/published.js +5 -5
  54. package/dist/sse/index.d.ts +1 -6
  55. package/dist/theme/index.js +2 -2
  56. package/dist/types/index.d.ts +1608 -2487
  57. package/dist/utils/index.d.ts +32 -1
  58. package/dist/utils/index.js +1 -1
  59. package/dist/zustand/index.d.ts +4 -8
  60. package/dist/zustand/index.js +2 -2
  61. package/package.json +4 -4
  62. package/dist/chunk-ADSSLKKP.js +0 -10
  63. /package/dist/{chunk-GCBWGGI6.js → chunk-OD7GWIZS.js} +0 -0
@@ -5,18 +5,18 @@ import { SubshellNavItem } from './chunk-CEWTOKE7.js';
5
5
  import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
6
6
  import { FilterBar } from './chunk-PDHTXPSF.js';
7
7
  import { CustomModal } from './chunk-GBMNCNHX.js';
8
- import { useProjectRealtime, useTableSort, sortData, usePaginationState, useTableSelection, useProjectActivities } from './chunk-R7GKX4HW.js';
9
- import { useCreateTask, useCreateMilestone, useProjectMilestones, useUpdateTask, useProjects, useDeleteProject, useProject, useProjectNotes, useUpdateMilestone, useCreateNote, showApiErrorNotification, projectKeys } from './chunk-GRGRBWIO.js';
8
+ import { useProjectRealtime, useTableSort, sortData, usePaginationState, useTableSelection, useProjectActivities } from './chunk-UU6PJ4EJ.js';
9
+ import { useCreateTask, useCreateMilestone, useProjectMilestones, useUpdateTask, useProjects, useDeleteProject, useProject, useProjectNotes, useUpdateMilestone, useCreateNote, showApiErrorNotification, projectKeys } from './chunk-M7W7CGPL.js';
10
10
  import { SubshellContentContainer } from './chunk-RX4UWZZR.js';
11
- import { StatusBadge, EmptyState, PageTitleCaption, CenteredErrorState, StatCard } from './chunk-TTP62HWW.js';
11
+ import { StatusBadge, EmptyState, PageTitleCaption, CenteredErrorState, StatCard, CardHeader } from './chunk-BHR7IV72.js';
12
12
  import { useRouterContext } from './chunk-Q7DJKLEN.js';
13
- import { PAGE_SIZE_DEFAULT, formatTimeAgo, formatDate, formatRelativeTime } from './chunk-GCBWGGI6.js';
13
+ import { PAGE_SIZE_DEFAULT, formatTimeAgo, formatDate, formatRelativeTime } from './chunk-OD7GWIZS.js';
14
14
  import { useElevasisServices } from './chunk-IRW7JMQ4.js';
15
15
  import { useState, useMemo, useCallback } from 'react';
16
- import { Stack, Text, Group, Checkbox, ActionIcon, TextInput, Button, Modal, Title, Textarea, Select, SimpleGrid, Card, ThemeIcon, RingProgress, Paper, Timeline, Badge, Collapse, Center, Loader, Table, Pagination, Alert, CopyButton, Tooltip, Divider, Tabs, Anchor, Chip } from '@mantine/core';
17
- import { IconNotes, IconBriefcase, IconChecklist, IconFlag, IconX, IconPlus, IconHeartbeat, IconFileText, IconCalendar, IconInbox, IconLock, IconAlertTriangle, IconCircleCheck, IconClock, IconChevronDown, IconChevronRight, IconDownload, IconListCheck, IconMessageCircle, IconSearch, IconArrowLeft, IconCheck, IconCopy, IconTerminal2, IconCurrencyDollar, IconBuilding } from '@tabler/icons-react';
16
+ import { Stack, Text, Group, Checkbox, ActionIcon, TextInput, Button, Modal, Title, Textarea, Select, SimpleGrid, Card, ThemeIcon, RingProgress, Paper, Timeline, Badge, Collapse, Center, Loader, Table, Pagination, Alert, CopyButton, Tooltip, Space, Tabs, Divider, Anchor, Chip } from '@mantine/core';
17
+ import { IconNotes, IconBriefcase, IconChecklist, IconFlag, IconX, IconPlus, IconHeartbeat, IconFileText, IconCalendar, IconInbox, IconLock, IconAlertTriangle, IconCircleCheck, IconClock, IconChevronDown, IconChevronRight, IconDownload, IconListCheck, IconMessageCircle, IconSearch, IconCheck, IconCopy, IconFileDescription, IconArrowLeft, IconCurrencyDollar, IconBuilding } from '@tabler/icons-react';
18
18
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
19
- import { useDisclosure, useClipboard } from '@mantine/hooks';
19
+ import { useDisclosure } from '@mantine/hooks';
20
20
  import { useQueryClient, useMutation } from '@tanstack/react-query';
21
21
 
22
22
  function Checklist({ items, onToggle, onAdd, onRemove }) {
@@ -349,7 +349,8 @@ var noteTypeColors = {
349
349
  call_note: "blue",
350
350
  status_update: "green",
351
351
  issue: "yellow",
352
- blocker: "red"
352
+ blocker: "red",
353
+ agent_learning: "grape"
353
354
  };
354
355
  function formatStatusLabel(status) {
355
356
  return status.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
@@ -772,75 +773,92 @@ function ProjectsListPage({ onProjectClick } = {}) {
772
773
  function isResumeContext(val) {
773
774
  return !!val && typeof val === "object" && !Array.isArray(val);
774
775
  }
776
+ function ContextRow({ label, value }) {
777
+ return /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
778
+ /* @__PURE__ */ jsx(
779
+ Text,
780
+ {
781
+ size: "xs",
782
+ ff: "monospace",
783
+ c: "var(--color-text-subtle)",
784
+ style: { textTransform: "uppercase", letterSpacing: "0.06em", opacity: 0.7 },
785
+ children: label
786
+ }
787
+ ),
788
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "var(--color-text)", style: { lineHeight: 1.55 }, children: value })
789
+ ] });
790
+ }
775
791
  function ResumeContextPreview({ tasks }) {
776
792
  const candidate = tasks.filter((t) => isResumeContext(t.resume_context)).sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime())[0];
777
793
  if (!candidate) return null;
778
794
  const ctx = candidate.resume_context;
779
- return /* @__PURE__ */ jsx(
795
+ const hasBody = ctx.current_state || ctx.next_steps;
796
+ return /* @__PURE__ */ jsxs(
780
797
  Paper,
781
798
  {
782
- p: "sm",
799
+ p: "md",
783
800
  style: {
784
801
  border: "1px solid var(--color-border)",
785
802
  borderRadius: "var(--mantine-radius-default)",
786
- backgroundColor: "color-mix(in srgb, var(--color-primary) 5%, var(--color-surface))"
803
+ backgroundColor: "color-mix(in srgb, var(--color-primary) 4%, var(--color-surface))",
804
+ position: "relative",
805
+ overflow: "hidden"
787
806
  },
788
- children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
789
- /* @__PURE__ */ jsx(Group, { gap: "xs", children: /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
790
- "Last worked",
791
- " ",
792
- /* @__PURE__ */ jsx(Text, { component: "span", size: "xs", fw: 500, c: "var(--color-text)", children: formatRelativeTime(candidate.updated_at) }),
793
- " ",
794
- "on",
795
- " ",
796
- /* @__PURE__ */ jsx(Text, { component: "span", size: "xs", fw: 500, c: "var(--color-text)", children: candidate.name })
797
- ] }) }),
798
- ctx.current_state && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
799
- "Current state:",
800
- " ",
801
- /* @__PURE__ */ jsx(Text, { component: "span", size: "xs", c: "var(--color-text-subtle)", children: ctx.current_state })
802
- ] }),
803
- ctx.next_steps && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
804
- "Next:",
805
- " ",
806
- /* @__PURE__ */ jsx(Text, { component: "span", size: "xs", c: "var(--color-text-subtle)", children: ctx.next_steps })
807
+ children: [
808
+ /* @__PURE__ */ jsx(
809
+ "div",
810
+ {
811
+ style: {
812
+ position: "absolute",
813
+ inset: "0 auto 0 0",
814
+ width: 3,
815
+ background: "linear-gradient(180deg, var(--color-primary) 0%, color-mix(in srgb, var(--color-primary) 30%, transparent) 100%)"
816
+ }
817
+ }
818
+ ),
819
+ /* @__PURE__ */ jsxs(Stack, { gap: "sm", pl: 4, children: [
820
+ /* @__PURE__ */ jsxs(Group, { gap: 6, align: "baseline", wrap: "wrap", children: [
821
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Last worked" }),
822
+ /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "var(--color-text)", children: formatRelativeTime(candidate.updated_at) }),
823
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "on" }),
824
+ /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "var(--color-text)", children: candidate.name })
825
+ ] }),
826
+ hasBody && /* @__PURE__ */ jsxs(Fragment, { children: [
827
+ /* @__PURE__ */ jsx(Divider, { opacity: 0.3 }),
828
+ /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
829
+ ctx.current_state && /* @__PURE__ */ jsx(ContextRow, { label: "Current State", value: ctx.current_state }),
830
+ ctx.next_steps && /* @__PURE__ */ jsx(ContextRow, { label: "Next Steps", value: ctx.next_steps })
831
+ ] })
832
+ ] })
807
833
  ] })
808
- ] })
834
+ ]
809
835
  }
810
836
  );
811
837
  }
812
- var buildBootstrapCommand = (projectId) => `/project work ${projectId}`;
813
838
  function QuickActionsRow({
814
839
  onCreateTask,
815
840
  onAddMilestone,
816
841
  onLogBlocker,
817
- onResumeBootstrap
842
+ onBack,
843
+ backLabel = "Projects"
818
844
  }) {
819
- return /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
820
- /* @__PURE__ */ jsx(Button, { variant: "light", size: "compact-sm", leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 14 }), onClick: onCreateTask, children: "Create Task" }),
821
- /* @__PURE__ */ jsx(Button, { variant: "light", size: "compact-sm", leftSection: /* @__PURE__ */ jsx(IconFlag, { size: 14 }), onClick: onAddMilestone, children: "Add Milestone" }),
822
- /* @__PURE__ */ jsx(
823
- Button,
824
- {
825
- variant: "light",
826
- size: "compact-sm",
827
- color: "orange",
828
- leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 14 }),
829
- onClick: onLogBlocker,
830
- children: "Log Blocker"
831
- }
832
- ),
833
- /* @__PURE__ */ jsx(Tooltip, { label: "Copies bootstrap command to clipboard", children: /* @__PURE__ */ jsx(
834
- Button,
835
- {
836
- variant: "light",
837
- size: "compact-sm",
838
- color: "grape",
839
- leftSection: /* @__PURE__ */ jsx(IconTerminal2, { size: 14 }),
840
- onClick: onResumeBootstrap,
841
- children: "Resume Bootstrap"
842
- }
843
- ) })
845
+ return /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", justify: "space-between", children: [
846
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
847
+ /* @__PURE__ */ jsx(Button, { variant: "light", size: "compact-sm", leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 14 }), onClick: onCreateTask, children: "Create Task" }),
848
+ /* @__PURE__ */ jsx(Button, { variant: "light", size: "compact-sm", leftSection: /* @__PURE__ */ jsx(IconFlag, { size: 14 }), onClick: onAddMilestone, children: "Add Milestone" }),
849
+ /* @__PURE__ */ jsx(
850
+ Button,
851
+ {
852
+ variant: "light",
853
+ size: "compact-sm",
854
+ color: "orange",
855
+ leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 14 }),
856
+ onClick: onLogBlocker,
857
+ children: "Log Blocker"
858
+ }
859
+ )
860
+ ] }),
861
+ /* @__PURE__ */ jsx(Button, { variant: "light", size: "compact-sm", leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 14 }), onClick: onBack, children: backLabel })
844
862
  ] });
845
863
  }
846
864
  function LinkedRecordChips({ dealId, clientCompanyId }) {
@@ -886,7 +904,8 @@ var NOTE_FILTER_OPTIONS = [
886
904
  { value: "call_note", label: "Call Notes" },
887
905
  { value: "status_update", label: "Status Updates" },
888
906
  { value: "issue", label: "Issues" },
889
- { value: "blocker", label: "Blockers" }
907
+ { value: "blocker", label: "Blockers" },
908
+ { value: "agent_learning", label: "Agent Learning" }
890
909
  ];
891
910
  function isWithinLastWeek(dateStr) {
892
911
  if (!dateStr) return false;
@@ -1026,13 +1045,69 @@ var noteTypeOptions = [
1026
1045
  { value: "call_note", label: "Call Note" },
1027
1046
  { value: "status_update", label: "Status Update" },
1028
1047
  { value: "issue", label: "Issue" },
1029
- { value: "blocker", label: "Blocker" }
1048
+ { value: "blocker", label: "Blocker" },
1049
+ { value: "agent_learning", label: "Agent Learning" }
1030
1050
  ];
1031
1051
  function parseChecklist2(milestone) {
1032
1052
  const raw = milestone.checklist;
1033
1053
  if (!Array.isArray(raw)) return [];
1034
1054
  return raw;
1035
1055
  }
1056
+ function sortMilestonesForTimeline(milestones) {
1057
+ return [...milestones].sort((a, b) => {
1058
+ if (a.sequence !== b.sequence) return a.sequence - b.sequence;
1059
+ const aCreated = a.created_at ? new Date(a.created_at).getTime() : 0;
1060
+ const bCreated = b.created_at ? new Date(b.created_at).getTime() : 0;
1061
+ if (aCreated !== bCreated) return aCreated - bCreated;
1062
+ return a.name.localeCompare(b.name);
1063
+ });
1064
+ }
1065
+ var bulletSize = 14;
1066
+ function renderMilestoneBullet(status) {
1067
+ const normalizedStatus = status ?? "upcoming";
1068
+ const isCompleted = normalizedStatus === "completed";
1069
+ const isInProgress = normalizedStatus === "in_progress";
1070
+ if (isCompleted) {
1071
+ return /* @__PURE__ */ jsx(
1072
+ "div",
1073
+ {
1074
+ style: {
1075
+ width: bulletSize,
1076
+ height: bulletSize,
1077
+ borderRadius: "50%",
1078
+ backgroundColor: "var(--color-primary)",
1079
+ boxShadow: "0 0 0 4px var(--color-surface)"
1080
+ }
1081
+ }
1082
+ );
1083
+ }
1084
+ const fillColor = isInProgress ? "var(--color-primary)" : "color-mix(in srgb, var(--color-primary) 50%, transparent)";
1085
+ const borderColor = isInProgress ? "var(--color-primary)" : "color-mix(in srgb, var(--color-primary) 20%, transparent)";
1086
+ return /* @__PURE__ */ jsx(
1087
+ "div",
1088
+ {
1089
+ style: {
1090
+ width: bulletSize,
1091
+ height: bulletSize,
1092
+ borderRadius: "50%",
1093
+ backgroundColor: fillColor,
1094
+ border: `2px solid ${borderColor}`,
1095
+ boxSizing: "border-box",
1096
+ zIndex: 2,
1097
+ boxShadow: "0 0 0 4px var(--color-surface)"
1098
+ }
1099
+ }
1100
+ );
1101
+ }
1102
+ function getMilestoneSurfaceStyles(status) {
1103
+ const normalizedStatus = status ?? "upcoming";
1104
+ const accent = normalizedStatus === "completed" ? "var(--color-primary)" : normalizedStatus === "in_progress" ? "color-mix(in srgb, var(--color-primary) 72%, white)" : "color-mix(in srgb, var(--color-primary) 36%, var(--color-border))";
1105
+ const background = normalizedStatus === "completed" ? "var(--color-primary)" : normalizedStatus === "in_progress" ? "linear-gradient(180deg, color-mix(in srgb, var(--color-primary) 3%, transparent) 0%, transparent 100%)" : "linear-gradient(180deg, color-mix(in srgb, var(--color-primary) 1.5%, transparent) 0%, transparent 100%)";
1106
+ return {
1107
+ accent,
1108
+ background
1109
+ };
1110
+ }
1036
1111
  function MilestoneChecklist({ milestone }) {
1037
1112
  const items = parseChecklist2(milestone);
1038
1113
  const { mutate: updateMilestone } = useUpdateMilestone();
@@ -1185,7 +1260,6 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1185
1260
  const [logBlockerOpen, { open: openLogBlocker, close: closeLogBlocker }] = useDisclosure(false);
1186
1261
  const [createTaskOpen, { open: openCreateTask, close: closeCreateTask }] = useDisclosure(false);
1187
1262
  const [addMilestoneOpen, { open: openAddMilestone, close: closeAddMilestone }] = useDisclosure(false);
1188
- const clipboard = useClipboard({ timeout: 2e3 });
1189
1263
  if (isLoading) {
1190
1264
  return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(Center, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(Loader, {}) }) });
1191
1265
  }
@@ -1195,7 +1269,7 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1195
1269
  if (!project) {
1196
1270
  return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(Center, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(Alert, { color: "yellow", children: "Project not found" }) }) });
1197
1271
  }
1198
- const milestones = project.milestones ?? [];
1272
+ const milestones = sortMilestonesForTimeline(project.milestones ?? []);
1199
1273
  const tasks = project.tasks ?? [];
1200
1274
  const totalMilestones = milestones.length;
1201
1275
  const completedMilestones = milestones.filter((milestone) => milestone.status === "completed").length;
@@ -1204,25 +1278,26 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1204
1278
  const milestoneProgress = calculateProgress(completedMilestones, totalMilestones);
1205
1279
  const taskProgress = calculateProgress(approvedTasks, totalTasks);
1206
1280
  const companyName = project.company?.name ?? null;
1207
- const isEmpty = milestones.length === 0 && tasks.length === 0 && !notes?.length;
1208
- const defaultTab = isEmpty ? "details" : "status";
1281
+ const activeMilestoneIndex = milestones.reduce(
1282
+ (lastIndex, milestone, index) => milestone.status !== "upcoming" ? index : lastIndex,
1283
+ -1
1284
+ );
1209
1285
  return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
1210
1286
  /* @__PURE__ */ jsx(
1211
1287
  PageTitleCaption,
1212
1288
  {
1213
1289
  title: project.name,
1214
- caption: [companyName, formatStatusLabel(project.status || "unknown")].filter(Boolean).join(" - "),
1215
- rightSection: /* @__PURE__ */ jsx(Group, { children: /* @__PURE__ */ jsx(Button, { variant: "light", size: "sm", leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }), onClick: onBack, children: backLabel }) })
1290
+ caption: [companyName, formatStatusLabel(project.status || "unknown")].filter(Boolean).join(" - ")
1216
1291
  }
1217
1292
  ),
1218
1293
  /* @__PURE__ */ jsx(
1219
1294
  QuickActionsRow,
1220
1295
  {
1221
- projectId,
1222
1296
  onCreateTask: openCreateTask,
1223
1297
  onAddMilestone: openAddMilestone,
1224
1298
  onLogBlocker: openLogBlocker,
1225
- onResumeBootstrap: () => clipboard.copy(buildBootstrapCommand(projectId))
1299
+ onBack,
1300
+ backLabel
1226
1301
  }
1227
1302
  ),
1228
1303
  /* @__PURE__ */ jsxs(SimpleGrid, { cols: 4, children: [
@@ -1267,7 +1342,6 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1267
1342
  }
1268
1343
  )
1269
1344
  ] }),
1270
- /* @__PURE__ */ jsx(ResumeContextPreview, { tasks }),
1271
1345
  /* @__PURE__ */ jsxs(
1272
1346
  Paper,
1273
1347
  {
@@ -1277,13 +1351,13 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1277
1351
  borderRadius: "var(--mantine-radius-default)"
1278
1352
  },
1279
1353
  children: [
1280
- /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
1281
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "wrap", children: [
1282
- /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
1283
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Project Details" }),
1284
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: projectStatusColors[project.status || ""] || "gray", children: formatStatusLabel(project.status || "unknown") })
1285
- ] }),
1286
- /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
1354
+ /* @__PURE__ */ jsx(Stack, { gap: "md", children: /* @__PURE__ */ jsx(
1355
+ CardHeader,
1356
+ {
1357
+ icon: /* @__PURE__ */ jsx(IconFileDescription, { size: 18 }),
1358
+ title: "Project Details",
1359
+ rightSection: /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "wrap", justify: "flex-end", children: [
1360
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: projectStatusColors[project.status || ""] || "gray", children: formatStatusLabel(project.status || "unknown") }),
1287
1361
  /* @__PURE__ */ jsx(LinkedRecordChips, { dealId: project.deal_id, clientCompanyId: project.client_company_id }),
1288
1362
  /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", c: "var(--color-text-subtle)", children: project.id }),
1289
1363
  /* @__PURE__ */ jsx(CopyButton, { value: `/project work ${project.id}`, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied!" : "Copy ID", withArrow: true, children: /* @__PURE__ */ jsx(
@@ -1297,161 +1371,257 @@ function ProjectDetailPage({ projectId, onBack, backLabel = "Projects" }) {
1297
1371
  }
1298
1372
  ) }) })
1299
1373
  ] })
1374
+ }
1375
+ ) }),
1376
+ /* @__PURE__ */ jsx(Space, { my: "xs" }),
1377
+ /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1378
+ project.description && /* @__PURE__ */ jsxs("div", { children: [
1379
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Description" }),
1380
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: project.description })
1300
1381
  ] }),
1301
- /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
1302
- project.start_date && /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
1303
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Started:" }),
1382
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: 4, children: [
1383
+ /* @__PURE__ */ jsxs("div", { children: [
1384
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Start Date" }),
1304
1385
  /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.start_date) })
1305
1386
  ] }),
1306
- project.target_end_date && /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
1307
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Target:" }),
1387
+ /* @__PURE__ */ jsxs("div", { children: [
1388
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Target End Date" }),
1308
1389
  /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.target_end_date) })
1309
1390
  ] }),
1310
- project.contract_value != null && /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
1311
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Contract:" }),
1312
- /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
1313
- "$",
1314
- project.contract_value.toLocaleString(),
1315
- project.metadata && project.metadata.rate_type === "hourly" ? "/hr" : ""
1316
- ] })
1391
+ /* @__PURE__ */ jsxs("div", { children: [
1392
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Actual End Date" }),
1393
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.actual_end_date) })
1317
1394
  ] }),
1318
- project.company && /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
1319
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Company:" }),
1320
- /* @__PURE__ */ jsx(Text, { size: "sm", children: project.company.name })
1395
+ /* @__PURE__ */ jsxs("div", { children: [
1396
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Contract Value" }),
1397
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: project.contract_value != null ? `$${project.contract_value.toLocaleString()}${project.metadata && project.metadata.rate_type === "hourly" ? "/hr" : ""}` : "-" })
1321
1398
  ] })
1399
+ ] }),
1400
+ project.company && /* @__PURE__ */ jsxs("div", { children: [
1401
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Company" }),
1402
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: project.company.name }),
1403
+ project.company.domain && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: project.company.domain })
1322
1404
  ] })
1323
1405
  ] }),
1324
- /* @__PURE__ */ jsx(Divider, { my: "md" }),
1325
- /* @__PURE__ */ jsxs(Tabs, { defaultValue: defaultTab, children: [
1406
+ /* @__PURE__ */ jsx(Space, { my: "xs" }),
1407
+ /* @__PURE__ */ jsx(ResumeContextPreview, { tasks }),
1408
+ /* @__PURE__ */ jsx(Space, { my: "md" }),
1409
+ /* @__PURE__ */ jsxs(Tabs, { defaultValue: "status", children: [
1326
1410
  /* @__PURE__ */ jsxs(Tabs.List, { children: [
1327
1411
  /* @__PURE__ */ jsx(Tabs.Tab, { value: "status", children: "Status" }),
1328
- /* @__PURE__ */ jsx(Tabs.Tab, { value: "details", children: "Details" }),
1329
1412
  /* @__PURE__ */ jsx(Tabs.Tab, { value: "notes", children: "Notes" }),
1330
1413
  /* @__PURE__ */ jsx(Tabs.Tab, { value: "activity", children: "Activity" })
1331
1414
  ] }),
1332
1415
  /* @__PURE__ */ jsx(Tabs.Panel, { value: "status", pt: "md", children: milestones.length === 0 ? /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: "No milestones yet." }) : /* @__PURE__ */ jsx(
1333
1416
  Timeline,
1334
1417
  {
1335
- active: completedMilestones,
1418
+ active: activeMilestoneIndex,
1336
1419
  bulletSize: 20,
1420
+ lineWidth: 3,
1337
1421
  color: "var(--color-primary)",
1338
1422
  styles: {
1339
1423
  itemBullet: {
1340
- borderColor: "color-mix(in srgb, var(--color-primary) 40%, transparent)",
1341
- backgroundColor: "var(--color-surface)"
1424
+ borderColor: "transparent",
1425
+ backgroundColor: "transparent",
1426
+ padding: 0,
1427
+ zIndex: 3,
1428
+ overflow: "visible",
1429
+ display: "flex",
1430
+ alignItems: "center",
1431
+ justifyContent: "center"
1342
1432
  },
1343
1433
  item: {
1344
- "--_item-border-color": "color-mix(in srgb, var(--color-primary) 25%, transparent)"
1434
+ "--_item-border-color": "color-mix(in srgb, var(--color-primary) 22%, transparent)",
1435
+ paddingBottom: "var(--mantine-spacing-xl)"
1345
1436
  },
1346
1437
  itemTitle: {
1347
1438
  color: "var(--color-text)"
1439
+ },
1440
+ itemBody: {
1441
+ marginTop: 0
1348
1442
  }
1349
1443
  },
1350
1444
  children: milestones.map((milestone) => {
1351
1445
  const milestoneTasks = tasks.filter((task) => task.milestone_id === milestone.id);
1352
- return /* @__PURE__ */ jsxs(
1446
+ const checklistItems = parseChecklist2(milestone);
1447
+ const completedChecklistItems = checklistItems.filter((item) => item.completed).length;
1448
+ const { accent, background } = getMilestoneSurfaceStyles(milestone.status);
1449
+ return /* @__PURE__ */ jsx(
1353
1450
  Timeline.Item,
1354
1451
  {
1355
- bullet: milestone.status === "completed" ? /* @__PURE__ */ jsx(
1356
- "div",
1452
+ bullet: renderMilestoneBullet(milestone.status),
1453
+ title: /* @__PURE__ */ jsx("div", {}),
1454
+ children: /* @__PURE__ */ jsxs(
1455
+ Paper,
1357
1456
  {
1457
+ p: "lg",
1458
+ radius: "md",
1358
1459
  style: {
1359
- width: 12,
1360
- height: 12,
1361
- borderRadius: "50%",
1362
- backgroundColor: "var(--color-primary)",
1363
- boxShadow: "0 0 8px var(--color-primary), 0 0 16px color-mix(in srgb, var(--color-primary) 50%, transparent)"
1364
- }
1365
- }
1366
- ) : void 0,
1367
- title: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1368
- /* @__PURE__ */ jsx(Text, { fw: 500, children: milestone.name }),
1369
- /* @__PURE__ */ jsx(
1370
- Badge,
1371
- {
1372
- variant: "light",
1373
- color: milestoneStatusColors[milestone.status || ""] || "gray",
1374
- size: "sm",
1375
- children: formatStatusLabel(milestone.status || "unknown")
1376
- }
1377
- ),
1378
- milestone.due_date && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1379
- "Due ",
1380
- formatDate(milestone.due_date)
1381
- ] })
1382
- ] }),
1383
- children: [
1384
- milestone.description && /* @__PURE__ */ jsx(Text, { size: "sm", mt: "xs", children: milestone.description }),
1385
- /* @__PURE__ */ jsx(MilestoneChecklist, { milestone }),
1386
- milestoneTasks.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: "xs", mt: "sm", children: milestoneTasks.map((task) => /* @__PURE__ */ jsx(Card, { withBorder: true, p: "xs", children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1387
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", children: [
1388
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: task.name }),
1389
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1390
- /* @__PURE__ */ jsx(
1391
- Badge,
1392
- {
1393
- variant: "light",
1394
- color: taskTypeColors[task.type || ""] || "gray",
1395
- size: "xs",
1396
- children: formatStatusLabel(task.type || "other")
1460
+ background,
1461
+ border: "none",
1462
+ borderTop: "1px solid var(--color-border)",
1463
+ borderRight: "1px solid var(--color-border)",
1464
+ borderBottom: "1px solid var(--color-border)",
1465
+ boxShadow: "none",
1466
+ position: "relative",
1467
+ overflow: "hidden"
1468
+ },
1469
+ children: [
1470
+ /* @__PURE__ */ jsx(
1471
+ "div",
1472
+ {
1473
+ style: {
1474
+ position: "absolute",
1475
+ inset: "0 auto 0 0",
1476
+ width: 3,
1477
+ background: `linear-gradient(180deg, ${accent} 0%, color-mix(in srgb, ${accent} 30%, transparent) 100%)`
1397
1478
  }
1398
- ),
1399
- /* @__PURE__ */ jsx(
1400
- Badge,
1479
+ }
1480
+ ),
1481
+ /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
1482
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "wrap", children: [
1483
+ /* @__PURE__ */ jsxs(Stack, { gap: 6, style: { flex: 1, minWidth: 260 }, children: [
1484
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
1485
+ /* @__PURE__ */ jsx(
1486
+ Text,
1487
+ {
1488
+ fw: 700,
1489
+ size: "lg",
1490
+ c: milestone.status === "completed" ? "var(--color-background)" : "var(--color-text)",
1491
+ children: milestone.name
1492
+ }
1493
+ ),
1494
+ /* @__PURE__ */ jsx(
1495
+ Badge,
1496
+ {
1497
+ variant: "light",
1498
+ color: milestoneStatusColors[milestone.status || ""] || "gray",
1499
+ size: "sm",
1500
+ styles: {
1501
+ root: {
1502
+ letterSpacing: "0.02em"
1503
+ }
1504
+ },
1505
+ children: formatStatusLabel(milestone.status || "unknown")
1506
+ }
1507
+ )
1508
+ ] }),
1509
+ milestone.description && /* @__PURE__ */ jsx(
1510
+ Text,
1511
+ {
1512
+ size: "sm",
1513
+ c: milestone.status === "completed" ? "color-mix(in srgb, var(--color-background) 82%, transparent)" : "var(--color-text-dimmed)",
1514
+ maw: 900,
1515
+ children: milestone.description
1516
+ }
1517
+ )
1518
+ ] }),
1519
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
1520
+ milestone.due_date && /* @__PURE__ */ jsxs(
1521
+ Badge,
1522
+ {
1523
+ variant: "outline",
1524
+ size: "md",
1525
+ styles: {
1526
+ root: {
1527
+ borderColor: "color-mix(in srgb, var(--color-primary) 18%, var(--color-border))",
1528
+ backgroundColor: "color-mix(in srgb, var(--color-primary) 5%, var(--color-surface))"
1529
+ }
1530
+ },
1531
+ children: [
1532
+ "Due ",
1533
+ formatDate(milestone.due_date)
1534
+ ]
1535
+ }
1536
+ ),
1537
+ /* @__PURE__ */ jsxs(
1538
+ Badge,
1539
+ {
1540
+ variant: "outline",
1541
+ size: "md",
1542
+ styles: {
1543
+ root: {
1544
+ borderColor: "color-mix(in srgb, var(--color-primary) 16%, var(--color-border))",
1545
+ backgroundColor: "var(--color-surface)"
1546
+ }
1547
+ },
1548
+ children: [
1549
+ completedChecklistItems,
1550
+ "/",
1551
+ checklistItems.length,
1552
+ " complete"
1553
+ ]
1554
+ }
1555
+ ),
1556
+ milestoneTasks.length > 0 && /* @__PURE__ */ jsxs(
1557
+ Badge,
1558
+ {
1559
+ variant: "outline",
1560
+ size: "md",
1561
+ styles: {
1562
+ root: {
1563
+ borderColor: "color-mix(in srgb, var(--color-primary) 16%, var(--color-border))",
1564
+ backgroundColor: "var(--color-surface)"
1565
+ }
1566
+ },
1567
+ children: [
1568
+ milestoneTasks.length,
1569
+ " tasks"
1570
+ ]
1571
+ }
1572
+ )
1573
+ ] })
1574
+ ] }),
1575
+ /* @__PURE__ */ jsx(MilestoneChecklist, { milestone }),
1576
+ milestoneTasks.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: "sm", children: milestoneTasks.map((task) => /* @__PURE__ */ jsx(
1577
+ Card,
1401
1578
  {
1402
- variant: "light",
1403
- color: taskStatusColors[task.status || ""] || "gray",
1404
- size: "xs",
1405
- children: formatStatusLabel(task.status || "pending")
1406
- }
1407
- )
1579
+ p: "sm",
1580
+ radius: "md",
1581
+ style: {
1582
+ border: "1px solid color-mix(in srgb, var(--color-primary) 12%, var(--color-border))",
1583
+ backgroundColor: "color-mix(in srgb, var(--color-surface-hover) 70%, var(--color-surface))",
1584
+ boxShadow: "var(--standard-box-shadow)"
1585
+ },
1586
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1587
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", wrap: "wrap", children: [
1588
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, c: "var(--color-text)", children: task.name }),
1589
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
1590
+ /* @__PURE__ */ jsx(
1591
+ Badge,
1592
+ {
1593
+ variant: "light",
1594
+ color: taskTypeColors[task.type || ""] || "gray",
1595
+ size: "xs",
1596
+ children: formatStatusLabel(task.type || "other")
1597
+ }
1598
+ ),
1599
+ /* @__PURE__ */ jsx(
1600
+ Badge,
1601
+ {
1602
+ variant: "light",
1603
+ color: taskStatusColors[task.status || ""] || "gray",
1604
+ size: "xs",
1605
+ children: formatStatusLabel(task.status || "pending")
1606
+ }
1607
+ )
1608
+ ] })
1609
+ ] }),
1610
+ /* @__PURE__ */ jsx(InlineResumeContextEditor, { task, projectId })
1611
+ ] })
1612
+ },
1613
+ task.id
1614
+ )) })
1408
1615
  ] })
1409
- ] }),
1410
- /* @__PURE__ */ jsx(InlineResumeContextEditor, { task, projectId })
1411
- ] }) }, task.id)) })
1412
- ]
1616
+ ]
1617
+ }
1618
+ )
1413
1619
  },
1414
1620
  milestone.id
1415
1621
  );
1416
1622
  })
1417
1623
  }
1418
1624
  ) }),
1419
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "details", pt: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
1420
- isEmpty && /* @__PURE__ */ jsx(Alert, { color: "blue", title: "Get started", children: "This project has no milestones, tasks, or notes yet. Add a milestone or create a task to begin tracking progress." }),
1421
- /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1422
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Project Details" }),
1423
- project.description && /* @__PURE__ */ jsxs("div", { children: [
1424
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Description" }),
1425
- /* @__PURE__ */ jsx(Text, { size: "sm", children: project.description })
1426
- ] }),
1427
- project.contract_value != null && /* @__PURE__ */ jsxs("div", { children: [
1428
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Contract Value" }),
1429
- /* @__PURE__ */ jsxs(Text, { size: "sm", fw: 500, children: [
1430
- "$",
1431
- project.contract_value.toLocaleString()
1432
- ] })
1433
- ] }),
1434
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: 3, children: [
1435
- /* @__PURE__ */ jsxs("div", { children: [
1436
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Start Date" }),
1437
- /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.start_date) })
1438
- ] }),
1439
- /* @__PURE__ */ jsxs("div", { children: [
1440
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Target End Date" }),
1441
- /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.target_end_date) })
1442
- ] }),
1443
- /* @__PURE__ */ jsxs("div", { children: [
1444
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Actual End Date" }),
1445
- /* @__PURE__ */ jsx(Text, { size: "sm", children: formatDate(project.actual_end_date) })
1446
- ] })
1447
- ] })
1448
- ] }) }),
1449
- project.company && /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1450
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Company" }),
1451
- /* @__PURE__ */ jsx(Text, { fw: 500, children: project.company.name }),
1452
- project.company.domain && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: project.company.domain })
1453
- ] }) })
1454
- ] }) }),
1455
1625
  /* @__PURE__ */ jsx(Tabs.Panel, { value: "notes", pt: "md", children: /* @__PURE__ */ jsx(NotesTabContent, { notes, onAddNote: () => setAddNoteOpen(true) }) }),
1456
1626
  /* @__PURE__ */ jsx(Tabs.Panel, { value: "activity", pt: "md", children: /* @__PURE__ */ jsx(ProjectActivityTimeline, { projectId }) })
1457
1627
  ] })