@powerhousedao/builder-profile 0.0.10 → 0.0.12

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 (60) hide show
  1. package/dist/document-models/builder-profile/actions.d.ts.map +1 -1
  2. package/dist/document-models/builder-profile/gen/builders/actions.d.ts +1 -1
  3. package/dist/document-models/builder-profile/gen/builders/actions.d.ts.map +1 -1
  4. package/dist/document-models/builder-profile/gen/builders/actions.js +1 -1
  5. package/dist/document-models/builder-profile/gen/builders/operations.d.ts +2 -2
  6. package/dist/document-models/builder-profile/gen/builders/operations.d.ts.map +1 -1
  7. package/dist/document-models/builder-profile/gen/builders/operations.js +0 -2
  8. package/dist/document-models/builder-profile/gen/document-model.js +7 -7
  9. package/dist/document-models/builder-profile/gen/document-schema.d.ts +54 -379
  10. package/dist/document-models/builder-profile/gen/document-schema.d.ts.map +1 -1
  11. package/dist/document-models/builder-profile/gen/ph-factories.d.ts.map +1 -1
  12. package/dist/document-models/builder-profile/gen/ph-factories.js +0 -1
  13. package/dist/document-models/builder-profile/gen/reducer.d.ts.map +1 -1
  14. package/dist/document-models/builder-profile/gen/reducer.js +22 -11
  15. package/dist/document-models/builder-profile/gen/schema/types.d.ts +13 -5
  16. package/dist/document-models/builder-profile/gen/schema/types.d.ts.map +1 -1
  17. package/dist/document-models/builder-profile/gen/schema/zod.d.ts +59 -11
  18. package/dist/document-models/builder-profile/gen/schema/zod.d.ts.map +1 -1
  19. package/dist/document-models/builder-profile/gen/schema/zod.js +17 -21
  20. package/dist/document-models/builder-profile/gen/types.d.ts.map +1 -1
  21. package/dist/document-models/builder-profile/gen/utils.d.ts.map +1 -1
  22. package/dist/document-models/builder-profile/gen/utils.js +0 -1
  23. package/dist/document-models/builder-profile/hooks.d.ts +5 -2
  24. package/dist/document-models/builder-profile/hooks.d.ts.map +1 -1
  25. package/dist/document-models/builder-profile/hooks.js +3 -4
  26. package/dist/document-models/builder-profile/index.d.ts +0 -4
  27. package/dist/document-models/builder-profile/index.d.ts.map +1 -1
  28. package/dist/document-models/builder-profile/index.js +0 -4
  29. package/dist/document-models/builder-profile/module.d.ts.map +1 -1
  30. package/dist/document-models/builder-profile/module.js +1 -0
  31. package/dist/document-models/builder-profile/src/reducers/builders.d.ts.map +1 -1
  32. package/dist/document-models/builder-profile/src/reducers/builders.js +0 -2
  33. package/dist/document-models/builder-profile/tests/builders.test.d.ts +2 -0
  34. package/dist/document-models/builder-profile/tests/builders.test.d.ts.map +1 -0
  35. package/dist/document-models/builder-profile/tests/builders.test.js +115 -0
  36. package/dist/document-models/builder-profile/tests/document-model.test.d.ts +10 -0
  37. package/dist/document-models/builder-profile/tests/document-model.test.d.ts.map +1 -0
  38. package/dist/document-models/builder-profile/tests/document-model.test.js +104 -0
  39. package/dist/editors/builder-profile/components/ContributorsSection.d.ts.map +1 -1
  40. package/dist/editors/builder-profile/components/ContributorsSection.js +15 -1
  41. package/dist/editors/builder-profile/components/ProfilePreview.d.ts.map +1 -1
  42. package/dist/editors/builder-profile/components/ProfilePreview.js +2 -2
  43. package/dist/editors/builder-profile/editor.d.ts.map +1 -1
  44. package/dist/editors/builder-profile/editor.js +147 -48
  45. package/dist/editors/builder-profile/module.d.ts +1 -1
  46. package/dist/editors/builder-profile/module.d.ts.map +1 -1
  47. package/dist/editors/builder-profile/module.js +1 -1
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -4
  51. package/dist/scripts/builder-migration/migrate_builders.d.ts +18 -0
  52. package/dist/scripts/builder-migration/migrate_builders.d.ts.map +1 -0
  53. package/dist/scripts/builder-migration/migrate_builders.js +405 -0
  54. package/dist/style.css +120 -29
  55. package/dist/subgraphs/builder-profile/schema.d.ts.map +1 -1
  56. package/dist/subgraphs/builder-profile/schema.js +2 -37
  57. package/package.json +31 -26
  58. package/dist/vitest.config.d.ts +0 -3
  59. package/dist/vitest.config.d.ts.map +0 -1
  60. package/dist/vitest.config.js +0 -8
@@ -0,0 +1,104 @@
1
+ /**
2
+ * This is a scaffold file meant for customization:
3
+ * - change it by adding new tests or modifying the existing ones
4
+ */
5
+ /**
6
+ * This is a scaffold file meant for customization:
7
+ * - change it by adding new tests or modifying the existing ones
8
+ */
9
+ import { describe, it, expect } from "vitest";
10
+ import { utils, initialGlobalState, initialLocalState, builderProfileDocumentType, isBuilderProfileDocument, assertIsBuilderProfileDocument, isBuilderProfileState, assertIsBuilderProfileState, } from "@powerhousedao/builder-profile/document-models/builder-profile";
11
+ import { ZodError } from "zod";
12
+ describe("BuilderProfile Document Model", () => {
13
+ it("should create a new BuilderProfile document", () => {
14
+ const document = utils.createDocument();
15
+ expect(document).toBeDefined();
16
+ expect(document.header.documentType).toBe(builderProfileDocumentType);
17
+ });
18
+ it("should create a new BuilderProfile document with a valid initial state", () => {
19
+ const document = utils.createDocument();
20
+ expect(document.state.global).toStrictEqual(initialGlobalState);
21
+ expect(document.state.local).toStrictEqual(initialLocalState);
22
+ expect(isBuilderProfileDocument(document)).toBe(true);
23
+ expect(isBuilderProfileState(document.state)).toBe(true);
24
+ });
25
+ it("should reject a document that is not a BuilderProfile document", () => {
26
+ const wrongDocumentType = utils.createDocument();
27
+ wrongDocumentType.header.documentType = "the-wrong-thing-1234";
28
+ try {
29
+ expect(assertIsBuilderProfileDocument(wrongDocumentType)).toThrow();
30
+ expect(isBuilderProfileDocument(wrongDocumentType)).toBe(false);
31
+ }
32
+ catch (error) {
33
+ expect(error).toBeInstanceOf(ZodError);
34
+ }
35
+ });
36
+ const wrongState = utils.createDocument();
37
+ // @ts-expect-error - we are testing the error case
38
+ wrongState.state.global = {
39
+ ...{ notWhat: "you want" },
40
+ };
41
+ try {
42
+ expect(isBuilderProfileState(wrongState.state)).toBe(false);
43
+ expect(assertIsBuilderProfileState(wrongState.state)).toThrow();
44
+ expect(isBuilderProfileDocument(wrongState)).toBe(false);
45
+ expect(assertIsBuilderProfileDocument(wrongState)).toThrow();
46
+ }
47
+ catch (error) {
48
+ expect(error).toBeInstanceOf(ZodError);
49
+ }
50
+ const wrongInitialState = utils.createDocument();
51
+ // @ts-expect-error - we are testing the error case
52
+ wrongInitialState.initialState.global = {
53
+ ...{ notWhat: "you want" },
54
+ };
55
+ try {
56
+ expect(isBuilderProfileState(wrongInitialState.state)).toBe(false);
57
+ expect(assertIsBuilderProfileState(wrongInitialState.state)).toThrow();
58
+ expect(isBuilderProfileDocument(wrongInitialState)).toBe(false);
59
+ expect(assertIsBuilderProfileDocument(wrongInitialState)).toThrow();
60
+ }
61
+ catch (error) {
62
+ expect(error).toBeInstanceOf(ZodError);
63
+ }
64
+ const missingIdInHeader = utils.createDocument();
65
+ // @ts-expect-error - we are testing the error case
66
+ delete missingIdInHeader.header.id;
67
+ try {
68
+ expect(isBuilderProfileDocument(missingIdInHeader)).toBe(false);
69
+ expect(assertIsBuilderProfileDocument(missingIdInHeader)).toThrow();
70
+ }
71
+ catch (error) {
72
+ expect(error).toBeInstanceOf(ZodError);
73
+ }
74
+ const missingNameInHeader = utils.createDocument();
75
+ // @ts-expect-error - we are testing the error case
76
+ delete missingNameInHeader.header.name;
77
+ try {
78
+ expect(isBuilderProfileDocument(missingNameInHeader)).toBe(false);
79
+ expect(assertIsBuilderProfileDocument(missingNameInHeader)).toThrow();
80
+ }
81
+ catch (error) {
82
+ expect(error).toBeInstanceOf(ZodError);
83
+ }
84
+ const missingCreatedAtUtcIsoInHeader = utils.createDocument();
85
+ // @ts-expect-error - we are testing the error case
86
+ delete missingCreatedAtUtcIsoInHeader.header.createdAtUtcIso;
87
+ try {
88
+ expect(isBuilderProfileDocument(missingCreatedAtUtcIsoInHeader)).toBe(false);
89
+ expect(assertIsBuilderProfileDocument(missingCreatedAtUtcIsoInHeader)).toThrow();
90
+ }
91
+ catch (error) {
92
+ expect(error).toBeInstanceOf(ZodError);
93
+ }
94
+ const missingLastModifiedAtUtcIsoInHeader = utils.createDocument();
95
+ // @ts-expect-error - we are testing the error case
96
+ delete missingLastModifiedAtUtcIsoInHeader.header.lastModifiedAtUtcIso;
97
+ try {
98
+ expect(isBuilderProfileDocument(missingLastModifiedAtUtcIsoInHeader)).toBe(false);
99
+ expect(assertIsBuilderProfileDocument(missingLastModifiedAtUtcIsoInHeader)).toThrow();
100
+ }
101
+ catch (error) {
102
+ expect(error).toBeInstanceOf(ZodError);
103
+ }
104
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"ContributorsSection.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ContributorsSection.tsx"],"names":[],"mappings":"AA0JA,UAAU,wBAAwB;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,mBAAmB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,wBAAwB,2CAiR1B"}
1
+ {"version":3,"file":"ContributorsSection.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ContributorsSection.tsx"],"names":[],"mappings":"AA0JA,UAAU,wBAAwB;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,mBAAmB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,wBAAwB,2CAiS1B"}
@@ -105,7 +105,21 @@ export function ContributorsSection({ contributors, onAddContributor, onRemoveCo
105
105
  return builderProfileNodesWithDriveId.map(({ node }) => node.id);
106
106
  }, [builderProfileNodesWithDriveId]);
107
107
  // Fetch all builder profile documents from all drives
108
- const builderProfileDocuments = useGetDocuments(builderPhids);
108
+ const getDocuments = useGetDocuments();
109
+ const [builderProfileDocuments, setBuilderProfileDocuments] = useState([]);
110
+ useEffect(() => {
111
+ if (builderPhids.length > 0) {
112
+ getDocuments(builderPhids)
113
+ .then(setBuilderProfileDocuments)
114
+ .catch((error) => {
115
+ console.error("Failed to fetch builder profile documents:", error);
116
+ setBuilderProfileDocuments([]);
117
+ });
118
+ }
119
+ else {
120
+ setBuilderProfileDocuments([]);
121
+ }
122
+ }, [builderPhids, getDocuments]);
109
123
  // Create a map of PHID to document for quick lookup (local drives)
110
124
  const localBuilderProfileMap = useMemo(() => {
111
125
  const map = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"ProfilePreview.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ProfilePreview.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,uDAAuD,CAAC;AAmD/D,UAAU,mBAAmB;IAC3B,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,mBAAmB,kDA6I5D"}
1
+ {"version":3,"file":"ProfilePreview.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ProfilePreview.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,uDAAuD,CAAC;AAmD/D,UAAU,mBAAmB;IAC3B,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,mBAAmB,kDAwI5D"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Users, Link2 } from "lucide-react";
2
+ import { Link2 } from "lucide-react";
3
3
  import { MarkdownPreview } from "./MarkdownPreview.js";
4
4
  const SKILL_LABELS = {
5
5
  FRONTEND_DEVELOPMENT: "Frontend",
@@ -52,5 +52,5 @@ export function ProfilePreview({ state }) {
52
52
  const statusStyle = state.status
53
53
  ? STATUS_STYLES[state.status]
54
54
  : STATUS_STYLES.INACTIVE;
55
- return (_jsxs("div", { className: "bg-white border border-slate-200/60 rounded-2xl shadow-sm overflow-hidden", children: [_jsx("div", { className: "h-24 bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 relative", children: _jsx("div", { className: "absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC4xIj48cGF0aCBkPSJNMzYgMzBoLTZWMGg2djMwem0tNiAwSDI0VjBoNnYzMHoiLz48L2c+PC9nPjwvc3ZnPg==')] opacity-30" }) }), _jsxs("div", { className: "px-6 pb-6", children: [_jsxs("div", { className: "-mt-12 mb-4 flex items-end justify-between", children: [_jsxs("div", { className: "relative", children: [state.icon ? (_jsx("img", { src: state.icon, alt: "Profile", className: "w-24 h-24 rounded-2xl object-cover border-4 border-white shadow-lg" })) : (_jsx("div", { className: "w-24 h-24 rounded-2xl bg-gradient-to-br from-slate-700 to-slate-900 border-4 border-white shadow-lg flex items-center justify-center", children: _jsx("span", { className: "text-3xl font-bold text-white", children: state.name?.charAt(0).toUpperCase() || "?" }) })), state.type === "TEAM" && (_jsx("div", { className: "absolute -bottom-1 -right-1 w-7 h-7 bg-purple-500 rounded-lg border-2 border-white flex items-center justify-center", children: _jsx(Users, { size: 14, className: "text-white" }) }))] }), state.status && (_jsxs("div", { className: `flex items-center gap-1.5 px-3 py-1.5 rounded-full ${statusStyle.bg}`, children: [_jsx("span", { className: `w-2 h-2 rounded-full ${statusStyle.dot}` }), _jsx("span", { className: `text-xs font-medium ${statusStyle.text}`, children: state.status.replace("_", " ") })] }))] }), _jsxs("div", { className: "mb-4", children: [_jsx("h4", { className: "text-xl font-semibold text-slate-900 tracking-tight", children: state.name || "Unnamed Builder" }), state.slug && (_jsxs("p", { className: "text-sm text-slate-500 font-medium", children: ["@", state.slug] }))] }), state.description && (_jsx("p", { className: "text-sm text-slate-600 mb-4 leading-relaxed", children: state.description })), state.about && (_jsx("div", { className: "mb-5", children: _jsx(MarkdownPreview, { content: state.about, maxLength: 300 }) })), state.skills && state.skills.length > 0 && (_jsxs("div", { className: "mb-4", children: [_jsx("p", { className: "text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2", children: "Skills" }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: state.skills.map((skill) => (_jsx("span", { className: "px-2.5 py-1 rounded-lg text-xs font-medium bg-indigo-50 text-indigo-700 border border-indigo-100", children: SKILL_LABELS[skill] || skill }, skill))) })] })), state.scopes && state.scopes.length > 0 && (_jsxs("div", { className: "mb-4", children: [_jsx("p", { className: "text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2", children: "Scopes" }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: state.scopes.map((scope) => (_jsx("span", { className: "px-2.5 py-1 rounded-lg text-xs font-medium bg-emerald-50 text-emerald-700 border border-emerald-100", children: SCOPE_LABELS[scope] || scope }, scope))) })] })), state.links && state.links.length > 0 && (_jsx("div", { className: "pt-4 border-t border-slate-100", children: _jsx("div", { className: "flex flex-wrap gap-3", children: state.links.map((link) => (_jsxs("a", { href: link.url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1.5 text-sm text-slate-600 hover:text-indigo-600 transition-colors group", children: [_jsx(Link2, { size: 14, className: "text-slate-400 group-hover:text-indigo-500 transition-colors" }), _jsx("span", { className: "group-hover:underline underline-offset-2", children: link.label || new URL(link.url).hostname })] }, link.id))) }) }))] })] }));
55
+ return (_jsxs("div", { className: "bg-white border border-slate-200/60 rounded-2xl shadow-sm overflow-hidden", children: [_jsx("div", { className: "h-24 bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 relative", children: _jsx("div", { className: "absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC4xIj48cGF0aCBkPSJNMzYgMzBoLTZWMGg2djMwem0tNiAwSDI0VjBoNnYzMHoiLz48L2c+PC9nPjwvc3ZnPg==')] opacity-30" }) }), _jsxs("div", { className: "px-6 pb-6", children: [_jsxs("div", { className: "-mt-12 mb-4 flex items-end justify-between", children: [_jsx("div", { className: "relative", children: state.icon ? (_jsx("img", { src: state.icon, alt: "Profile", className: "w-24 h-24 rounded-2xl object-cover border-4 border-white shadow-lg" })) : (_jsx("div", { className: "w-24 h-24 rounded-2xl bg-gradient-to-br from-slate-700 to-slate-900 border-4 border-white shadow-lg flex items-center justify-center", children: _jsx("span", { className: "text-3xl font-bold text-white", children: state.name?.charAt(0).toUpperCase() || "?" }) })) }), state.status && (_jsxs("div", { className: `flex items-center gap-1.5 px-3 py-1.5 rounded-full ${statusStyle.bg}`, children: [_jsx("span", { className: `w-2 h-2 rounded-full ${statusStyle.dot}` }), _jsx("span", { className: `text-xs font-medium ${statusStyle.text}`, children: state.status.replace("_", " ") })] }))] }), _jsxs("div", { className: "mb-4", children: [_jsx("h4", { className: "text-xl font-semibold text-slate-900 tracking-tight", children: state.name || "Unnamed Builder" }), state.slug && (_jsxs("p", { className: "text-sm text-slate-500 font-medium", children: ["@", state.slug] }))] }), state.description && (_jsx("p", { className: "text-sm text-slate-600 mb-4 leading-relaxed", children: state.description })), state.about && (_jsx("div", { className: "mb-5", children: _jsx(MarkdownPreview, { content: state.about, maxLength: 300 }) })), state.skills && state.skills.length > 0 && (_jsxs("div", { className: "mb-4", children: [_jsx("p", { className: "text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2", children: "Skills" }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: state.skills.map((skill) => (_jsx("span", { className: "px-2.5 py-1 rounded-lg text-xs font-medium bg-indigo-50 text-indigo-700 border border-indigo-100", children: SKILL_LABELS[skill] || skill }, skill))) })] })), state.scopes && state.scopes.length > 0 && (_jsxs("div", { className: "mb-4", children: [_jsx("p", { className: "text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2", children: "Scopes" }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: state.scopes.map((scope) => (_jsx("span", { className: "px-2.5 py-1 rounded-lg text-xs font-medium bg-emerald-50 text-emerald-700 border border-emerald-100", children: SCOPE_LABELS[scope] || scope }, scope))) })] })), state.links && state.links.length > 0 && (_jsx("div", { className: "pt-4 border-t border-slate-100", children: _jsx("div", { className: "flex flex-wrap gap-3", children: state.links.map((link) => (_jsxs("a", { href: link.url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1.5 text-sm text-slate-600 hover:text-indigo-600 transition-colors group", children: [_jsx(Link2, { size: 14, className: "text-slate-400 group-hover:text-indigo-500 transition-colors" }), _jsx("span", { className: "group-hover:underline underline-offset-2", children: link.label || new URL(link.url).hostname })] }, link.id))) }) }))] })] }));
56
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/builder-profile/editor.tsx"],"names":[],"mappings":"AA0CA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAupB7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/builder-profile/editor.tsx"],"names":[],"mappings":"AAyCA,MAAM,CAAC,OAAO,UAAU,MAAM,4CA0yB7B"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { TextInput, Textarea } from "@powerhousedao/document-engineering";
3
- import { User, Users, Settings, FileText, Copy, Info } from "lucide-react";
3
+ import { Settings, FileText, Copy, Info } from "lucide-react";
4
4
  import { toast, ToastContainer, DocumentToolbar, } from "@powerhousedao/design-system/connect";
5
5
  import { actions } from "../../document-models/builder-profile/index.js";
6
6
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -30,6 +30,8 @@ export default function Editor() {
30
30
  }
31
31
  const idGeneratedRef = useRef(false);
32
32
  const [descriptionValue, setDescriptionValue] = useState(state?.description || "");
33
+ const [showRoleDialog, setShowRoleDialog] = useState(false);
34
+ const [pendingRoleChange, setPendingRoleChange] = useState(null);
33
35
  // Sync description state when document changes
34
36
  useEffect(() => {
35
37
  setDescriptionValue(state?.description || "");
@@ -100,12 +102,6 @@ export default function Editor() {
100
102
  return;
101
103
  dispatch(actions.updateProfile({ status }));
102
104
  }, [dispatch]);
103
- // Handle type change
104
- const handleTypeChange = useCallback((type) => {
105
- if (!dispatch)
106
- return;
107
- dispatch(actions.updateProfile({ type }));
108
- }, [dispatch]);
109
105
  // Skill handlers
110
106
  const handleAddSkill = useCallback((skill) => {
111
107
  if (!dispatch)
@@ -155,12 +151,32 @@ export default function Editor() {
155
151
  return;
156
152
  dispatch(actions.removeContributor({ contributorPHID }));
157
153
  }, [dispatch]);
158
- // Operator handler
154
+ // Operator handler - shows confirmation dialog
159
155
  const handleSetOperator = useCallback((isOperator) => {
160
156
  if (!dispatch)
161
157
  return;
162
- dispatch(actions.setOperator({ isOperator }));
163
- }, [dispatch]);
158
+ // If trying to change role, show confirmation dialog
159
+ if (state?.isOperator !== isOperator) {
160
+ setPendingRoleChange(isOperator);
161
+ setShowRoleDialog(true);
162
+ }
163
+ }, [dispatch, state?.isOperator]);
164
+ // Confirm role change after dialog
165
+ const confirmRoleChange = useCallback(() => {
166
+ if (!dispatch || pendingRoleChange === null)
167
+ return;
168
+ dispatch(actions.setOperator({ isOperator: pendingRoleChange }));
169
+ setShowRoleDialog(false);
170
+ setPendingRoleChange(null);
171
+ toast(`Switched to ${pendingRoleChange ? "Operator" : "Builder"} profile`, {
172
+ type: "success",
173
+ });
174
+ }, [dispatch, pendingRoleChange]);
175
+ // Cancel role change
176
+ const cancelRoleChange = useCallback(() => {
177
+ setShowRoleDialog(false);
178
+ setPendingRoleChange(null);
179
+ }, []);
164
180
  // Dynamic role label based on isOperator flag
165
181
  const roleLabel = state?.isOperator ? "Operator" : "Builder";
166
182
  return (_jsxs("div", { className: "w-full min-h-screen bg-gradient-to-br from-slate-50 via-white to-slate-100", children: [_jsx("style", { children: `
@@ -200,34 +216,6 @@ export default function Editor() {
200
216
  border-radius: 8px;
201
217
  border: 1px solid #E5E7EB;
202
218
  }
203
- .builder-editor .type-toggle {
204
- display: flex;
205
- background: #F3F4F6;
206
- border-radius: 10px;
207
- padding: 4px;
208
- gap: 4px;
209
- }
210
- .builder-editor .type-toggle button {
211
- flex: 1;
212
- padding: 0.625rem 1rem;
213
- font-size: 0.875rem;
214
- font-weight: 500;
215
- border-radius: 8px;
216
- border: none;
217
- cursor: pointer;
218
- transition: all 0.2s ease;
219
- color: #6B7280;
220
- background: transparent;
221
- }
222
- .builder-editor .type-toggle button.active {
223
- background: white;
224
- color: #111827;
225
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
226
- }
227
- .builder-editor .type-toggle button:not(.active):hover {
228
- color: #374151;
229
- background: rgba(255, 255, 255, 0.5);
230
- }
231
219
  .builder-editor .status-select {
232
220
  appearance: none;
233
221
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
@@ -281,12 +269,125 @@ export default function Editor() {
281
269
  .builder-editor .role-toggle button.active .role-icon {
282
270
  transform: scale(1.1);
283
271
  }
284
- ` }), _jsx(DocumentToolbar, { document: doc, onClose: handleClose }), _jsxs("div", { className: "builder-editor p-6 max-w-4xl mx-auto space-y-6 pb-12", children: [_jsx("div", { className: "section-card p-8", children: _jsxs("div", { className: "flex items-start justify-between gap-6", children: [_jsxs("div", { children: [_jsxs("h1", { className: "text-2xl font-semibold text-slate-900 tracking-tight", children: [roleLabel, " Profile"] }), _jsxs("p", { className: "text-slate-500 mt-1 text-sm", children: ["Configure your ", roleLabel.toLowerCase(), " identity and capabilities"] })] }), _jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [_jsxs("div", { className: "role-toggle", children: [_jsxs("button", { type: "button", onClick: () => handleSetOperator(false), className: !state?.isOperator ? "active builder" : "", children: [_jsx("span", { className: "role-icon", children: "\uD83D\uDD28" }), "Builder"] }), _jsxs("button", { type: "button", onClick: () => handleSetOperator(true), className: state?.isOperator ? "active operator" : "", children: [_jsx("span", { className: "role-icon", children: "\u26A1" }), "Operator"] })] }), _jsx("p", { className: "text-xs text-slate-400 text-right max-w-[180px]", children: state?.isOperator ? "Sells & buys services" : "Buys services" })] })] }) }), state && _jsx(ProfilePreview, { state: state }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-slate-100 flex items-center justify-center", children: _jsx(Info, { size: 18, className: "text-slate-600" }) }), "Metadata"] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "field-label", children: [roleLabel, " ID"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "meta-value flex-1 truncate", children: doc?.header.id }), _jsx("button", { type: "button", className: "p-2 rounded-lg border border-slate-200 hover:bg-slate-50 transition-colors", title: `Copy ${roleLabel} ID`, onClick: () => {
272
+ .role-dialog-overlay {
273
+ position: fixed;
274
+ inset: 0;
275
+ background: rgba(0, 0, 0, 0.6);
276
+ backdrop-filter: blur(4px);
277
+ display: flex;
278
+ align-items: center;
279
+ justify-content: center;
280
+ z-index: 9999;
281
+ animation: fadeIn 0.2s ease-out;
282
+ }
283
+ @keyframes fadeIn {
284
+ from { opacity: 0; }
285
+ to { opacity: 1; }
286
+ }
287
+ .role-dialog {
288
+ background: white;
289
+ border-radius: 20px;
290
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
291
+ max-width: 700px;
292
+ width: 90%;
293
+ max-height: 90vh;
294
+ overflow-y: auto;
295
+ animation: slideUp 0.3s ease-out;
296
+ }
297
+ @keyframes slideUp {
298
+ from {
299
+ opacity: 0;
300
+ transform: translateY(20px);
301
+ }
302
+ to {
303
+ opacity: 1;
304
+ transform: translateY(0);
305
+ }
306
+ }
307
+ .role-dialog-header {
308
+ padding: 2rem 2rem 1.5rem 2rem;
309
+ border-bottom: 1px solid #E5E7EB;
310
+ }
311
+ .role-dialog-content {
312
+ padding: 2rem;
313
+ }
314
+ .role-comparison {
315
+ display: grid;
316
+ gap: 1rem;
317
+ margin-top: 1rem;
318
+ }
319
+ .role-card {
320
+ padding: 1.5rem;
321
+ border: 2px solid #E5E7EB;
322
+ border-radius: 12px;
323
+ background: #F9FAFB;
324
+ transition: all 0.2s ease;
325
+ }
326
+ .role-card.highlight {
327
+ border-color: #3B82F6;
328
+ background: #EFF6FF;
329
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
330
+ }
331
+ .role-card-header {
332
+ display: flex;
333
+ align-items: center;
334
+ gap: 0.75rem;
335
+ margin-bottom: 0.75rem;
336
+ }
337
+ .role-icon-large {
338
+ font-size: 1.5rem;
339
+ }
340
+ .role-features {
341
+ list-style: none;
342
+ padding: 0;
343
+ margin: 1rem 0 0 0;
344
+ display: flex;
345
+ flex-direction: column;
346
+ gap: 0.5rem;
347
+ }
348
+ .role-features li {
349
+ font-size: 0.875rem;
350
+ color: #475569;
351
+ padding-left: 0;
352
+ }
353
+ .role-dialog-actions {
354
+ padding: 1.5rem 2rem 2rem 2rem;
355
+ display: flex;
356
+ gap: 1rem;
357
+ justify-content: flex-end;
358
+ border-top: 1px solid #E5E7EB;
359
+ }
360
+ .dialog-button {
361
+ padding: 0.75rem 1.5rem;
362
+ border-radius: 10px;
363
+ font-weight: 600;
364
+ font-size: 0.9375rem;
365
+ cursor: pointer;
366
+ transition: all 0.2s ease;
367
+ border: none;
368
+ }
369
+ .dialog-button-cancel {
370
+ background: #F3F4F6;
371
+ color: #374151;
372
+ }
373
+ .dialog-button-cancel:hover {
374
+ background: #E5E7EB;
375
+ }
376
+ .dialog-button-confirm {
377
+ background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
378
+ color: white;
379
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
380
+ }
381
+ .dialog-button-confirm:hover {
382
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
383
+ transform: translateY(-1px);
384
+ }
385
+ ` }), _jsx(DocumentToolbar, { document: doc, onClose: handleClose }), _jsxs("div", { className: "builder-editor p-6 max-w-4xl mx-auto space-y-6 pb-12", children: [_jsx("div", { className: "section-card p-8", children: _jsxs("div", { className: "flex items-start justify-between gap-6", children: [_jsxs("div", { children: [_jsxs("h1", { className: "text-2xl font-semibold text-slate-900 tracking-tight", children: [roleLabel, " Team Profile"] }), _jsxs("p", { className: "text-slate-500 mt-1 text-sm", children: ["Configure your ", roleLabel.toLowerCase(), " team identity and capabilities"] })] }), _jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [_jsxs("div", { className: "role-toggle", children: [_jsxs("button", { type: "button", onClick: () => handleSetOperator(false), className: !state?.isOperator ? "active builder" : "", children: [_jsx("span", { className: "role-icon", children: "\uD83D\uDD28" }), "Builder"] }), _jsxs("button", { type: "button", onClick: () => handleSetOperator(true), className: state?.isOperator ? "active operator" : "", children: [_jsx("span", { className: "role-icon", children: "\u26A1" }), "Operator"] })] }), _jsx("p", { className: "text-xs text-slate-400 text-right max-w-[180px]", children: state?.isOperator ? "Sells & buys services" : "Buys services" })] })] }) }), state && _jsx(ProfilePreview, { state: state }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-slate-100 flex items-center justify-center", children: _jsx(Info, { size: 18, className: "text-slate-600" }) }), "Metadata"] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "field-label", children: [roleLabel, " ID"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "meta-value flex-1 truncate", children: doc?.header.id }), _jsx("button", { type: "button", className: "p-2 rounded-lg border border-slate-200 hover:bg-slate-50 transition-colors", title: `Copy ${roleLabel} ID`, onClick: () => {
285
386
  void navigator.clipboard.writeText(doc?.header.id || "");
286
387
  toast(`Copied ${roleLabel} ID!`, { type: "success" });
287
388
  }, children: _jsx(Copy, { size: 16, className: "text-slate-500" }) })] })] }), _jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Last Modified" }), _jsx("div", { className: "meta-value", children: state?.lastModified
288
389
  ? formatLastModified(state.lastModified)
289
- : "Never modified" })] })] })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-indigo-50 flex items-center justify-center", children: _jsx(User, { size: 18, className: "text-indigo-600" }) }), "Identity"] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "field-label", children: [roleLabel, " Name"] }), _jsx(TextInput, { className: "w-full", defaultValue: state?.name || "", onBlur: (e) => {
390
+ : "Never modified" })] })] })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-indigo-50 flex items-center justify-center", children: _jsx(Info, { size: 18, className: "text-indigo-600" }) }), "Identity"] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "field-label", children: [roleLabel, " Name"] }), _jsx(TextInput, { className: "w-full", defaultValue: state?.name || "", onBlur: (e) => {
290
391
  if (e.target.value !== state?.name) {
291
392
  handleFieldChange("name", e.target.value);
292
393
  }
@@ -296,13 +397,11 @@ export default function Editor() {
296
397
  }
297
398
  }, placeholder: "Short identifier" }), _jsx("p", { className: "field-hint", children: "Unique code for quick reference" })] }), _jsxs("div", { className: "md:col-span-2", children: [_jsx("label", { className: "field-label", children: "Profile Slug" }), _jsx(TextInput, { className: "w-full", value: state?.slug || "", onChange: (e) => {
298
399
  handleFieldChange("slug", e.target.value);
299
- }, placeholder: "your-profile-slug" }), _jsx("p", { className: "field-hint", children: "Auto-generated from name. Lowercase, hyphens only." })] }), _jsx("div", { className: "md:col-span-2", children: _jsx(ImageUrlInput, { label: "Profile Image", value: state?.icon || "", onChange: (value) => handleFieldChange("icon", value), placeholder: "https://example.com/avatar.jpg" }) })] })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-amber-50 flex items-center justify-center", children: _jsx(Settings, { size: 18, className: "text-amber-600" }) }), "Status & Type"] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Current Status" }), _jsxs("select", { className: "status-select w-full px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white", value: state?.status || "", onChange: (e) => {
300
- if (e.target.value) {
301
- handleStatusChange(e.target.value);
302
- }
303
- }, children: [_jsx("option", { value: "", disabled: true, children: "Select status..." }), STATUS_OPTIONS.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] })] }), _jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Profile Type" }), _jsxs("div", { className: "type-toggle", children: [_jsx("button", { type: "button", onClick: () => handleTypeChange("INDIVIDUAL"), className: state?.type === "INDIVIDUAL" ? "active" : "", children: _jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx(User, { size: 16 }), "Individual"] }) }), _jsx("button", { type: "button", onClick: () => handleTypeChange("TEAM"), className: state?.type === "TEAM" ? "active" : "", children: _jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx(Users, { size: 16 }), "Team"] }) })] }), _jsx("p", { className: "field-hint", children: state?.type === "TEAM"
304
- ? "Teams can add contributors to their profile"
305
- : `Individual profiles represent a single ${roleLabel.toLowerCase()}` })] })] })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-emerald-50 flex items-center justify-center", children: _jsx(FileText, { size: 18, className: "text-emerald-600" }) }), "Description & About"] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("label", { className: "field-label mb-0", children: "Short Description" }), _jsxs("span", { className: `text-xs font-medium ${descriptionValue.length > DESCRIPTION_MAX_LENGTH
400
+ }, placeholder: "your-profile-slug" }), _jsx("p", { className: "field-hint", children: "Auto-generated from name. Lowercase, hyphens only." })] }), _jsx("div", { className: "md:col-span-2", children: _jsx(ImageUrlInput, { label: "Profile Image", value: state?.icon || "", onChange: (value) => handleFieldChange("icon", value), placeholder: "https://example.com/avatar.jpg" }) })] })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-amber-50 flex items-center justify-center", children: _jsx(Settings, { size: 18, className: "text-amber-600" }) }), "Status & Type"] }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: _jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Current Status" }), _jsxs("select", { className: "status-select w-full px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white", value: state?.status || "", onChange: (e) => {
401
+ if (e.target.value) {
402
+ handleStatusChange(e.target.value);
403
+ }
404
+ }, children: [_jsx("option", { value: "", disabled: true, children: "Select status..." }), STATUS_OPTIONS.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] })] }) })] }), _jsxs("div", { className: "section-card p-6", children: [_jsxs("h3", { className: "text-lg font-semibold text-slate-900 mb-6 flex items-center gap-2", children: [_jsx("span", { className: "w-8 h-8 rounded-lg bg-emerald-50 flex items-center justify-center", children: _jsx(FileText, { size: 18, className: "text-emerald-600" }) }), "Description & About"] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("label", { className: "field-label mb-0", children: "Short Description" }), _jsxs("span", { className: `text-xs font-medium ${descriptionValue.length > DESCRIPTION_MAX_LENGTH
306
405
  ? "text-red-500"
307
406
  : descriptionValue.length > DESCRIPTION_MAX_LENGTH * 0.9
308
407
  ? "text-amber-500"
@@ -318,5 +417,5 @@ export default function Editor() {
318
417
  }
319
418
  handleFieldChange("description", e.target.value);
320
419
  }
321
- }, placeholder: `A brief summary of your ${roleLabel.toLowerCase()} profile`, rows: 3, maxLength: DESCRIPTION_MAX_LENGTH + 50 }), descriptionValue.length > DESCRIPTION_MAX_LENGTH && (_jsxs("p", { className: "text-xs text-red-500 mt-1", children: ["Description exceeds ", DESCRIPTION_MAX_LENGTH, " character limit. Please shorten it to save."] })), _jsx("p", { className: "field-hint", children: "A short, plain-text description shown in previews and listings" })] }), _jsxs("div", { children: [_jsx(MarkdownEditor, { label: "About", height: 350, value: state?.about || "", onChange: () => { }, onBlur: (value) => handleFieldChange("about", value) }), _jsx("p", { className: "field-hint", children: "A detailed description with markdown formatting to showcase your capabilities" })] })] })] }), _jsx(SkillsSection, { skills: state?.skills || [], onAddSkill: handleAddSkill, onRemoveSkill: handleRemoveSkill }), _jsx(ScopesSection, { scopes: state?.scopes || [], onAddScope: handleAddScope, onRemoveScope: handleRemoveScope }), _jsx(LinksSection, { links: state?.links || [], onAddLink: handleAddLink, onEditLink: handleEditLink, onRemoveLink: handleRemoveLink }), state?.type === "TEAM" && (_jsx(ContributorsSection, { contributors: state.contributors, onAddContributor: handleAddContributor, onRemoveContributor: handleRemoveContributor })), _jsx(ToastContainer, { position: "bottom-right" })] })] }));
420
+ }, placeholder: `A brief summary of your ${roleLabel.toLowerCase()} profile`, rows: 3, maxLength: DESCRIPTION_MAX_LENGTH + 50 }), descriptionValue.length > DESCRIPTION_MAX_LENGTH && (_jsxs("p", { className: "text-xs text-red-500 mt-1", children: ["Description exceeds ", DESCRIPTION_MAX_LENGTH, " character limit. Please shorten it to save."] })), _jsx("p", { className: "field-hint", children: "A short, plain-text description shown in previews and listings" })] }), _jsxs("div", { children: [_jsx(MarkdownEditor, { label: "About", height: 350, value: state?.about || "", onChange: () => { }, onBlur: (value) => handleFieldChange("about", value) }), _jsx("p", { className: "field-hint", children: "A detailed description with markdown formatting to showcase your capabilities" })] })] })] }), _jsx(SkillsSection, { skills: state?.skills || [], onAddSkill: handleAddSkill, onRemoveSkill: handleRemoveSkill }), _jsx(ScopesSection, { scopes: state?.scopes || [], onAddScope: handleAddScope, onRemoveScope: handleRemoveScope }), _jsx(LinksSection, { links: state?.links || [], onAddLink: handleAddLink, onEditLink: handleEditLink, onRemoveLink: handleRemoveLink }), _jsx(ContributorsSection, { contributors: state.contributors, onAddContributor: handleAddContributor, onRemoveContributor: handleRemoveContributor }), _jsx(ToastContainer, { position: "bottom-right" }), showRoleDialog && (_jsx("div", { className: "role-dialog-overlay", children: _jsxs("div", { className: "role-dialog", children: [_jsx("div", { className: "role-dialog-header", children: _jsxs("h3", { className: "text-xl font-semibold text-slate-900", children: ["Switch to ", pendingRoleChange ? "Operator" : "Builder", "?"] }) }), _jsxs("div", { className: "role-dialog-content", children: [_jsx("p", { className: "text-slate-600 mb-4", children: "Before switching, make sure you understand the difference between these roles:" }), _jsxs("div", { className: "role-comparison", children: [_jsxs("div", { className: `role-card ${!pendingRoleChange ? "highlight" : ""}`, children: [_jsxs("div", { className: "role-card-header", children: [_jsx("span", { className: "role-icon-large", children: "\uD83D\uDD28" }), _jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Builder" })] }), _jsx("p", { className: "text-sm text-slate-600 mb-3", children: "Connect gives you the tools to run your builder operations effectively. Manage your team members, edit your profile, find work to complete and purchase supporting services." }), _jsxs("ul", { className: "role-features", children: [_jsx("li", { children: "\u2713 Sign up to services" }), _jsx("li", { children: "\u2713 Purchase services from Operators" }), _jsx("li", { children: "\u2713 Manage service subscriptions" })] })] }), _jsxs("div", { className: `role-card ${pendingRoleChange ? "highlight" : ""}`, children: [_jsxs("div", { className: "role-card-header", children: [_jsx("span", { className: "role-icon-large", children: "\u26A1" }), _jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Operator" })] }), _jsx("p", { className: "text-sm text-slate-600 mb-3", children: "Everything that a builder team can do PLUS, you have services to sell to other builders and operators." }), _jsxs("ul", { className: "role-features", children: [_jsx("li", { children: "\u2713 Create and offer services" }), _jsx("li", { children: "\u2713 Sign up to other services" }), _jsx("li", { children: "\u2713 Both sell and buy services" })] })] })] })] }), _jsxs("div", { className: "role-dialog-actions", children: [_jsx("button", { type: "button", onClick: cancelRoleChange, className: "dialog-button dialog-button-cancel", children: "Cancel" }), _jsxs("button", { type: "button", onClick: confirmRoleChange, className: "dialog-button dialog-button-confirm", children: ["Continue as ", pendingRoleChange ? "Operator" : "Builder"] })] })] }) }))] })] }));
322
421
  }
@@ -1,4 +1,4 @@
1
1
  import type { EditorModule } from "document-model";
2
- /** Document editor module for the Todo List document type */
2
+ /** Document editor module for the "["powerhouse/builder-profile"]" document type */
3
3
  export declare const BuilderProfile: EditorModule;
4
4
  //# sourceMappingURL=module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../editors/builder-profile/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,6DAA6D;AAC7D,eAAO,MAAM,cAAc,EAAE,YAO5B,CAAC"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../editors/builder-profile/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,oFAAoF;AACpF,eAAO,MAAM,cAAc,EAAE,YAO5B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { lazy } from "react";
2
- /** Document editor module for the Todo List document type */
2
+ /** Document editor module for the "["powerhouse/builder-profile"]" document type */
3
3
  export const BuilderProfile = {
4
4
  Component: lazy(() => import("./editor.js")),
5
5
  documentTypes: ["powerhouse/builder-profile"],
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Manifest } from "document-model";
2
+ export { documentModels } from "./document-models/document-models.js";
3
+ export { editors } from "./editors/editors.js";
2
4
  export declare const manifest: Manifest;
3
- export declare const documentModels: import("document-model").DocumentModelModule<import("./document-models/builder-profile/index.js").BuilderProfilePHState>[];
4
- export declare const editors: import("document-model").EditorModule[];
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,eAAO,MAAM,QAAQ,EAAE,QAAuB,CAAC;AAC/C,eAAO,MAAM,cAAc,4HAAuC,CAAC;AACnE,eAAO,MAAM,OAAO,yCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,eAAO,MAAM,QAAQ,EAAE,QAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,4 @@
1
1
  import manifestJson from "./powerhouse.manifest.json" with { type: "json" };
2
- import * as documentModelsExports from "./document-models/index.js";
3
- import * as editorsExports from "./editors/index.js";
2
+ export { documentModels } from "./document-models/document-models.js";
3
+ export { editors } from "./editors/editors.js";
4
4
  export const manifest = manifestJson;
5
- export const documentModels = Object.values(documentModelsExports);
6
- export const editors = Object.values(editorsExports);
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Builder Profile Migration Script
4
+ *
5
+ * Migrates all builder profile documents from a source drive (on one MCP endpoint)
6
+ * to a new "BuildersV2" drive (on another MCP endpoint).
7
+ *
8
+ * Usage:
9
+ * bun migrate_builders.ts <source-mcp-url> <source-drive-id> <target-mcp-url>
10
+ *
11
+ * Example:
12
+ * bun migrate_builders.ts \
13
+ * https://switchboard.powerhouse.xyz/mcp \
14
+ * source-drive-id \
15
+ * http://localhost:4001/mcp
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=migrate_builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate_builders.d.ts","sourceRoot":"","sources":["../../../scripts/builder-migration/migrate_builders.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG"}