@burdenoff/microfe-crewfoundry 2026.704.5 → 2026.704.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"LearningCourseLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCourseLearningPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, Clock, GraduationCap, Users } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningCourseLearningPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { courses } = useCrewFoundryStore();\n\n const courseId = searchParams.get('id');\n const course = courseId ? courses.find((c) => c.id === courseId) : courses[0];\n\n if (!course) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Course not found\"\n description=\"This course is no longer available.\"\n action={\n <Button variant=\"outline\" onClick={() => navigate('../learning/courses-page')}>\n Browse courses\n </Button>\n }\n />\n </div>\n );\n }\n\n return (\n <div className=\"max-w-3xl space-y-6 p-6\">\n <div>\n <div className=\"flex items-center gap-2\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{course.title}</GradientText>\n </h1>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n <p className=\"text-sm text-text-secondary\">\n by {course.instructor} · {course.category}\n </p>\n <PagePurpose className=\"mt-1\">\n Work through a course lesson-by-lesson — track your progress and complete modules to build\n the skill at hand.\n </PagePurpose>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.modules}</p>\n <p className=\"text-xs text-text-secondary\">Modules</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"Interactive lessons are coming soon\"\n description=\"The lesson player and per-module progress tracking are being built. In the meantime you can enroll from the course page and review what this course covers.\"\n action={\n <div className=\"flex flex-wrap justify-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={() =>\n navigate(\n `../../learning/course-details-page?id=${encodeURIComponent(course.id)}`\n )\n }\n >\n <GraduationCap className=\"mr-1 h-4 w-4\" />\n Course details\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => navigate('../learning/my-learning-page')}\n >\n My learning\n </Button>\n </div>\n }\n />\n </CardContent>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,IAAiC;CAC/C,IAAM,IAAW,GAAa,EACxB,CAAC,KAAgB,GAAiB,EAClC,EAAE,eAAY,GAAqB,EAEnC,IAAW,EAAa,IAAI,KAAK,EACjC,IAAS,IAAW,EAAQ,MAAM,MAAM,EAAE,OAAO,EAAS,GAAG,EAAQ;AAmB3E,QAjBK,IAkBH,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAe,EAAO,OAAqB,CAAA;MACxC,CAAA,EACL,kBAAC,GAAD;MACE,SACE,EAAO,UAAU,aACb,cACA,EAAO,UAAU,iBACf,YACA;gBAGP,EAAgB,EAAO,MAAM;MACxB,CAAA,CACJ;;IACN,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2C;MACrC,EAAO;MAAW;MAAI,EAAO;MAC/B;;IACJ,kBAAC,GAAD;KAAa,WAAU;eAAO;KAGhB,CAAA;IACV,EAAA,CAAA;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAU,WAAU,4CAA6C,CAAA;OACjE,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAY,CAAA;OACrD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAW,CAAA;OAC1C;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAO,WAAU,4CAA6C,CAAA;OAC9D,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAa,CAAA;OACtD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA;OAC3C;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAO,WAAU,4CAA6C,CAAA;OAC9D,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAa,CAAA;OACtD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA;OAC3C;SACT,CAAA;KACH;;GAEN,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAC1C,kBAAC,GAAD;KAAa,WAAU;eACrB,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,QACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,SAAQ;QACR,eACE,EACE,yCAAyC,mBAAmB,EAAO,GAAG,GACvE;kBALL,CAQE,kBAAC,GAAD,EAAe,WAAU,gBAAiB,CAAA,EAAA,iBAEnC;WACT,kBAAC,GAAD;QACE,SAAQ;QACR,eAAe,EAAS,+BAA+B;kBACxD;QAEQ,CAAA,CACL;;MAER,CAAA;KACU,CAAA;IACJ,CAAA;GACR;MAjGJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,eAAe,EAAS,2BAA2B;cAAE;IAEtE,CAAA;GAEX,CAAA;EACE,CAAA"}
1
+ {"version":3,"file":"LearningCourseLearningPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningCourseLearningPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, Clock, GraduationCap, Users } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningCourseLearningPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { courses } = useCrewFoundryStore();\n\n const courseId = searchParams.get('id');\n const course = courseId ? courses.find((c) => c.id === courseId) : courses[0];\n\n if (!course) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Course not found\"\n description=\"This course is no longer available.\"\n action={\n <Button variant=\"outline\" onClick={() => navigate('../learning/courses-page')}>\n Browse courses\n </Button>\n }\n />\n </div>\n );\n }\n\n return (\n <div className=\"max-w-3xl space-y-6 p-6\">\n <div>\n <div className=\"flex items-center gap-2\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{course.title}</GradientText>\n </h1>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n <p className=\"text-sm text-text-secondary\">\n by {course.instructor} · {course.category}\n </p>\n <PagePurpose className=\"mt-1\">\n Work through a course lesson-by-lesson — track your progress and complete modules to build\n the skill at hand.\n </PagePurpose>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.modules}</p>\n <p className=\"text-xs text-text-secondary\">Modules</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"mx-auto mb-1 h-5 w-5 text-text-secondary\" />\n <p className=\"text-lg font-bold\">{course.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"Interactive lessons are coming soon\"\n description=\"The lesson player and per-module progress tracking are being built. In the meantime you can enroll from the course page and review what this course covers.\"\n action={\n <div className=\"flex flex-wrap justify-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={() =>\n navigate(\n `../../learning/course-details-page?id=${encodeURIComponent(course.id)}`\n )\n }\n >\n <GraduationCap className=\"mr-1 h-4 w-4\" />\n Course details\n </Button>\n <Button variant=\"outline\" onClick={() => navigate('../learning/my-learning-page')}>\n My learning\n </Button>\n </div>\n }\n />\n </CardContent>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,IAAiC;CAC/C,IAAM,IAAW,GAAa,EACxB,CAAC,KAAgB,GAAiB,EAClC,EAAE,eAAY,GAAqB,EAEnC,IAAW,EAAa,IAAI,KAAK,EACjC,IAAS,IAAW,EAAQ,MAAM,MAAM,EAAE,OAAO,EAAS,GAAG,EAAQ;AAmB3E,QAjBK,IAkBH,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAe,EAAO,OAAqB,CAAA;MACxC,CAAA,EACL,kBAAC,GAAD;MACE,SACE,EAAO,UAAU,aACb,cACA,EAAO,UAAU,iBACf,YACA;gBAGP,EAAgB,EAAO,MAAM;MACxB,CAAA,CACJ;;IACN,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2C;MACrC,EAAO;MAAW;MAAI,EAAO;MAC/B;;IACJ,kBAAC,GAAD;KAAa,WAAU;eAAO;KAGhB,CAAA;IACV,EAAA,CAAA;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAU,WAAU,4CAA6C,CAAA;OACjE,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAY,CAAA;OACrD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAW,CAAA;OAC1C;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAO,WAAU,4CAA6C,CAAA;OAC9D,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAa,CAAA;OACtD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA;OAC3C;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,GAAD,EAAO,WAAU,4CAA6C,CAAA;OAC9D,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAO;QAAa,CAAA;OACtD,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA;OAC3C;SACT,CAAA;KACH;;GAEN,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAC1C,kBAAC,GAAD;KAAa,WAAU;eACrB,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,QACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,SAAQ;QACR,eACE,EACE,yCAAyC,mBAAmB,EAAO,GAAG,GACvE;kBALL,CAQE,kBAAC,GAAD,EAAe,WAAU,gBAAiB,CAAA,EAAA,iBAEnC;WACT,kBAAC,GAAD;QAAQ,SAAQ;QAAU,eAAe,EAAS,+BAA+B;kBAAE;QAE1E,CAAA,CACL;;MAER,CAAA;KACU,CAAA;IACJ,CAAA;GACR;MA9FJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,eAAe,EAAS,2BAA2B;cAAE;IAEtE,CAAA;GAEX,CAAA;EACE,CAAA"}
@@ -4,12 +4,16 @@ import { useState as n } from "react";
4
4
  import { BookOpen as r, CheckCircle as i, Clock as a, Star as o, Users as s } from "lucide-react";
5
5
  import { useSearchParams as c } from "react-router-dom";
6
6
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
- import { Badge as d, Button as f, Card as p, CardContent as m, EmphasisPanel as h, GradientText as g, IllustratedEmptyState as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
8
- import { useGlobalUi as y } from "@burdenoff/fe-libs/shared/providers/shell";
7
+ import { Badge as d, Button as f, Card as p, CardContent as m, EmphasisPanel as h, GradientText as g, IllustratedEmptyState as _, PagePurpose as v, Spinner as y } from "@burdenoff/fe-libs/ui";
8
+ import { useGlobalUi as b } from "@burdenoff/fe-libs/shared/providers/shell";
9
9
  //#region src/crewfoundry/pages/LearningLearningPathDetailPagePage.tsx
10
- function b() {
11
- let [b] = c(), { learningPaths: x, courses: S, enrollCourse: C } = e(), { showToast: w } = y(), [T, E] = n(!1), D = b.get("id"), O = D ? x.find((e) => e.id === D) : x[0];
12
- if (!O) return /* @__PURE__ */ l("div", {
10
+ function x() {
11
+ let [x] = c(), { learningPaths: S, courses: C, enrollCourse: w, initialized: T } = e(), { showToast: E } = b(), [D, O] = n(!1), k = x.get("id"), A = k ? S.find((e) => e.id === k) : S[0];
12
+ if (!T && !A) return /* @__PURE__ */ l("div", {
13
+ className: "flex min-h-[60vh] items-center justify-center p-6",
14
+ children: /* @__PURE__ */ l(y, { size: "lg" })
15
+ });
16
+ if (!A) return /* @__PURE__ */ l("div", {
13
17
  className: "p-6",
14
18
  children: /* @__PURE__ */ l(_, {
15
19
  illustration: "empty-search",
@@ -17,7 +21,7 @@ function b() {
17
21
  description: "This learning path is no longer available."
18
22
  })
19
23
  });
20
- let k = S.filter((e) => O.courses.includes(e.id));
24
+ let j = C.filter((e) => A.courses.includes(e.id));
21
25
  return /* @__PURE__ */ u("div", {
22
26
  className: "space-y-6 p-6 max-w-4xl",
23
27
  children: [
@@ -26,11 +30,11 @@ function b() {
26
30
  children: [/* @__PURE__ */ u("div", { children: [
27
31
  /* @__PURE__ */ l("h1", {
28
32
  className: "text-2xl font-semibold",
29
- children: /* @__PURE__ */ l(g, { children: O.title })
33
+ children: /* @__PURE__ */ l(g, { children: A.title })
30
34
  }),
31
35
  /* @__PURE__ */ l("p", {
32
36
  className: "text-sm text-text-secondary",
33
- children: O.description
37
+ children: A.description
34
38
  }),
35
39
  /* @__PURE__ */ l(v, {
36
40
  className: "mt-1",
@@ -38,22 +42,22 @@ function b() {
38
42
  })
39
43
  ] }), /* @__PURE__ */ l(f, {
40
44
  onClick: async () => {
41
- if (k.length === 0) {
42
- w("No courses in this path yet", "warning");
45
+ if (j.length === 0) {
46
+ E("No courses in this path yet", "warning");
43
47
  return;
44
48
  }
45
- E(!0);
49
+ O(!0);
46
50
  try {
47
- for (let e of k) await C(e.id);
48
- w(`Enrolled in ${k.length} course${k.length > 1 ? "s" : ""}`, "success");
51
+ for (let e of j) await w(e.id);
52
+ E(`Enrolled in ${j.length} course${j.length > 1 ? "s" : ""}`, "success");
49
53
  } catch (e) {
50
- w(e instanceof Error ? e.message : "Unable to enroll in path", "error");
54
+ E(e instanceof Error ? e.message : "Unable to enroll in path", "error");
51
55
  } finally {
52
- E(!1);
56
+ O(!1);
53
57
  }
54
58
  },
55
- disabled: T,
56
- children: T ? "Enrolling…" : "Enroll Now"
59
+ disabled: D,
60
+ children: D ? "Enrolling…" : "Enroll Now"
57
61
  })]
58
62
  }),
59
63
  /* @__PURE__ */ u("div", {
@@ -65,7 +69,7 @@ function b() {
65
69
  /* @__PURE__ */ l(r, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
66
70
  /* @__PURE__ */ l("p", {
67
71
  className: "text-lg font-bold",
68
- children: O.courses.length
72
+ children: A.courses.length
69
73
  }),
70
74
  /* @__PURE__ */ l("p", {
71
75
  className: "text-xs text-text-secondary",
@@ -79,7 +83,7 @@ function b() {
79
83
  /* @__PURE__ */ l(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
80
84
  /* @__PURE__ */ l("p", {
81
85
  className: "text-lg font-bold",
82
- children: O.duration
86
+ children: A.duration
83
87
  }),
84
88
  /* @__PURE__ */ l("p", {
85
89
  className: "text-xs text-text-secondary",
@@ -93,7 +97,7 @@ function b() {
93
97
  /* @__PURE__ */ l(s, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
94
98
  /* @__PURE__ */ l("p", {
95
99
  className: "text-lg font-bold",
96
- children: O.enrolled
100
+ children: A.enrolled
97
101
  }),
98
102
  /* @__PURE__ */ l("p", {
99
103
  className: "text-xs text-text-secondary",
@@ -107,7 +111,7 @@ function b() {
107
111
  /* @__PURE__ */ l(i, { className: "h-5 w-5 mx-auto text-status-success-text mb-1" }),
108
112
  /* @__PURE__ */ u("p", {
109
113
  className: "text-lg font-bold",
110
- children: [O.completionRate, "%"]
114
+ children: [A.completionRate, "%"]
111
115
  }),
112
116
  /* @__PURE__ */ l("p", {
113
117
  className: "text-xs text-text-secondary",
@@ -125,18 +129,18 @@ function b() {
125
129
  /* @__PURE__ */ u("p", {
126
130
  className: "mb-4 text-sm text-text-secondary",
127
131
  children: [
128
- k.length,
132
+ j.length,
129
133
  " courses · ",
130
- O.level
134
+ A.level
131
135
  ]
132
136
  }),
133
137
  /* @__PURE__ */ l("div", {
134
138
  className: "space-y-3",
135
- children: k.length === 0 ? /* @__PURE__ */ l(_, {
139
+ children: j.length === 0 ? /* @__PURE__ */ l(_, {
136
140
  illustration: "empty-generic",
137
141
  title: "No courses in this path yet",
138
142
  description: "Courses added to this path will appear here in order."
139
- }) : k.map((e, n) => /* @__PURE__ */ u("div", {
143
+ }) : j.map((e, n) => /* @__PURE__ */ u("div", {
140
144
  className: "flex items-center gap-3 rounded border p-4",
141
145
  children: [
142
146
  /* @__PURE__ */ l("div", {
@@ -182,6 +186,6 @@ function b() {
182
186
  });
183
187
  }
184
188
  //#endregion
185
- export { b as LearningLearningPathDetailPagePage };
189
+ export { x as LearningLearningPathDetailPagePage };
186
190
 
187
191
  //# sourceMappingURL=LearningLearningPathDetailPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LearningLearningPathDetailPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathDetailPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, CheckCircle, Clock, Star, Users } from 'lucide-react';\nimport { useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningLearningPathDetailPagePage() {\n const [searchParams] = useSearchParams();\n const { learningPaths, courses, enrollCourse } = useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [enrolling, setEnrolling] = useState(false);\n const pathId = searchParams.get('id');\n const path = pathId ? learningPaths.find((p) => p.id === pathId) : learningPaths[0];\n if (!path)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No learning path found\"\n description=\"This learning path is no longer available.\"\n />\n </div>\n );\n const pathCourses = courses.filter((c) => path.courses.includes(c.id));\n\n const handleEnroll = async () => {\n if (pathCourses.length === 0) {\n showToast('No courses in this path yet', 'warning');\n return;\n }\n setEnrolling(true);\n try {\n for (const course of pathCourses) {\n await enrollCourse(course.id);\n }\n showToast(\n `Enrolled in ${pathCourses.length} course${pathCourses.length > 1 ? 's' : ''}`,\n 'success'\n );\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to enroll in path', 'error');\n } finally {\n setEnrolling(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{path.title}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{path.description}</p>\n <PagePurpose className=\"mt-1\">\n Follow a single learning path end-to-end — see its courses, your progress, and what to\n complete next to finish the journey.\n </PagePurpose>\n </div>\n <Button onClick={handleEnroll} disabled={enrolling}>\n {enrolling ? 'Enrolling…' : 'Enroll Now'}\n </Button>\n </div>\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.courses.length}</p>\n <p className=\"text-xs text-text-secondary\">Courses</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <CheckCircle className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">{path.completionRate}%</p>\n <p className=\"text-xs text-text-secondary\">Completion</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"text-lg font-semibold\">Courses in this Path</div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n {pathCourses.length} courses · {path.level}\n </p>\n <div className=\"space-y-3\">\n {pathCourses.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No courses in this path yet\"\n description=\"Courses added to this path will appear here in order.\"\n />\n ) : (\n pathCourses.map((course, idx) => (\n <div key={course.id} className=\"flex items-center gap-3 rounded border p-4\">\n <div className=\"flex-shrink-0 w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-bold\">\n {idx + 1}\n </div>\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · {course.duration} · {course.modules} modules\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n </div>\n ))\n )}\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LearningLearningPathDetailPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/LearningLearningPathDetailPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Spinner,\n} from '@burdenoff/fe-libs/ui';\nimport { BookOpen, CheckCircle, Clock, Star, Users } from 'lucide-react';\nimport { useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function LearningLearningPathDetailPagePage() {\n const [searchParams] = useSearchParams();\n const { learningPaths, courses, enrollCourse, initialized } = useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [enrolling, setEnrolling] = useState(false);\n const pathId = searchParams.get('id');\n const path = pathId ? learningPaths.find((p) => p.id === pathId) : learningPaths[0];\n if (!initialized && !path) {\n return (\n <div className=\"flex min-h-[60vh] items-center justify-center p-6\">\n <Spinner size=\"lg\" />\n </div>\n );\n }\n\n if (!path)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No learning path found\"\n description=\"This learning path is no longer available.\"\n />\n </div>\n );\n const pathCourses = courses.filter((c) => path.courses.includes(c.id));\n\n const handleEnroll = async () => {\n if (pathCourses.length === 0) {\n showToast('No courses in this path yet', 'warning');\n return;\n }\n setEnrolling(true);\n try {\n for (const course of pathCourses) {\n await enrollCourse(course.id);\n }\n showToast(\n `Enrolled in ${pathCourses.length} course${pathCourses.length > 1 ? 's' : ''}`,\n 'success'\n );\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to enroll in path', 'error');\n } finally {\n setEnrolling(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{path.title}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{path.description}</p>\n <PagePurpose className=\"mt-1\">\n Follow a single learning path end-to-end — see its courses, your progress, and what to\n complete next to finish the journey.\n </PagePurpose>\n </div>\n <Button onClick={handleEnroll} disabled={enrolling}>\n {enrolling ? 'Enrolling…' : 'Enroll Now'}\n </Button>\n </div>\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <BookOpen className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.courses.length}</p>\n <p className=\"text-xs text-text-secondary\">Courses</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Clock className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.duration}</p>\n <p className=\"text-xs text-text-secondary\">Duration</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{path.enrolled}</p>\n <p className=\"text-xs text-text-secondary\">Enrolled</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <CheckCircle className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">{path.completionRate}%</p>\n <p className=\"text-xs text-text-secondary\">Completion</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"text-lg font-semibold\">Courses in this Path</div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n {pathCourses.length} courses · {path.level}\n </p>\n <div className=\"space-y-3\">\n {pathCourses.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No courses in this path yet\"\n description=\"Courses added to this path will appear here in order.\"\n />\n ) : (\n pathCourses.map((course, idx) => (\n <div key={course.id} className=\"flex items-center gap-3 rounded border p-4\">\n <div className=\"flex-shrink-0 w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-bold\">\n {idx + 1}\n </div>\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{course.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {course.instructor} · {course.duration} · {course.modules} modules\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm\">{course.rating}</span>\n </div>\n <Badge\n variant={\n course.level === 'beginner'\n ? 'secondary'\n : course.level === 'intermediate'\n ? 'default'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {formatEnumLabel(course.level)}\n </Badge>\n </div>\n </div>\n ))\n )}\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceFreelancerProfilePageEnhancedPage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n Separator,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n MessageSquare,\n Star,\n TrendingUp,\n Video,\n} from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst initialsOf = (name: string): string =>\n name\n .split(' ')\n .map((part) => part[0] ?? '')\n .join('')\n .slice(0, 2)\n .toUpperCase() || '—';\n\nexport function MarketplaceFreelancerProfilePageEnhancedPage() {\n const [selectedTab, setSelectedTab] = useState('overview');\n const navigate = useNavigate();\n const location = useLocation();\n const { marketplaceServices } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n\n const baseService =\n marketplaceServices.find((service) => service.id === selectedId) ?? marketplaceServices[0];\n const providerName = baseService?.provider ?? '';\n\n const providerServices = useMemo(\n () => marketplaceServices.filter((service) => service.provider === providerName),\n [marketplaceServices, providerName]\n );\n\n const skills = useMemo(\n () => Array.from(new Set(providerServices.flatMap((service) => service.skills))).slice(0, 20),\n [providerServices]\n );\n\n const categories = useMemo(\n () => Array.from(new Set(providerServices.map((service) => service.category))),\n [providerServices]\n );\n\n const services = useMemo(\n () =>\n providerServices.map((service) => ({\n id: service.id,\n title: service.title,\n price:\n service.priceType === 'hourly'\n ? `$${service.price}/hr`\n : service.priceType === 'monthly'\n ? `$${service.price}/mo`\n : `$${service.price}`,\n type: service.priceType,\n description: service.description,\n delivery: service.deliveryTime,\n rating: service.rating,\n reviews: service.reviews,\n })),\n [providerServices]\n );\n\n const avgRating =\n providerServices.length > 0\n ? (\n providerServices.reduce((sum, service) => sum + service.rating, 0) /\n providerServices.length\n ).toFixed(1)\n : '0.0';\n const totalReviews = providerServices.reduce((sum, service) => sum + service.reviews, 0);\n const startingRate =\n providerServices.length > 0 ? Math.min(...providerServices.map((service) => service.price)) : 0;\n const isTopRated = Number(avgRating) >= 4.5 && totalReviews > 0;\n\n const stats = [\n { label: 'Services', value: `${providerServices.length}` },\n { label: 'Avg Rating', value: avgRating },\n { label: 'Total Reviews', value: `${totalReviews}` },\n { label: 'Starting Rate', value: `$${startingRate.toLocaleString()}` },\n ];\n\n if (!baseService) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Provider not found\"\n description=\"This freelancer is no longer available on the marketplace.\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start gap-6\">\n <div className=\"flex h-24 w-24 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-primary to-primary/60 text-action-primary-text text-3xl font-semibold\">\n {initialsOf(providerName)}\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{providerName}</GradientText>\n </h1>\n {isTopRated ? <Badge>Top Rated</Badge> : null}\n </div>\n <p className=\"text-sm font-medium\">\n {categories.length > 0 ? categories.join(' · ') : 'Marketplace provider'}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" /> {avgRating} ({totalReviews}{' '}\n reviews)\n </span>\n <span className=\"flex items-center gap-1\">\n <Briefcase className=\"h-3 w-3\" /> {providerServices.length} services\n </span>\n <span className=\"flex items-center gap-1\">\n <DollarSign className=\"h-3 w-3\" /> from ${startingRate.toLocaleString()}\n </span>\n </div>\n <div className=\"flex gap-2 pt-2 flex-wrap\">\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Send Proposal\n </Button>\n {/* No video-intro/call surface exists yet — honest disabled control. */}\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled\n title=\"Video intro is coming soon\"\n aria-label=\"Video intro — coming soon\"\n >\n <Video className=\"h-3 w-3 mr-1\" /> Video Intro · Coming soon\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSelectedTab('availability')}>\n <Calendar className=\"h-3 w-3 mr-1\" /> Schedule Call\n </Button>\n </div>\n <PagePurpose className=\"pt-2\">\n A freelancer&apos;s full profile — skills, listed services, and performance — so you\n can vet them thoroughly and decide whether to hire before you reach out.\n </PagePurpose>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n\n <NextSteps\n storageKey=\"crewfoundry-freelancer-profile-enhanced\"\n steps={[\n {\n id: 'services',\n label: 'Review their services',\n description: 'See exactly what this freelancer offers and at what price.',\n icon: <Briefcase className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('services'),\n },\n {\n id: 'availability',\n label: 'Check availability',\n description: 'Find open slots before you schedule a call.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('availability'),\n },\n {\n id: 'performance',\n label: 'Inspect performance',\n description: 'Look at ratings and delivery history to reduce risk.',\n icon: <TrendingUp className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('analytics'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {stats.map((stat) => (\n <Card key={stat.label}>\n <CardContent className=\"pt-6\">\n <p className=\"text-xs text-text-secondary\">{stat.label}</p>\n <p className=\"text-lg font-bold\">{stat.value}</p>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <Tabs value={selectedTab} onValueChange={setSelectedTab}>\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"services\">Services</TabsTrigger>\n <TabsTrigger value=\"availability\">Availability</TabsTrigger>\n <TabsTrigger value=\"analytics\">Performance</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"space-y-6 mt-4\">\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Summary</CardTitle>\n </CardHeader>\n <CardContent className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {providerName} offers {providerServices.length}{' '}\n {providerServices.length === 1 ? 'service' : 'services'} on the marketplace\n {categories.length > 0 ? ` across ${categories.join(', ')}` : ''}.\n </p>\n <p>\n Across all listings the provider holds an average rating of {avgRating} from{' '}\n {totalReviews} reviews, with rates starting at ${startingRate.toLocaleString()}.\n </p>\n </CardContent>\n </Card>\n </div>\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Expertise Areas</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {skills.length > 0 ? (\n skills.map((s) => (\n <Badge key={s} variant=\"secondary\" className=\"text-xs\">\n {s}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No skills listed yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"services\" className=\"mt-4\">\n {services.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2\">\n {services.map((svc) => (\n <Card key={svc.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-sm\">{svc.title}</CardTitle>\n <Badge variant=\"outline\" className=\"text-xs\">\n {formatEnumLabel(svc.type)}\n </Badge>\n </div>\n <CardDescription className=\"text-xs\">{svc.description}</CardDescription>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <Separator className=\"mb-3\" />\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <p className=\"text-sm font-semibold\">{svc.price}</p>\n <p className=\"text-[10px] text-text-secondary\">Delivery: {svc.delivery}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() =>\n navigate(`../marketplace/service-details-page?id=${svc.id}`)\n }\n >\n View\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No services listed\"\n description=\"This provider has not published any services yet.\"\n />\n )}\n </TabsContent>\n\n <TabsContent value=\"availability\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Availability</CardTitle>\n <CardDescription>Real-time scheduling with this provider</CardDescription>\n </CardHeader>\n <CardContent>\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"Scheduling is coming soon\"\n description=\"Live availability and consultation booking will appear here once the scheduling backend ships. In the meantime, send a message to arrange a time.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Message provider\n </Button>\n }\n />\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"analytics\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Service Performance</CardTitle>\n <CardDescription>Ratings and reviews per listed service</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {providerServices.length > 0 ? (\n providerServices.map((service) => (\n <div key={service.id} className=\"flex items-center justify-between\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium truncate\">{service.title}</p>\n <p className=\"text-xs text-text-secondary\">{service.category}</p>\n </div>\n <div className=\"flex items-center gap-2 text-sm shrink-0\">\n <Star className=\"h-3.5 w-3.5 text-status-warning-text\" />\n <span className=\"font-semibold\">{service.rating}</span>\n <span className=\"text-xs text-text-secondary\">({service.reviews})</span>\n </div>\n </div>\n ))\n ) : (\n <p className=\"text-sm text-text-secondary\">No performance data yet.</p>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MarketplaceFreelancerProfilePageEnhancedPage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n Separator,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n MessageSquare,\n Star,\n TrendingUp,\n Video,\n} from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst initialsOf = (name: string): string =>\n name\n .split(' ')\n .map((part) => part[0] ?? '')\n .join('')\n .slice(0, 2)\n .toUpperCase() || '—';\n\nexport function MarketplaceFreelancerProfilePageEnhancedPage() {\n const [selectedTab, setSelectedTab] = useState('overview');\n const navigate = useNavigate();\n const location = useLocation();\n const { marketplaceServices } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n\n const baseService =\n marketplaceServices.find((service) => service.id === selectedId) ?? marketplaceServices[0];\n const providerName = baseService?.provider ?? '';\n\n const providerServices = useMemo(\n () => marketplaceServices.filter((service) => service.provider === providerName),\n [marketplaceServices, providerName]\n );\n\n const skills = useMemo(\n () => Array.from(new Set(providerServices.flatMap((service) => service.skills))).slice(0, 20),\n [providerServices]\n );\n\n const categories = useMemo(\n () => Array.from(new Set(providerServices.map((service) => service.category))),\n [providerServices]\n );\n\n const services = useMemo(\n () =>\n providerServices.map((service) => ({\n id: service.id,\n title: service.title,\n price:\n service.priceType === 'hourly'\n ? `$${service.price}/hr`\n : service.priceType === 'monthly'\n ? `$${service.price}/mo`\n : `$${service.price}`,\n type: service.priceType,\n description: service.description,\n delivery: service.deliveryTime,\n rating: service.rating,\n reviews: service.reviews,\n })),\n [providerServices]\n );\n\n const avgRating =\n providerServices.length > 0\n ? (\n providerServices.reduce((sum, service) => sum + service.rating, 0) /\n providerServices.length\n ).toFixed(1)\n : '0.0';\n const totalReviews = providerServices.reduce((sum, service) => sum + service.reviews, 0);\n const startingRate =\n providerServices.length > 0 ? Math.min(...providerServices.map((service) => service.price)) : 0;\n const isTopRated = Number(avgRating) >= 4.5 && totalReviews > 0;\n\n const stats = [\n { label: 'Services', value: `${providerServices.length}` },\n { label: 'Avg Rating', value: avgRating },\n { label: 'Total Reviews', value: `${totalReviews}` },\n { label: 'Starting Rate', value: `$${startingRate.toLocaleString()}` },\n ];\n\n if (!baseService) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Provider not found\"\n description=\"This freelancer is no longer available on the marketplace.\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start gap-6\">\n <div className=\"flex h-24 w-24 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-primary to-primary/60 text-action-primary-text text-3xl font-semibold\">\n {initialsOf(providerName)}\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{providerName}</GradientText>\n </h1>\n {isTopRated ? <Badge>Top Rated</Badge> : null}\n </div>\n <p className=\"text-sm font-medium\">\n {categories.length > 0 ? categories.join(' · ') : 'Marketplace provider'}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" /> {avgRating} ({totalReviews}{' '}\n reviews)\n </span>\n <span className=\"flex items-center gap-1\">\n <Briefcase className=\"h-3 w-3\" /> {providerServices.length} services\n </span>\n <span className=\"flex items-center gap-1\">\n <DollarSign className=\"h-3 w-3\" /> from ${startingRate.toLocaleString()}\n </span>\n </div>\n <div className=\"flex gap-2 pt-2 flex-wrap\">\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Send Proposal\n </Button>\n {/* No video-intro/call surface exists yet — honest disabled control. */}\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled\n title=\"Video intro is coming soon\"\n aria-label=\"Video intro — coming soon\"\n >\n <Video className=\"h-3 w-3 mr-1\" /> Video Intro · Coming soon\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSelectedTab('availability')}>\n <Calendar className=\"h-3 w-3 mr-1\" /> Schedule Call\n </Button>\n </div>\n <PagePurpose className=\"pt-2\">\n A freelancer&apos;s full profile — skills, listed services, and performance — so you\n can vet them thoroughly and decide whether to hire before you reach out.\n </PagePurpose>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n\n <NextSteps\n storageKey=\"crewfoundry-freelancer-profile-enhanced\"\n steps={[\n {\n id: 'services',\n label: 'Review their services',\n description: 'See exactly what this freelancer offers and at what price.',\n icon: <Briefcase className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('services'),\n },\n {\n id: 'availability',\n label: 'Check availability',\n description: 'Find open slots before you schedule a call.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('availability'),\n },\n {\n id: 'performance',\n label: 'Inspect performance',\n description: 'Look at ratings and delivery history to reduce risk.',\n icon: <TrendingUp className=\"h-4 w-4\" />,\n onClick: () => setSelectedTab('analytics'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {stats.map((stat) => (\n <Card key={stat.label}>\n <CardContent className=\"pt-6\">\n <p className=\"text-xs text-text-secondary\">{stat.label}</p>\n <p className=\"text-lg font-bold\">{stat.value}</p>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <Tabs value={selectedTab} onValueChange={setSelectedTab}>\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"services\">Services</TabsTrigger>\n <TabsTrigger value=\"availability\">Availability</TabsTrigger>\n <TabsTrigger value=\"analytics\">Performance</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"space-y-6 mt-4\">\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Summary</CardTitle>\n </CardHeader>\n <CardContent className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {providerName} offers {providerServices.length}{' '}\n {providerServices.length === 1 ? 'service' : 'services'} on the marketplace\n {categories.length > 0 ? ` across ${categories.join(', ')}` : ''}.\n </p>\n <p>\n Across all listings the provider holds an average rating of {avgRating} from{' '}\n {totalReviews} reviews, with rates starting at ${startingRate.toLocaleString()}.\n </p>\n </CardContent>\n </Card>\n </div>\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Expertise Areas</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {skills.length > 0 ? (\n skills.map((s) => (\n <Badge key={s} variant=\"secondary\" className=\"text-xs\">\n {s}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No skills listed yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"services\" className=\"mt-4\">\n {services.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2\">\n {services.map((svc) => (\n <Card key={svc.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-sm\">{svc.title}</CardTitle>\n <Badge variant=\"outline\" className=\"text-xs\">\n {formatEnumLabel(svc.type)}\n </Badge>\n </div>\n <CardDescription className=\"text-xs\">{svc.description}</CardDescription>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <Separator className=\"mb-3\" />\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <p className=\"text-sm font-semibold\">{svc.price}</p>\n <p className=\"text-[10px] text-text-secondary\">Delivery: {svc.delivery}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigate(`../marketplace/service-details-page?id=${svc.id}`)}\n >\n View\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No services listed\"\n description=\"This provider has not published any services yet.\"\n />\n )}\n </TabsContent>\n\n <TabsContent value=\"availability\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Availability</CardTitle>\n <CardDescription>Real-time scheduling with this provider</CardDescription>\n </CardHeader>\n <CardContent>\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"Scheduling is coming soon\"\n description=\"Live availability and consultation booking will appear here once the scheduling backend ships. In the meantime, send a message to arrange a time.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Message provider\n </Button>\n }\n />\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"analytics\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Service Performance</CardTitle>\n <CardDescription>Ratings and reviews per listed service</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {providerServices.length > 0 ? (\n providerServices.map((service) => (\n <div key={service.id} className=\"flex items-center justify-between\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium truncate\">{service.title}</p>\n <p className=\"text-xs text-text-secondary\">{service.category}</p>\n </div>\n <div className=\"flex items-center gap-2 text-sm shrink-0\">\n <Star className=\"h-3.5 w-3.5 text-status-warning-text\" />\n <span className=\"font-semibold\">{service.rating}</span>\n <span className=\"text-xs text-text-secondary\">({service.reviews})</span>\n </div>\n </div>\n ))\n ) : (\n <p className=\"text-sm text-text-secondary\">No performance data yet.</p>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceFreelancerProfilePagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, Briefcase, DollarSign, MessageSquare, Star } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nconst initialsOf = (name: string): string =>\n name\n .split(' ')\n .map((part) => part[0] ?? '')\n .join('')\n .slice(0, 2)\n .toUpperCase() || '—';\n\nexport function MarketplaceFreelancerProfilePagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { marketplaceServices } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n\n const baseService =\n marketplaceServices.find((service) => service.id === selectedId) ?? marketplaceServices[0];\n const providerName = baseService?.provider ?? '';\n\n const providerServices = useMemo(\n () => marketplaceServices.filter((service) => service.provider === providerName),\n [marketplaceServices, providerName]\n );\n\n const skills = useMemo(\n () => Array.from(new Set(providerServices.flatMap((service) => service.skills))).slice(0, 20),\n [providerServices]\n );\n\n const categories = useMemo(\n () => Array.from(new Set(providerServices.map((service) => service.category))),\n [providerServices]\n );\n\n const avgRating =\n providerServices.length > 0\n ? (\n providerServices.reduce((sum, service) => sum + service.rating, 0) /\n providerServices.length\n ).toFixed(1)\n : '0.0';\n const totalReviews = providerServices.reduce((sum, service) => sum + service.reviews, 0);\n const startingRate =\n providerServices.length > 0 ? Math.min(...providerServices.map((service) => service.price)) : 0;\n const isTopRated = Number(avgRating) >= 4.5 && totalReviews > 0;\n\n if (!baseService) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Provider not found\"\n description=\"This freelancer is no longer available on the marketplace.\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start gap-6\">\n <div className=\"flex h-20 w-20 shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text text-2xl font-semibold\">\n {initialsOf(providerName)}\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{providerName}</GradientText>\n </h1>\n {isTopRated ? <Badge>Top Rated</Badge> : null}\n </div>\n <p className=\"text-sm text-text-secondary\">\n {categories.length > 0 ? `Provider · ${categories.join(', ')}` : 'Marketplace provider'}\n </p>\n <PagePurpose className=\"mt-1\">\n Review a freelancer&apos;s full profile — skills, listed services, and ratings — to\n decide if they&apos;re the right fit before you hire.\n </PagePurpose>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" /> {avgRating} ({totalReviews}{' '}\n reviews)\n </span>\n <span className=\"flex items-center gap-1\">\n <Briefcase className=\"h-3 w-3\" /> {providerServices.length} services\n </span>\n </div>\n <div className=\"flex gap-2 pt-1\">\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Message\n </Button>\n {/* No consultation-booking mutation exists yet — honest disabled control. */}\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled\n title=\"Consultation booking is coming soon\"\n aria-label=\"Book consultation — coming soon\"\n >\n Book Consultation · Coming soon\n </Button>\n </div>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {[\n {\n icon: Briefcase,\n label: 'Services',\n value: `${providerServices.length}`,\n color: 'text-status-info-text',\n },\n {\n icon: Star,\n label: 'Avg Rating',\n value: `${avgRating}`,\n color: 'text-status-warning-text',\n },\n {\n icon: Award,\n label: 'Total Reviews',\n value: `${totalReviews}`,\n color: 'text-status-success-text',\n },\n {\n icon: DollarSign,\n label: 'Starting Rate',\n value: `$${startingRate.toLocaleString()}`,\n color: 'text-action-primary-bg',\n },\n ].map((stat) => (\n <Card key={stat.label}>\n <CardContent className=\"flex items-center gap-3 pt-6\">\n <stat.icon className={`h-5 w-5 ${stat.color}`} />\n <div>\n <p className=\"text-xs text-text-secondary\">{stat.label}</p>\n <p className=\"text-lg font-bold\">{stat.value}</p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n <EmphasisPanel>\n <div className=\"mb-2 text-base font-semibold\">Overview</div>\n <p className=\"text-sm text-text-secondary\">\n {providerName} offers {providerServices.length}{' '}\n {providerServices.length === 1 ? 'service' : 'services'} on the marketplace\n {categories.length > 0 ? ` across ${categories.join(', ')}` : ''}, with an average\n rating of {avgRating} from {totalReviews} reviews.\n </p>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Listed Services</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {providerServices.map((service) => (\n <button\n key={service.id}\n type=\"button\"\n onClick={() =>\n navigate(`../marketplace/service-details-page?id=${service.id}`)\n }\n className=\"w-full rounded-lg border p-4 space-y-2 text-left hover:bg-bg-sunken/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-sm\">{service.title}</p>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {service.deliveryTime}\n </Badge>\n </div>\n <p className=\"text-xs text-text-secondary\">{service.description}</p>\n <div className=\"flex items-center gap-3 text-xs\">\n <span className=\"font-medium\">\n ${service.price.toLocaleString()}/{service.priceType}\n </span>\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {service.rating} ({service.reviews})\n </span>\n </div>\n </button>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Skills &amp; Expertise</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {skills.length > 0 ? (\n skills.map((skill) => (\n <Badge key={skill} variant=\"secondary\" className=\"text-xs\">\n {skill}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No skills listed yet.</p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Service Categories</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {categories.length > 0 ? (\n categories.map((category) => (\n <Badge key={category} variant=\"outline\" className=\"text-xs\">\n {category}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No categories listed yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MarketplaceFreelancerProfilePagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Award, Briefcase, DollarSign, MessageSquare, Star } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nconst initialsOf = (name: string): string =>\n name\n .split(' ')\n .map((part) => part[0] ?? '')\n .join('')\n .slice(0, 2)\n .toUpperCase() || '—';\n\nexport function MarketplaceFreelancerProfilePagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { marketplaceServices } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n\n const baseService =\n marketplaceServices.find((service) => service.id === selectedId) ?? marketplaceServices[0];\n const providerName = baseService?.provider ?? '';\n\n const providerServices = useMemo(\n () => marketplaceServices.filter((service) => service.provider === providerName),\n [marketplaceServices, providerName]\n );\n\n const skills = useMemo(\n () => Array.from(new Set(providerServices.flatMap((service) => service.skills))).slice(0, 20),\n [providerServices]\n );\n\n const categories = useMemo(\n () => Array.from(new Set(providerServices.map((service) => service.category))),\n [providerServices]\n );\n\n const avgRating =\n providerServices.length > 0\n ? (\n providerServices.reduce((sum, service) => sum + service.rating, 0) /\n providerServices.length\n ).toFixed(1)\n : '0.0';\n const totalReviews = providerServices.reduce((sum, service) => sum + service.reviews, 0);\n const startingRate =\n providerServices.length > 0 ? Math.min(...providerServices.map((service) => service.price)) : 0;\n const isTopRated = Number(avgRating) >= 4.5 && totalReviews > 0;\n\n if (!baseService) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Provider not found\"\n description=\"This freelancer is no longer available on the marketplace.\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start gap-6\">\n <div className=\"flex h-20 w-20 shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text text-2xl font-semibold\">\n {initialsOf(providerName)}\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{providerName}</GradientText>\n </h1>\n {isTopRated ? <Badge>Top Rated</Badge> : null}\n </div>\n <p className=\"text-sm text-text-secondary\">\n {categories.length > 0 ? `Provider · ${categories.join(', ')}` : 'Marketplace provider'}\n </p>\n <PagePurpose className=\"mt-1\">\n Review a freelancer&apos;s full profile — skills, listed services, and ratings — to\n decide if they&apos;re the right fit before you hire.\n </PagePurpose>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" /> {avgRating} ({totalReviews}{' '}\n reviews)\n </span>\n <span className=\"flex items-center gap-1\">\n <Briefcase className=\"h-3 w-3\" /> {providerServices.length} services\n </span>\n </div>\n <div className=\"flex gap-2 pt-1\">\n <Button size=\"sm\" onClick={() => navigate('../marketplace/messaging-page')}>\n <MessageSquare className=\"h-3 w-3 mr-1\" /> Message\n </Button>\n {/* No consultation-booking mutation exists yet — honest disabled control. */}\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled\n title=\"Consultation booking is coming soon\"\n aria-label=\"Book consultation — coming soon\"\n >\n Book Consultation · Coming soon\n </Button>\n </div>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {[\n {\n icon: Briefcase,\n label: 'Services',\n value: `${providerServices.length}`,\n color: 'text-status-info-text',\n },\n {\n icon: Star,\n label: 'Avg Rating',\n value: `${avgRating}`,\n color: 'text-status-warning-text',\n },\n {\n icon: Award,\n label: 'Total Reviews',\n value: `${totalReviews}`,\n color: 'text-status-success-text',\n },\n {\n icon: DollarSign,\n label: 'Starting Rate',\n value: `$${startingRate.toLocaleString()}`,\n color: 'text-action-primary-bg',\n },\n ].map((stat) => (\n <Card key={stat.label}>\n <CardContent className=\"flex items-center gap-3 pt-6\">\n <stat.icon className={`h-5 w-5 ${stat.color}`} />\n <div>\n <p className=\"text-xs text-text-secondary\">{stat.label}</p>\n <p className=\"text-lg font-bold\">{stat.value}</p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n <EmphasisPanel>\n <div className=\"mb-2 text-base font-semibold\">Overview</div>\n <p className=\"text-sm text-text-secondary\">\n {providerName} offers {providerServices.length}{' '}\n {providerServices.length === 1 ? 'service' : 'services'} on the marketplace\n {categories.length > 0 ? ` across ${categories.join(', ')}` : ''}, with an average\n rating of {avgRating} from {totalReviews} reviews.\n </p>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Listed Services</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {providerServices.map((service) => (\n <button\n key={service.id}\n type=\"button\"\n onClick={() => navigate(`../marketplace/service-details-page?id=${service.id}`)}\n className=\"w-full rounded-lg border p-4 space-y-2 text-left hover:bg-bg-sunken/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-sm\">{service.title}</p>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {service.deliveryTime}\n </Badge>\n </div>\n <p className=\"text-xs text-text-secondary\">{service.description}</p>\n <div className=\"flex items-center gap-3 text-xs\">\n <span className=\"font-medium\">\n ${service.price.toLocaleString()}/{service.priceType}\n </span>\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {service.rating} ({service.reviews})\n </span>\n </div>\n </button>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Skills &amp; Expertise</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {skills.length > 0 ? (\n skills.map((skill) => (\n <Badge key={skill} variant=\"secondary\" className=\"text-xs\">\n {skill}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No skills listed yet.</p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Service Categories</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1.5\">\n {categories.length > 0 ? (\n categories.map((category) => (\n <Badge key={category} variant=\"outline\" className=\"text-xs\">\n {category}\n </Badge>\n ))\n ) : (\n <p className=\"text-xs text-text-secondary\">No categories listed yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -3,11 +3,14 @@ import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
3
3
  import { Calendar as n, DollarSign as r, MessageSquare as i, Users as a } from "lucide-react";
4
4
  import { useLocation as o, useNavigate as s } from "react-router-dom";
5
5
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
- import { Badge as u, Card as d, CardContent as f, EmphasisPanel as p, GradientText as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
6
+ import { Badge as u, Card as d, CardContent as f, EmphasisPanel as p, GradientText as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _, Spinner as v } from "@burdenoff/fe-libs/ui";
7
7
  //#region src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx
8
- function v() {
9
- let v = s(), y = o(), { projects: b } = e(), x = new URLSearchParams(y.search).get("id"), S = b.find((e) => e.id === x) ?? b[0];
10
- return S ? /* @__PURE__ */ l("div", {
8
+ function y() {
9
+ let y = s(), b = o(), { projects: x, initialized: S } = e(), C = new URLSearchParams(b.search).get("id"), w = x.find((e) => e.id === C) ?? x[0];
10
+ return !S && !w ? /* @__PURE__ */ c("div", {
11
+ className: "flex min-h-[60vh] items-center justify-center p-6",
12
+ children: /* @__PURE__ */ c(v, { size: "lg" })
13
+ }) : w ? /* @__PURE__ */ l("div", {
11
14
  className: "space-y-6 p-6 max-w-4xl",
12
15
  children: [
13
16
  /* @__PURE__ */ l("div", {
@@ -15,19 +18,19 @@ function v() {
15
18
  children: [/* @__PURE__ */ l("div", { children: [
16
19
  /* @__PURE__ */ c("h1", {
17
20
  className: "text-2xl font-semibold",
18
- children: /* @__PURE__ */ c(m, { children: S.name })
21
+ children: /* @__PURE__ */ c(m, { children: w.name })
19
22
  }),
20
23
  /* @__PURE__ */ c("p", {
21
24
  className: "text-sm text-text-secondary",
22
- children: S.description
25
+ children: w.description
23
26
  }),
24
27
  /* @__PURE__ */ c(_, {
25
28
  className: "mt-2",
26
29
  children: "The full picture of a marketplace project — scope, budget, timeline, and progress — so you can track delivery and stay aligned with the team doing the work."
27
30
  })
28
31
  ] }), /* @__PURE__ */ c(u, {
29
- variant: S.status === "active" ? "default" : "secondary",
30
- children: t(S.status)
32
+ variant: w.status === "active" ? "default" : "secondary",
33
+ children: t(w.status)
31
34
  })]
32
35
  }),
33
36
  /* @__PURE__ */ c(g, {
@@ -38,21 +41,21 @@ function v() {
38
41
  label: "Message the team",
39
42
  description: "Coordinate on scope, blockers, and next milestones.",
40
43
  icon: /* @__PURE__ */ c(i, { className: "h-4 w-4" }),
41
- onClick: () => v("../marketplace/messaging-page")
44
+ onClick: () => y("../marketplace/messaging-page")
42
45
  },
43
46
  {
44
47
  id: "bookings",
45
48
  label: "Review bookings",
46
49
  description: "Check the engagements tied to this project.",
47
50
  icon: /* @__PURE__ */ c(n, { className: "h-4 w-4" }),
48
- onClick: () => v("../marketplace/booking-management-page")
51
+ onClick: () => y("../marketplace/booking-management-page")
49
52
  },
50
53
  {
51
54
  id: "earnings",
52
55
  label: "Track earnings",
53
56
  description: "See payouts and balances connected to your work.",
54
57
  icon: /* @__PURE__ */ c(r, { className: "h-4 w-4" }),
55
- onClick: () => v("../marketplace/earnings-page")
58
+ onClick: () => y("../marketplace/earnings-page")
56
59
  }
57
60
  ]
58
61
  }),
@@ -67,7 +70,7 @@ function v() {
67
70
  className: "text-lg font-bold",
68
71
  children: [
69
72
  "$",
70
- (S.budget / 1e3).toFixed(0),
73
+ (w.budget / 1e3).toFixed(0),
71
74
  "K"
72
75
  ]
73
76
  }),
@@ -85,7 +88,7 @@ function v() {
85
88
  className: "text-lg font-bold",
86
89
  children: [
87
90
  "$",
88
- (S.spent / 1e3).toFixed(0),
91
+ (w.spent / 1e3).toFixed(0),
89
92
  "K"
90
93
  ]
91
94
  }),
@@ -101,7 +104,7 @@ function v() {
101
104
  /* @__PURE__ */ c(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
102
105
  /* @__PURE__ */ c("p", {
103
106
  className: "text-lg font-bold",
104
- children: S.teamName
107
+ children: w.teamName
105
108
  }),
106
109
  /* @__PURE__ */ c("p", {
107
110
  className: "text-xs text-text-secondary",
@@ -115,7 +118,7 @@ function v() {
115
118
  /* @__PURE__ */ c(n, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
116
119
  /* @__PURE__ */ c("p", {
117
120
  className: "text-lg font-bold",
118
- children: S.endDate
121
+ children: w.endDate
119
122
  }),
120
123
  /* @__PURE__ */ c("p", {
121
124
  className: "text-xs text-text-secondary",
@@ -135,19 +138,19 @@ function v() {
135
138
  children: [/* @__PURE__ */ l("div", {
136
139
  className: "flex justify-between text-sm",
137
140
  children: [/* @__PURE__ */ l("span", { children: [
138
- S.completedTasks,
141
+ w.completedTasks,
139
142
  " of ",
140
- S.tasks,
143
+ w.tasks,
141
144
  " tasks"
142
145
  ] }), /* @__PURE__ */ l("span", {
143
146
  className: "font-medium",
144
- children: [S.progress, "%"]
147
+ children: [w.progress, "%"]
145
148
  })]
146
149
  }), /* @__PURE__ */ c("div", {
147
150
  className: "h-3 bg-bg-sunken rounded overflow-hidden",
148
151
  children: /* @__PURE__ */ c("div", {
149
152
  className: "h-3 bg-action-primary-bg rounded",
150
- style: { width: `${S.progress}%` }
153
+ style: { width: `${w.progress}%` }
151
154
  })
152
155
  })]
153
156
  }),
@@ -159,28 +162,28 @@ function v() {
159
162
  children: "Manager"
160
163
  }), /* @__PURE__ */ c("p", {
161
164
  className: "text-sm font-medium",
162
- children: S.managerName
165
+ children: w.managerName
163
166
  })] }),
164
167
  /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
165
168
  className: "text-xs text-text-secondary",
166
169
  children: "Priority"
167
170
  }), /* @__PURE__ */ c(u, {
168
- variant: S.priority === "critical" ? "destructive" : S.priority === "high" ? "default" : "secondary",
169
- children: t(S.priority)
171
+ variant: w.priority === "critical" ? "destructive" : w.priority === "high" ? "default" : "secondary",
172
+ children: t(w.priority)
170
173
  })] }),
171
174
  /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
172
175
  className: "text-xs text-text-secondary",
173
176
  children: "Start Date"
174
177
  }), /* @__PURE__ */ c("p", {
175
178
  className: "text-sm",
176
- children: S.startDate
179
+ children: w.startDate
177
180
  })] }),
178
181
  /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
179
182
  className: "text-xs text-text-secondary",
180
183
  children: "End Date"
181
184
  }), /* @__PURE__ */ c("p", {
182
185
  className: "text-sm",
183
- children: S.endDate
186
+ children: w.endDate
184
187
  })] })
185
188
  ]
186
189
  })
@@ -196,6 +199,6 @@ function v() {
196
199
  });
197
200
  }
198
201
  //#endregion
199
- export { v as MarketplaceProjectDetailsPagePage };
202
+ export { y as MarketplaceProjectDetailsPagePage };
200
203
 
201
204
  //# sourceMappingURL=MarketplaceProjectDetailsPagePage.js.map