@powerhousedao/builder-profile 0.0.3 → 0.0.4
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.
- package/dist/document-models/builder-profile/actions.d.ts +9 -0
- package/dist/document-models/builder-profile/actions.d.ts.map +1 -1
- package/dist/document-models/builder-profile/actions.js +2 -2
- package/dist/document-models/builder-profile/gen/actions.d.ts +3 -3
- package/dist/document-models/builder-profile/gen/actions.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/actions.js +1 -1
- package/dist/document-models/builder-profile/gen/builders/actions.d.ts +44 -0
- package/dist/document-models/builder-profile/gen/builders/actions.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/creators.d.ts +13 -0
- package/dist/document-models/builder-profile/gen/builders/creators.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/creators.js +12 -0
- package/dist/document-models/builder-profile/gen/builders/error.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/operations.d.ts +16 -0
- package/dist/document-models/builder-profile/gen/builders/operations.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/creators.d.ts +2 -2
- package/dist/document-models/builder-profile/gen/creators.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/creators.js +2 -2
- package/dist/document-models/builder-profile/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/document-model.js +121 -22
- package/dist/document-models/builder-profile/gen/document-schema.d.ts +168 -16
- package/dist/document-models/builder-profile/gen/document-schema.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/index.d.ts +1 -1
- package/dist/document-models/builder-profile/gen/index.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/index.js +1 -1
- package/dist/document-models/builder-profile/gen/ph-factories.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/ph-factories.js +8 -0
- package/dist/document-models/builder-profile/gen/reducer.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/reducer.js +39 -3
- package/dist/document-models/builder-profile/gen/schema/types.d.ts +55 -0
- package/dist/document-models/builder-profile/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/schema/zod.d.ts +19 -1
- package/dist/document-models/builder-profile/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/schema/zod.js +126 -0
- package/dist/document-models/builder-profile/gen/utils.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/utils.js +9 -1
- package/dist/document-models/builder-profile/src/reducers/builders.d.ts +3 -0
- package/dist/document-models/builder-profile/src/reducers/builders.d.ts.map +1 -0
- package/dist/document-models/builder-profile/src/reducers/builders.js +108 -0
- package/dist/document-models/builder-profile/src/tests/{builder.test.d.ts → builders.test.d.ts} +1 -1
- package/dist/document-models/builder-profile/src/tests/builders.test.d.ts.map +1 -0
- package/dist/document-models/builder-profile/src/tests/{builder.test.js → builders.test.js} +1 -1
- package/dist/document-models/document-models.d.ts.map +1 -1
- package/dist/document-models/document-models.js +3 -1
- package/dist/document-models/index.d.ts +0 -4
- package/dist/document-models/index.d.ts.map +1 -1
- package/dist/document-models/index.js +0 -4
- package/dist/editors/builder-profile/components/ContributorsSection.d.ts +8 -0
- package/dist/editors/builder-profile/components/ContributorsSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ContributorsSection.js +177 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.d.ts +9 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.js +57 -0
- package/dist/editors/builder-profile/components/LinksSection.d.ts +18 -0
- package/dist/editors/builder-profile/components/LinksSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/LinksSection.js +74 -0
- package/dist/editors/builder-profile/components/ProfilePreview.d.ts +7 -0
- package/dist/editors/builder-profile/components/ProfilePreview.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ProfilePreview.js +55 -0
- package/dist/editors/builder-profile/components/ScopesSection.d.ts +9 -0
- package/dist/editors/builder-profile/components/ScopesSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ScopesSection.js +58 -0
- package/dist/editors/builder-profile/components/SkillsSection.d.ts +9 -0
- package/dist/editors/builder-profile/components/SkillsSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/SkillsSection.js +66 -0
- package/dist/editors/builder-profile/editor.d.ts.map +1 -1
- package/dist/editors/builder-profile/editor.js +213 -101
- package/dist/editors/builder-profile/module.js +1 -1
- package/dist/editors/index.d.ts +0 -4
- package/dist/editors/index.d.ts.map +1 -1
- package/dist/editors/index.js +0 -4
- package/dist/index.js +2 -2
- package/dist/powerhouse.manifest.json +9 -4
- package/dist/style.css +745 -29
- package/dist/subgraphs/builder-profile/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/builder-profile/resolvers.js +108 -0
- package/dist/subgraphs/builder-profile/schema.d.ts.map +1 -1
- package/dist/subgraphs/builder-profile/schema.js +118 -1
- package/package.json +24 -20
- package/dist/document-models/builder-profile/gen/builder/actions.d.ts +0 -8
- package/dist/document-models/builder-profile/gen/builder/actions.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/creators.d.ts +0 -4
- package/dist/document-models/builder-profile/gen/builder/creators.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/creators.js +0 -3
- package/dist/document-models/builder-profile/gen/builder/error.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/operations.d.ts +0 -7
- package/dist/document-models/builder-profile/gen/builder/operations.d.ts.map +0 -1
- package/dist/document-models/builder-profile/src/reducers/builder.d.ts +0 -3
- package/dist/document-models/builder-profile/src/reducers/builder.d.ts.map +0 -1
- package/dist/document-models/builder-profile/src/reducers/builder.js +0 -9
- package/dist/document-models/builder-profile/src/tests/builder.test.d.ts.map +0 -1
- /package/dist/document-models/builder-profile/gen/{builder → builders}/actions.js +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/error.d.ts +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/error.js +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/operations.js +0 -0
|
@@ -1,138 +1,250 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
-
import { TextInput, Textarea
|
|
3
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TextInput, Textarea } from "@powerhousedao/document-engineering";
|
|
3
|
+
import { User, Users, Settings, FileText, Copy, Info } from "lucide-react";
|
|
4
|
+
import { toast, ToastContainer, DocumentToolbar, } from "@powerhousedao/design-system/connect";
|
|
4
5
|
import { actions } from "../../document-models/builder-profile/index.js";
|
|
5
|
-
import { useCallback,
|
|
6
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
6
7
|
import { useSelectedBuilderProfileDocument } from "../../document-models/builder-profile/hooks.js";
|
|
7
|
-
import { setSelectedNode, useParentFolderForSelectedNode } from "@powerhousedao/reactor-browser";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
// Calculate modal size based on image dimensions with padding
|
|
23
|
-
const getModalSize = () => {
|
|
24
|
-
if (!imageLoaded)
|
|
25
|
-
return { width: "auto", height: "auto" };
|
|
26
|
-
const maxWidth = Math.min(imageDimensions.width + 100, window.innerWidth * 0.8);
|
|
27
|
-
const maxHeight = Math.min(imageDimensions.height + 100, window.innerHeight * 0.8);
|
|
28
|
-
return {
|
|
29
|
-
width: `${maxWidth}px`,
|
|
30
|
-
height: `${maxHeight}px`,
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center backdrop-blur-sm", onClick: onClose, children: _jsxs("div", { className: "relative bg-gray-900 rounded-lg shadow-2xl border-2 border-gray-700", style: getModalSize(), children: [_jsx("button", { onClick: onClose, className: "absolute -top-3 -right-3 z-10 w-8 h-8 bg-gray-800 hover:bg-gray-900 rounded-full flex items-center justify-center text-white transition-all duration-200 shadow-lg", children: _jsx(Icon, { name: "ArrowLeft", size: 16 }) }), _jsx("div", { className: "w-full h-full flex items-center justify-center p-8", children: _jsx("img", { src: imageUrl, alt: imageAlt, className: `max-w-full max-h-full object-contain rounded-lg ${imageLoaded ? "opacity-100" : "opacity-0"} transition-opacity duration-200`, onClick: (e) => e.stopPropagation(), onLoad: handleImageLoad }) })] }) }));
|
|
34
|
-
}
|
|
35
|
-
// Image URL input component with preview
|
|
36
|
-
function ImageUrlInput({ label, value, onChange, placeholder, fileSize = "200KB", }) {
|
|
37
|
-
const [imageError, setImageError] = useState(false);
|
|
38
|
-
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
39
|
-
// Reset image error when value changes
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
setImageError(false);
|
|
42
|
-
}, [value]);
|
|
43
|
-
const handleImageClick = () => {
|
|
44
|
-
if (value &&
|
|
45
|
-
!imageError &&
|
|
46
|
-
(value.startsWith("http://") || value.startsWith("https://"))) {
|
|
47
|
-
setIsModalOpen(true);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: label }), _jsxs("div", { className: "border border-gray-300 rounded-lg p-4", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center space-x-3", children: [_jsx("div", { className: `flex-shrink-0 w-12 h-12 bg-gray-100 rounded border flex items-center justify-center overflow-hidden ${value &&
|
|
51
|
-
!imageError &&
|
|
52
|
-
(value.startsWith("http://") || value.startsWith("https://"))
|
|
53
|
-
? "cursor-pointer hover:opacity-80 transition-opacity duration-200"
|
|
54
|
-
: ""}`, onClick: handleImageClick, children: value &&
|
|
55
|
-
!imageError &&
|
|
56
|
-
(value.startsWith("http://") ||
|
|
57
|
-
value.startsWith("https://")) ? (_jsx("img", { src: value, alt: `${label} preview`, className: "w-full h-full object-cover", onError: () => setImageError(true), onLoad: () => setImageError(false) })) : (_jsx(Icon, { name: "Image", size: 24, className: "text-gray-400" })) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "text-xs text-gray-500", children: ["File Type: jpg | File Size: ", value ? fileSize : "0KB", imageError && value && (_jsx("div", { className: "text-red-500 mt-1", children: "\u26A0 Failed to load image" })), value &&
|
|
58
|
-
!imageError &&
|
|
59
|
-
(value.startsWith("http://") ||
|
|
60
|
-
value.startsWith("https://")) && (_jsx("div", { className: "text-blue-600 mt-1", children: "\uD83D\uDCA1 Click image to view full size" }))] }) })] }) }), _jsx("div", { className: "mt-3", children: _jsx(TextInput, { className: "w-full", defaultValue: value || "", onBlur: (e) => {
|
|
61
|
-
if (e.target.value !== value) {
|
|
62
|
-
onChange(e.target.value);
|
|
63
|
-
}
|
|
64
|
-
}, placeholder: placeholder || "Enter image URL" }) })] })] }), _jsx(ImageModal, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), imageUrl: value, imageAlt: `${label} full size` })] }));
|
|
65
|
-
}
|
|
8
|
+
import { setSelectedNode, useParentFolderForSelectedNode, } from "@powerhousedao/reactor-browser";
|
|
9
|
+
import { SkillsSection } from "./components/SkillsSection.js";
|
|
10
|
+
import { ScopesSection } from "./components/ScopesSection.js";
|
|
11
|
+
import { LinksSection } from "./components/LinksSection.js";
|
|
12
|
+
import { ContributorsSection } from "./components/ContributorsSection.js";
|
|
13
|
+
import { ProfilePreview } from "./components/ProfilePreview.js";
|
|
14
|
+
import { ImageUrlInput } from "./components/ImageUrlInput.js";
|
|
15
|
+
const STATUS_OPTIONS = [
|
|
16
|
+
{ value: "ACTIVE", label: "Active", color: "bg-emerald-500" },
|
|
17
|
+
{ value: "INACTIVE", label: "Inactive", color: "bg-slate-400" },
|
|
18
|
+
{ value: "ON_HOLD", label: "On Hold", color: "bg-amber-500" },
|
|
19
|
+
{ value: "COMPLETED", label: "Completed", color: "bg-sky-500" },
|
|
20
|
+
{ value: "ARCHIVED", label: "Archived", color: "bg-slate-300" },
|
|
21
|
+
];
|
|
66
22
|
export default function Editor() {
|
|
67
|
-
// Getting dispatch from selected document
|
|
68
23
|
const [doc, dispatch] = useSelectedBuilderProfileDocument();
|
|
69
24
|
const state = doc?.state.global;
|
|
70
|
-
// Get the parent folder node for the currently selected node
|
|
71
25
|
const parentFolder = useParentFolderForSelectedNode();
|
|
72
|
-
// Set the selected node to the parent folder node (close the editor)
|
|
73
26
|
function handleClose() {
|
|
74
27
|
setSelectedNode(parentFolder?.id);
|
|
75
28
|
}
|
|
76
|
-
// Track if we've already attempted to generate an ID
|
|
77
29
|
const idGeneratedRef = useRef(false);
|
|
78
30
|
// Auto-generate ID if not present (only once)
|
|
79
31
|
useEffect(() => {
|
|
80
32
|
if (!state?.id && !idGeneratedRef.current && dispatch) {
|
|
81
|
-
idGeneratedRef.current = true;
|
|
33
|
+
idGeneratedRef.current = true;
|
|
82
34
|
dispatch(actions.updateProfile({
|
|
83
35
|
id: doc.header.id,
|
|
84
36
|
}));
|
|
85
37
|
}
|
|
86
|
-
}, [state?.id, dispatch]);
|
|
38
|
+
}, [state?.id, dispatch, doc?.header.id]);
|
|
39
|
+
// Format date as "09 DEC 2025 10:52:30"
|
|
40
|
+
const formatLastModified = (isoString) => {
|
|
41
|
+
const date = new Date(isoString);
|
|
42
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
43
|
+
const months = [
|
|
44
|
+
"JAN",
|
|
45
|
+
"FEB",
|
|
46
|
+
"MAR",
|
|
47
|
+
"APR",
|
|
48
|
+
"MAY",
|
|
49
|
+
"JUN",
|
|
50
|
+
"JUL",
|
|
51
|
+
"AUG",
|
|
52
|
+
"SEP",
|
|
53
|
+
"OCT",
|
|
54
|
+
"NOV",
|
|
55
|
+
"DEC",
|
|
56
|
+
];
|
|
57
|
+
const month = months[date.getMonth()];
|
|
58
|
+
const year = date.getFullYear();
|
|
59
|
+
const hours = date.getHours().toString().padStart(2, "0");
|
|
60
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
61
|
+
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
62
|
+
return `${day} ${month} ${year} ${hours}:${minutes}:${seconds}`;
|
|
63
|
+
};
|
|
87
64
|
// Generate slug from name
|
|
88
65
|
const generateSlug = useCallback((name) => {
|
|
89
66
|
return name
|
|
90
67
|
.toLowerCase()
|
|
91
68
|
.trim()
|
|
92
|
-
.replace(/[^a-z0-9\s-]/g, "")
|
|
93
|
-
.replace(/\s+/g, "-")
|
|
94
|
-
.replace(/-+/g, "-")
|
|
95
|
-
.replace(/^-|-$/g, "");
|
|
69
|
+
.replace(/[^a-z0-9\s-]/g, "")
|
|
70
|
+
.replace(/\s+/g, "-")
|
|
71
|
+
.replace(/-+/g, "-")
|
|
72
|
+
.replace(/^-|-$/g, "");
|
|
96
73
|
}, []);
|
|
97
|
-
// Handle field changes
|
|
74
|
+
// Handle basic profile field changes
|
|
98
75
|
const handleFieldChange = useCallback((field, value) => {
|
|
99
76
|
if (!dispatch) {
|
|
100
|
-
console.error("Dispatch function not available");
|
|
101
77
|
toast(`Failed to update ${field} - no dispatch function`, {
|
|
102
78
|
type: "error",
|
|
103
79
|
});
|
|
104
80
|
return;
|
|
105
81
|
}
|
|
106
|
-
// If updating name and value is not empty, also update slug
|
|
107
82
|
if (field === "name" && value && value.trim()) {
|
|
108
83
|
const slug = generateSlug(value);
|
|
109
|
-
dispatch(actions.updateProfile({
|
|
110
|
-
name: value,
|
|
111
|
-
slug: slug,
|
|
112
|
-
}));
|
|
84
|
+
dispatch(actions.updateProfile({ name: value, slug }));
|
|
113
85
|
}
|
|
114
86
|
else {
|
|
115
|
-
|
|
116
|
-
const updateAction = actions.updateProfile({
|
|
117
|
-
[field]: value,
|
|
118
|
-
});
|
|
119
|
-
dispatch(updateAction);
|
|
87
|
+
dispatch(actions.updateProfile({ [field]: value }));
|
|
120
88
|
}
|
|
121
89
|
}, [dispatch, generateSlug]);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
90
|
+
// Handle status change
|
|
91
|
+
const handleStatusChange = useCallback((status) => {
|
|
92
|
+
if (!dispatch)
|
|
93
|
+
return;
|
|
94
|
+
dispatch(actions.updateProfile({ status }));
|
|
95
|
+
}, [dispatch]);
|
|
96
|
+
// Handle type change
|
|
97
|
+
const handleTypeChange = useCallback((type) => {
|
|
98
|
+
if (!dispatch)
|
|
99
|
+
return;
|
|
100
|
+
dispatch(actions.updateProfile({ type }));
|
|
101
|
+
}, [dispatch]);
|
|
102
|
+
// Skill handlers
|
|
103
|
+
const handleAddSkill = useCallback((skill) => {
|
|
104
|
+
if (!dispatch)
|
|
105
|
+
return;
|
|
106
|
+
dispatch(actions.addSkill({ skill }));
|
|
107
|
+
}, [dispatch]);
|
|
108
|
+
const handleRemoveSkill = useCallback((skill) => {
|
|
109
|
+
if (!dispatch)
|
|
110
|
+
return;
|
|
111
|
+
dispatch(actions.removeSkill({ skill }));
|
|
112
|
+
}, [dispatch]);
|
|
113
|
+
// Scope handlers
|
|
114
|
+
const handleAddScope = useCallback((scope) => {
|
|
115
|
+
if (!dispatch)
|
|
116
|
+
return;
|
|
117
|
+
dispatch(actions.addScope({ scope }));
|
|
118
|
+
}, [dispatch]);
|
|
119
|
+
const handleRemoveScope = useCallback((scope) => {
|
|
120
|
+
if (!dispatch)
|
|
121
|
+
return;
|
|
122
|
+
dispatch(actions.removeScope({ scope }));
|
|
123
|
+
}, [dispatch]);
|
|
124
|
+
// Link handlers
|
|
125
|
+
const handleAddLink = useCallback((link) => {
|
|
126
|
+
if (!dispatch)
|
|
127
|
+
return;
|
|
128
|
+
dispatch(actions.addLink({ id: link.id, url: link.url, label: link.label }));
|
|
129
|
+
}, [dispatch]);
|
|
130
|
+
const handleEditLink = useCallback((link) => {
|
|
131
|
+
if (!dispatch)
|
|
132
|
+
return;
|
|
133
|
+
dispatch(actions.editLink({ id: link.id, url: link.url, label: link.label }));
|
|
134
|
+
}, [dispatch]);
|
|
135
|
+
const handleRemoveLink = useCallback((id) => {
|
|
136
|
+
if (!dispatch)
|
|
137
|
+
return;
|
|
138
|
+
dispatch(actions.removeLink({ id }));
|
|
139
|
+
}, [dispatch]);
|
|
140
|
+
// Contributor handlers
|
|
141
|
+
const handleAddContributor = useCallback((contributorPHID) => {
|
|
142
|
+
if (!dispatch)
|
|
143
|
+
return;
|
|
144
|
+
dispatch(actions.addContributor({ contributorPHID }));
|
|
145
|
+
}, [dispatch]);
|
|
146
|
+
const handleRemoveContributor = useCallback((contributorPHID) => {
|
|
147
|
+
if (!dispatch)
|
|
148
|
+
return;
|
|
149
|
+
dispatch(actions.removeContributor({ contributorPHID }));
|
|
150
|
+
}, [dispatch]);
|
|
151
|
+
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: `
|
|
152
|
+
.builder-editor input, .builder-editor textarea, .builder-editor select {
|
|
153
|
+
font-family: 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
154
|
+
}
|
|
155
|
+
.builder-editor .section-card {
|
|
156
|
+
background: white;
|
|
157
|
+
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
158
|
+
border-radius: 16px;
|
|
159
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.02);
|
|
160
|
+
transition: box-shadow 0.2s ease, transform 0.2s ease;
|
|
161
|
+
}
|
|
162
|
+
.builder-editor .section-card:hover {
|
|
163
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.04);
|
|
164
|
+
}
|
|
165
|
+
.builder-editor .field-label {
|
|
166
|
+
font-size: 0.8125rem;
|
|
167
|
+
font-weight: 600;
|
|
168
|
+
color: #374151;
|
|
169
|
+
letter-spacing: -0.01em;
|
|
170
|
+
margin-bottom: 0.5rem;
|
|
171
|
+
display: block;
|
|
172
|
+
}
|
|
173
|
+
.builder-editor .field-hint {
|
|
174
|
+
font-size: 0.75rem;
|
|
175
|
+
color: #9CA3AF;
|
|
176
|
+
margin-top: 0.375rem;
|
|
177
|
+
letter-spacing: -0.01em;
|
|
178
|
+
}
|
|
179
|
+
.builder-editor .meta-value {
|
|
180
|
+
font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
|
|
181
|
+
font-size: 0.8125rem;
|
|
182
|
+
color: #6B7280;
|
|
183
|
+
background: #F9FAFB;
|
|
184
|
+
padding: 0.5rem 0.75rem;
|
|
185
|
+
border-radius: 8px;
|
|
186
|
+
border: 1px solid #E5E7EB;
|
|
187
|
+
}
|
|
188
|
+
.builder-editor .type-toggle {
|
|
189
|
+
display: flex;
|
|
190
|
+
background: #F3F4F6;
|
|
191
|
+
border-radius: 10px;
|
|
192
|
+
padding: 4px;
|
|
193
|
+
gap: 4px;
|
|
194
|
+
}
|
|
195
|
+
.builder-editor .type-toggle button {
|
|
196
|
+
flex: 1;
|
|
197
|
+
padding: 0.625rem 1rem;
|
|
198
|
+
font-size: 0.875rem;
|
|
199
|
+
font-weight: 500;
|
|
200
|
+
border-radius: 8px;
|
|
201
|
+
border: none;
|
|
202
|
+
cursor: pointer;
|
|
203
|
+
transition: all 0.2s ease;
|
|
204
|
+
color: #6B7280;
|
|
205
|
+
background: transparent;
|
|
206
|
+
}
|
|
207
|
+
.builder-editor .type-toggle button.active {
|
|
208
|
+
background: white;
|
|
209
|
+
color: #111827;
|
|
210
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
211
|
+
}
|
|
212
|
+
.builder-editor .type-toggle button:not(.active):hover {
|
|
213
|
+
color: #374151;
|
|
214
|
+
background: rgba(255, 255, 255, 0.5);
|
|
215
|
+
}
|
|
216
|
+
.builder-editor .status-select {
|
|
217
|
+
appearance: none;
|
|
218
|
+
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");
|
|
219
|
+
background-position: right 0.75rem center;
|
|
220
|
+
background-repeat: no-repeat;
|
|
221
|
+
background-size: 1.25em 1.25em;
|
|
222
|
+
padding-right: 2.5rem;
|
|
223
|
+
}
|
|
224
|
+
` }), _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", { children: [_jsx("h1", { className: "text-2xl font-semibold text-slate-900 tracking-tight", children: "Builder Profile" }), _jsx("p", { className: "text-slate-500 mt-1 text-sm", children: "Configure your builder identity and capabilities" })] }) }), 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: [_jsx("label", { className: "field-label", children: "Builder 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 Builder ID", onClick: () => {
|
|
225
|
+
void navigator.clipboard.writeText(doc?.header.id || "");
|
|
226
|
+
toast("Copied Builder ID!", { type: "success" });
|
|
227
|
+
}, 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
|
|
228
|
+
? formatLastModified(state.lastModified)
|
|
229
|
+
: "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: [_jsx("label", { className: "field-label", children: "Builder Name" }), _jsx(TextInput, { className: "w-full", defaultValue: state?.name || "", onBlur: (e) => {
|
|
230
|
+
if (e.target.value !== state?.name) {
|
|
231
|
+
handleFieldChange("name", e.target.value);
|
|
232
|
+
}
|
|
233
|
+
}, placeholder: "Enter your name or team name" })] }), _jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Code" }), _jsx(TextInput, { className: "w-full", defaultValue: state?.code || "", onBlur: (e) => {
|
|
234
|
+
if (e.target.value !== state?.code) {
|
|
235
|
+
handleFieldChange("code", e.target.value);
|
|
236
|
+
}
|
|
237
|
+
}, 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) => {
|
|
238
|
+
handleFieldChange("slug", e.target.value);
|
|
239
|
+
}, 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) => {
|
|
240
|
+
if (e.target.value) {
|
|
241
|
+
handleStatusChange(e.target.value);
|
|
242
|
+
}
|
|
243
|
+
}, 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"
|
|
244
|
+
? "Teams can add contributors to their profile"
|
|
245
|
+
: "Individual profiles represent a single builder" })] })] })] }), _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" }) }), "About"] }), _jsxs("div", { children: [_jsx("label", { className: "field-label", children: "Description" }), _jsx(Textarea, { className: "w-full", defaultValue: state?.description || "", onBlur: (e) => {
|
|
246
|
+
if (e.target.value !== state?.description) {
|
|
247
|
+
handleFieldChange("description", e.target.value);
|
|
248
|
+
}
|
|
249
|
+
}, placeholder: "Describe your expertise, focus areas, and what you bring to the ecosystem...", rows: 4, autoExpand: true }), _jsx("p", { className: "field-hint", children: "A compelling description helps others understand your capabilities" })] })] }), _jsx(SkillsSection, { skills: state?.skilss || [], 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" })] })] }));
|
|
138
250
|
}
|
package/dist/editors/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../editors/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../editors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/editors/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import manifestJson from "./powerhouse.manifest.json" with { type: "json" };
|
|
2
|
-
import * as documentModelsExports from
|
|
3
|
-
import * as editorsExports from
|
|
2
|
+
import * as documentModelsExports from "./document-models/index.js";
|
|
3
|
+
import * as editorsExports from "./editors/index.js";
|
|
4
4
|
export const manifest = manifestJson;
|
|
5
5
|
export const documentModels = Object.values(documentModelsExports);
|
|
6
6
|
export const editors = Object.values(editorsExports);
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "",
|
|
3
|
-
"description": "",
|
|
4
|
-
"category": "",
|
|
2
|
+
"name": "powerhouse/builder-profile",
|
|
3
|
+
"description": "builder profile",
|
|
4
|
+
"category": "Project Management",
|
|
5
5
|
"publisher": {
|
|
6
6
|
"name": "",
|
|
7
7
|
"url": ""
|
|
8
8
|
},
|
|
9
|
-
"documentModels": [
|
|
9
|
+
"documentModels": [
|
|
10
|
+
{
|
|
11
|
+
"id": "powerhouse/builder-profile",
|
|
12
|
+
"name": "Builder Profile"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
10
15
|
"editors": [],
|
|
11
16
|
"apps": [],
|
|
12
17
|
"subgraphs": [],
|