@powerhousedao/vetra-builder-package 0.0.10 → 0.0.11

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.
@@ -58,12 +58,13 @@ export const reducer = {
58
58
  updatePackageOperation(state, action, dispatch) {
59
59
  const { id, title, description } = action.input;
60
60
  for (const space of state.spaces) {
61
- let packageObject = space.packages.find((packageObject) => packageObject.id === id);
62
- if (packageObject) {
63
- packageObject = {
64
- ...packageObject,
65
- name: title ?? packageObject.name,
66
- description: description ?? packageObject.description ?? "",
61
+ const packageIndex = space.packages.findIndex((packageObject) => packageObject.id === id);
62
+ if (packageIndex !== -1) {
63
+ // Update the package in place
64
+ space.packages[packageIndex] = {
65
+ ...space.packages[packageIndex],
66
+ name: title ?? space.packages[packageIndex].name,
67
+ description: description ?? space.packages[packageIndex].description ?? "",
67
68
  };
68
69
  }
69
70
  }
@@ -21,6 +21,7 @@ export default function Editor(props) {
21
21
  const [newPackageCategory, setNewPackageCategory] = useState("");
22
22
  const [newPackageGithub, setNewPackageGithub] = useState("");
23
23
  const [newPackageNpm, setNewPackageNpm] = useState("");
24
+ const [newPackageVetraDrive, setNewPackageVetraDrive] = useState("");
24
25
  const [newMemberAddress, setNewMemberAddress] = useState("");
25
26
  const [selectedSpaceForPackage, setSelectedSpaceForPackage] = useState("");
26
27
  // Editing form states
@@ -31,6 +32,7 @@ export default function Editor(props) {
31
32
  const [editingPackageCategory, setEditingPackageCategory] = useState("");
32
33
  const [editingPackageGithub, setEditingPackageGithub] = useState("");
33
34
  const [editingPackageNpm, setEditingPackageNpm] = useState("");
35
+ const [editingPackageVetraDrive, setEditingPackageVetraDrive] = useState("");
34
36
  const { state: { global } } = typedDocument;
35
37
  const { profile, spaces, members } = global;
36
38
  // Profile handlers
@@ -115,6 +117,7 @@ export default function Editor(props) {
115
117
  category: newPackageCategory.trim() || null,
116
118
  github: newPackageGithub.trim() || null,
117
119
  npm: newPackageNpm.trim() || null,
120
+ vetraDriveUrl: newPackageVetraDrive.trim() || null,
118
121
  spaceId: selectedSpaceForPackage,
119
122
  author: {
120
123
  name: profile.name,
@@ -126,10 +129,11 @@ export default function Editor(props) {
126
129
  setNewPackageCategory("");
127
130
  setNewPackageGithub("");
128
131
  setNewPackageNpm("");
132
+ setNewPackageVetraDrive("");
129
133
  setSelectedSpaceForPackage("");
130
134
  setIsAddingPackage(false);
131
135
  }
132
- }, [newPackageName, newPackageDescription, newPackageCategory, newPackageGithub, newPackageNpm, selectedSpaceForPackage, profile, dispatch]);
136
+ }, [newPackageName, newPackageDescription, newPackageCategory, newPackageGithub, newPackageNpm, newPackageVetraDrive, selectedSpaceForPackage, profile, dispatch]);
133
137
  const handleDeletePackage = useCallback((packageId) => {
134
138
  dispatch(actions.deletePackage({ id: packageId }));
135
139
  }, [dispatch]);
@@ -144,38 +148,28 @@ export default function Editor(props) {
144
148
  setEditingPackageCategory(pkg.category || "");
145
149
  setEditingPackageGithub(pkg.github || "");
146
150
  setEditingPackageNpm(pkg.npm || "");
151
+ setEditingPackageVetraDrive(pkg.vetraDriveUrl || "");
147
152
  break;
148
153
  }
149
154
  }
150
155
  }, [spaces]);
151
156
  const handleSavePackageEdit = useCallback(() => {
152
157
  if (editingPackageId && editingPackageName.trim()) {
153
- // Note: We'll need to add updatePackage action to the document model
154
- // For now, we'll delete and recreate the package
155
- const space = spaces.find(s => s.packages.some(p => p.id === editingPackageId));
156
- if (space) {
157
- const originalPackage = space.packages.find(p => p.id === editingPackageId);
158
- if (originalPackage) {
159
- dispatch(actions.deletePackage({ id: editingPackageId }));
160
- dispatch(actions.addPackage({
161
- name: editingPackageName.trim(),
162
- description: editingPackageDescription.trim() || null,
163
- category: editingPackageCategory.trim() || null,
164
- github: editingPackageGithub.trim() || null,
165
- npm: editingPackageNpm.trim() || null,
166
- spaceId: space.id,
167
- author: originalPackage.author,
168
- }));
169
- }
170
- }
158
+ // Use the proper updatePackage action
159
+ dispatch(actions.updatePackage({
160
+ id: editingPackageId,
161
+ title: editingPackageName.trim(),
162
+ description: editingPackageDescription.trim() || null,
163
+ }));
171
164
  setEditingPackageId(null);
172
165
  setEditingPackageName("");
173
166
  setEditingPackageDescription("");
174
167
  setEditingPackageCategory("");
175
168
  setEditingPackageGithub("");
176
169
  setEditingPackageNpm("");
170
+ setEditingPackageVetraDrive("");
177
171
  }
178
- }, [editingPackageId, editingPackageName, editingPackageDescription, editingPackageCategory, editingPackageGithub, editingPackageNpm, spaces, dispatch]);
172
+ }, [editingPackageId, editingPackageName, editingPackageDescription, dispatch]);
179
173
  const handleCancelPackageEdit = useCallback(() => {
180
174
  setEditingPackageId(null);
181
175
  setEditingPackageName("");
@@ -183,6 +177,7 @@ export default function Editor(props) {
183
177
  setEditingPackageCategory("");
184
178
  setEditingPackageGithub("");
185
179
  setEditingPackageNpm("");
180
+ setEditingPackageVetraDrive("");
186
181
  }, []);
187
182
  // Member handlers
188
183
  const handleAddMember = useCallback(() => {
@@ -197,5 +192,5 @@ export default function Editor(props) {
197
192
  return (_jsxs("div", { className: "html-defaults-container min-h-screen bg-gray-50", children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "py-6", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("div", { className: "flex-shrink-0", children: profile.logo ? (_jsx("img", { className: "w-12 h-12 rounded-lg object-cover", src: profile.logo, alt: "Logo" })) : (_jsx("div", { className: "w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center", children: _jsx("svg", { className: "w-6 h-6 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: profile.name || "Builder Account" }), _jsx("p", { className: "text-sm text-gray-500", children: profile.slug ? `@${profile.slug}` : "Manage your builder profile and packages" })] })] }), _jsx("div", { className: "flex items-center space-x-3", children: _jsx(Button, { color: "light", onClick: () => setIsEditingProfile(!isEditingProfile), children: isEditingProfile ? "Cancel" : "Edit Profile" }) })] }) }) }) }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [_jsxs("div", { className: "lg:col-span-2 space-y-8", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Profile Information" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage your builder profile details" })] }), _jsx("div", { className: "p-6", children: isEditingProfile ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-6", children: [_jsx(StringField, { name: "profileName", label: "Profile Name", value: profile.name, onChange: (e) => handleSetProfileName(e.target.value), placeholder: "Enter your profile name", description: "Your public display name" }), _jsx(StringField, { name: "slug", label: "Slug", value: profile.slug, onChange: (e) => handleSetSlug(e.target.value), placeholder: "your-slug", description: "Unique identifier for your profile (used in URLs)" }), _jsx(StringField, { name: "description", label: "Description", value: profile.description || "", onChange: (e) => handleSetProfileDescription(e.target.value), placeholder: "Tell us about yourself and your work", description: "Brief description of your work and interests" }), _jsx(UrlField, { name: "logo", label: "Logo URL", value: profile.logo || "", onChange: (e) => handleSetLogo(e.target.value), placeholder: "https://example.com/logo.png", description: "URL to your profile logo image" }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: "Social Links" }), _jsx(UrlField, { name: "github", label: "GitHub", value: profile.socials.github || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, github: e.target.value }), placeholder: "https://github.com/username" }), _jsx(UrlField, { name: "website", label: "Website", value: profile.socials.website || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, website: e.target.value }), placeholder: "https://your-website.com" }), _jsx(UrlField, { name: "x", label: "X (Twitter)", value: profile.socials.xProfile || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, x: e.target.value }), placeholder: "https://x.com/username" })] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsEditingProfile(false), children: "Cancel" }), _jsx(Button, { onClick: () => setIsEditingProfile(false), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Name" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.name || "Not set" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Slug" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.slug ? `@${profile.slug}` : "Not set" })] })] }), profile.description && (_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Description" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.description })] })), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Social Links" }), _jsxs("div", { className: "mt-2 flex space-x-4", children: [profile.socials.github && (_jsx("a", { href: profile.socials.github, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "GitHub" })), profile.socials.website && (_jsx("a", { href: profile.socials.website, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "Website" })), profile.socials.xProfile && (_jsx("a", { href: profile.socials.xProfile, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "X (Twitter)" })), !profile.socials.github && !profile.socials.website && !profile.socials.xProfile && (_jsx("span", { className: "text-gray-500 text-sm", children: "No social links added" }))] })] })] })) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Spaces" }), _jsx("p", { className: "text-sm text-gray-500", children: "Organize your packages into spaces" })] }), _jsx(Button, { onClick: () => setIsAddingSpace(true), children: "Add Space" })] }) }), _jsxs("div", { className: "p-6", children: [isAddingSpace ? (_jsx("div", { className: "p-4 bg-gray-50 rounded-lg", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "spaceTitle", label: "Space Title", value: newSpaceTitle, onChange: (e) => setNewSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "spaceDescription", label: "Description (optional)", value: newSpaceDescription, onChange: (e) => setNewSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingSpace(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddSpace, disabled: !newSpaceTitle.trim(), children: "Add Space" })] })] }) }) })) : null, _jsx("div", { className: "space-y-4", children: spaces.length > 0 ? (spaces.map((space) => (_jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [editingSpaceId === space.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "editingSpaceTitle", label: "Space Title", value: editingSpaceTitle, onChange: (e) => setEditingSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "editingSpaceDescription", label: "Description (optional)", value: editingSpaceDescription, onChange: (e) => setEditingSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelSpaceEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSaveSpaceEdit, disabled: !editingSpaceTitle.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: space.title }), space.description && (_jsx("p", { className: "text-sm text-gray-500 mt-1", children: space.description })), _jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [space.packages.length, " package", space.packages.length !== 1 ? 's' : ''] })] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingSpace(space.id), children: "Edit" }), _jsx(Button, { color: "light", size: "sm", onClick: () => {
198
193
  setSelectedSpaceForPackage(space.id);
199
194
  setIsAddingPackage(true);
200
- }, children: "Add Package" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeleteSpace(space.id), children: "Delete" })] })] })), space.packages.length > 0 && (_jsx("div", { className: "mt-4 space-y-2", children: space.packages.map((pkg) => (_jsx("div", { className: "p-3 bg-gray-50 rounded border", children: editingPackageId === pkg.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-3", children: [_jsx(StringField, { name: "editingPackageName", label: "Package Name", value: editingPackageName, onChange: (e) => setEditingPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "editingPackageDescription", label: "Description", value: editingPackageDescription, onChange: (e) => setEditingPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "editingPackageCategory", label: "Category", value: editingPackageCategory, onChange: (e) => setEditingPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "editingPackageGithub", label: "GitHub URL", value: editingPackageGithub, onChange: (e) => setEditingPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "editingPackageNpm", label: "NPM URL", value: editingPackageNpm, onChange: (e) => setEditingPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelPackageEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSavePackageEdit, disabled: !editingPackageName.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900", children: pkg.name }), pkg.description && (_jsx("p", { className: "text-sm text-gray-500", children: pkg.description })), pkg.category && (_jsxs("p", { className: "text-xs text-gray-400", children: ["Category: ", pkg.category] }))] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingPackage(pkg.id), children: "Edit" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeletePackage(pkg.id), children: "Remove" })] })] })) }, pkg.id))) }))] }, space.id)))) : (_jsx("div", { className: "text-center py-8 text-gray-500", children: _jsx("p", { children: "No spaces created yet. Create a space to organize your packages." }) })) })] })] }), isAddingPackage && (_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Add Package" }) }), _jsx("div", { className: "p-6", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "packageName", label: "Package Name", value: newPackageName, onChange: (e) => setNewPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "packageDescription", label: "Description", value: newPackageDescription, onChange: (e) => setNewPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "packageCategory", label: "Category", value: newPackageCategory, onChange: (e) => setNewPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "packageGithub", label: "GitHub URL", value: newPackageGithub, onChange: (e) => setNewPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "packageNpm", label: "NPM URL", value: newPackageNpm, onChange: (e) => setNewPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingPackage(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddPackage, disabled: !newPackageName.trim() || !selectedSpaceForPackage, children: "Add Package" })] })] }) }) })] }))] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Team Members" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage team access" })] }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex space-x-2", children: [_jsx("input", { type: "text", value: newMemberAddress, onChange: (e) => setNewMemberAddress(e.target.value), placeholder: "0x...", className: "flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" }), _jsx(Button, { onClick: handleAddMember, disabled: !newMemberAddress.trim(), children: "Add" })] }), _jsx("div", { className: "space-y-2", children: members.length > 0 ? (members.map((address, index) => (_jsxs("div", { className: "flex items-center justify-between p-2 bg-gray-50 rounded border", children: [_jsx("span", { className: "text-sm font-mono text-gray-700 truncate", children: address }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleRemoveMember(address), children: "Remove" })] }, index)))) : (_jsx("p", { className: "text-sm text-gray-500", children: "No team members added yet" })) })] }) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Quick Stats" }) }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Spaces" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.length })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Total Packages" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.reduce((total, space) => total + space.packages.length, 0) })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Team Members" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: members.length })] })] }) })] })] })] }) })] }));
195
+ }, children: "Add Package" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeleteSpace(space.id), children: "Delete" })] })] })), space.packages.length > 0 && (_jsx("div", { className: "mt-4 space-y-2", children: space.packages.map((pkg) => (_jsx("div", { className: "p-3 bg-gray-50 rounded border", children: editingPackageId === pkg.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-3", children: [_jsx(StringField, { name: "editingPackageName", label: "Package Name", value: editingPackageName, onChange: (e) => setEditingPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "editingPackageDescription", label: "Description", value: editingPackageDescription, onChange: (e) => setEditingPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "editingPackageCategory", label: "Category", value: editingPackageCategory, onChange: (e) => setEditingPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "editingPackageGithub", label: "GitHub URL", value: editingPackageGithub, onChange: (e) => setEditingPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "editingPackageNpm", label: "NPM URL", value: editingPackageNpm, onChange: (e) => setEditingPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsx(UrlField, { name: "editingPackageVetraDrive", label: "Vetra Drive URL", value: editingPackageVetraDrive, onChange: (e) => setEditingPackageVetraDrive(e.target.value), placeholder: "https://vetra.to/drive/..." }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelPackageEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSavePackageEdit, disabled: !editingPackageName.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900", children: pkg.name }), pkg.description && (_jsx("p", { className: "text-sm text-gray-500", children: pkg.description })), pkg.category && (_jsxs("p", { className: "text-xs text-gray-400", children: ["Category: ", pkg.category] })), pkg.vetraDriveUrl && (_jsx("p", { className: "text-xs text-blue-600", children: _jsx("a", { href: pkg.vetraDriveUrl, target: "_blank", rel: "noopener noreferrer", className: "hover:underline", children: "Vetra Drive" }) }))] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingPackage(pkg.id), children: "Edit" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeletePackage(pkg.id), children: "Remove" })] })] })) }, pkg.id))) }))] }, space.id)))) : (_jsx("div", { className: "text-center py-8 text-gray-500", children: _jsx("p", { children: "No spaces created yet. Create a space to organize your packages." }) })) })] })] }), isAddingPackage && (_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Add Package" }) }), _jsx("div", { className: "p-6", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "packageName", label: "Package Name", value: newPackageName, onChange: (e) => setNewPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "packageDescription", label: "Description", value: newPackageDescription, onChange: (e) => setNewPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "packageCategory", label: "Category", value: newPackageCategory, onChange: (e) => setNewPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "packageGithub", label: "GitHub URL", value: newPackageGithub, onChange: (e) => setNewPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "packageNpm", label: "NPM URL", value: newPackageNpm, onChange: (e) => setNewPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsx(UrlField, { name: "packageVetraDrive", label: "Vetra Drive URL", value: newPackageVetraDrive, onChange: (e) => setNewPackageVetraDrive(e.target.value), placeholder: "https://vetra.to/drive/..." }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingPackage(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddPackage, disabled: !newPackageName.trim() || !selectedSpaceForPackage, children: "Add Package" })] })] }) }) })] }))] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Team Members" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage team access" })] }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex space-x-2", children: [_jsx("input", { type: "text", value: newMemberAddress, onChange: (e) => setNewMemberAddress(e.target.value), placeholder: "0x...", className: "flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" }), _jsx(Button, { onClick: handleAddMember, disabled: !newMemberAddress.trim(), children: "Add" })] }), _jsx("div", { className: "space-y-2", children: members.length > 0 ? (members.map((address, index) => (_jsxs("div", { className: "flex items-center justify-between p-2 bg-gray-50 rounded border", children: [_jsx("span", { className: "text-sm font-mono text-gray-700 truncate", children: address }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleRemoveMember(address), children: "Remove" })] }, index)))) : (_jsx("p", { className: "text-sm text-gray-500", children: "No team members added yet" })) })] }) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Quick Stats" }) }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Spaces" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.length })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Total Packages" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.reduce((total, space) => total + space.packages.length, 0) })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Team Members" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: members.length })] })] }) })] })] })] }) })] }));
201
196
  }
@@ -0,0 +1,27 @@
1
+ import type { BuilderAccountAction } from "../../document-models/builder-account/gen/actions.js";
2
+ import type { BuilderAccountState } from "document-models/builder-account/index.js";
3
+ import type { DB } from "./schema.js";
4
+ import type { IRelationalDb } from "document-drive";
5
+ export declare class BuilderAccountHandlers {
6
+ private db;
7
+ private dbHelpers;
8
+ constructor(db: IRelationalDb<DB>);
9
+ handleBuilderAccountOperation(documentId: string, action: BuilderAccountAction, state: BuilderAccountState, driveId?: string): Promise<void>;
10
+ private handleSetLogo;
11
+ private handleSetProfileName;
12
+ private handleSetSlug;
13
+ private handleSetProfileDescription;
14
+ private handleUpdateSocials;
15
+ private handleAddMember;
16
+ private handleRemoveMember;
17
+ private handleAddSpace;
18
+ private handleDeleteSpace;
19
+ private handleSetSpaceTitle;
20
+ private handleSetSpaceDescription;
21
+ private handleReorderSpaces;
22
+ private handleAddPackage;
23
+ private handleSetPackageDriveId;
24
+ private handleUpdatePackage;
25
+ private handleReorderPackages;
26
+ private handleDeletePackage;
27
+ }
@@ -0,0 +1,249 @@
1
+ import { toPascalCase } from "document-drive/utils/misc";
2
+ import { DatabaseHelpers } from "./database-helpers.js";
3
+ export class BuilderAccountHandlers {
4
+ db;
5
+ dbHelpers;
6
+ constructor(db) {
7
+ this.db = db;
8
+ this.dbHelpers = new DatabaseHelpers(db);
9
+ }
10
+ async handleBuilderAccountOperation(documentId, action, state, driveId) {
11
+ switch (action.type) {
12
+ // Profile operations
13
+ case "SET_LOGO":
14
+ await this.handleSetLogo(documentId, action, state);
15
+ break;
16
+ case "SET_PROFILE_NAME":
17
+ await this.handleSetProfileName(documentId, action, state);
18
+ break;
19
+ case "SET_SLUG":
20
+ await this.handleSetSlug(documentId, action, state);
21
+ break;
22
+ case "SET_PROFILE_DESCRIPTION":
23
+ await this.handleSetProfileDescription(documentId, action, state);
24
+ break;
25
+ case "UPDATE_SOCIALS":
26
+ await this.handleUpdateSocials(documentId, action, state);
27
+ break;
28
+ // Members operations
29
+ case "ADD_MEMBER":
30
+ await this.handleAddMember(documentId, action, state);
31
+ break;
32
+ case "REMOVE_MEMBER":
33
+ await this.handleRemoveMember(documentId, action, state);
34
+ break;
35
+ // Spaces operations
36
+ case "ADD_SPACE":
37
+ await this.handleAddSpace(documentId, action, state);
38
+ break;
39
+ case "DELETE_SPACE":
40
+ await this.handleDeleteSpace(documentId, action, state);
41
+ break;
42
+ case "SET_SPACE_TITLE":
43
+ await this.handleSetSpaceTitle(documentId, action, state);
44
+ break;
45
+ case "SET_SPACE_DESCRIPTION":
46
+ await this.handleSetSpaceDescription(documentId, action, state);
47
+ break;
48
+ case "REORDER_SPACES":
49
+ await this.handleReorderSpaces(documentId, action, state);
50
+ break;
51
+ // Packages operations
52
+ case "ADD_PACKAGE":
53
+ await this.handleAddPackage(documentId, action, state);
54
+ break;
55
+ case "SET_PACKAGE_DRIVE_ID":
56
+ await this.handleSetPackageDriveId(documentId, action, state);
57
+ break;
58
+ case "UPDATE_PACKAGE":
59
+ await this.handleUpdatePackage(documentId, action, state);
60
+ break;
61
+ case "REORDER_PACKAGES":
62
+ await this.handleReorderPackages(documentId, action, state);
63
+ break;
64
+ case "DELETE_PACKAGE":
65
+ await this.handleDeletePackage(documentId, action, state);
66
+ break;
67
+ }
68
+ }
69
+ // Profile operations
70
+ async handleSetLogo(documentId, action, state) {
71
+ await this.dbHelpers.ensureBuilderAccount(documentId);
72
+ await this.dbHelpers.updateBuilderAccount(documentId, {
73
+ profile_logo: action.input.logoUrl,
74
+ });
75
+ }
76
+ async handleSetProfileName(documentId, action, state) {
77
+ await this.dbHelpers.ensureBuilderAccount(documentId);
78
+ await this.dbHelpers.updateBuilderAccount(documentId, {
79
+ profile_name: action.input.name,
80
+ });
81
+ }
82
+ async handleSetSlug(documentId, action, state) {
83
+ await this.dbHelpers.ensureBuilderAccount(documentId);
84
+ await this.dbHelpers.updateBuilderAccount(documentId, {
85
+ profile_slug: action.input.slug,
86
+ });
87
+ }
88
+ async handleSetProfileDescription(documentId, action, state) {
89
+ await this.dbHelpers.ensureBuilderAccount(documentId);
90
+ await this.dbHelpers.updateBuilderAccount(documentId, {
91
+ profile_description: action.input.description,
92
+ });
93
+ }
94
+ async handleUpdateSocials(documentId, action, state) {
95
+ await this.dbHelpers.ensureBuilderAccount(documentId);
96
+ await this.dbHelpers.updateBuilderAccount(documentId, {
97
+ profile_socials_x: action.input.x,
98
+ profile_socials_github: action.input.github,
99
+ profile_socials_website: action.input.website,
100
+ });
101
+ }
102
+ // Members operations
103
+ async handleAddMember(documentId, action, state) {
104
+ await this.dbHelpers.ensureBuilderAccount(documentId);
105
+ if (!action.input.ethAddress)
106
+ return;
107
+ const memberExists = await this.dbHelpers.memberExists(documentId, action.input.ethAddress);
108
+ if (!memberExists) {
109
+ await this.db
110
+ .insertInto("builder_account_members")
111
+ .values({
112
+ id: action.input.ethAddress,
113
+ builder_account_id: documentId,
114
+ eth_address: action.input.ethAddress,
115
+ created_at: new Date(),
116
+ })
117
+ .execute();
118
+ }
119
+ }
120
+ async handleRemoveMember(documentId, action, state) {
121
+ if (!action.input.ethAddress)
122
+ return;
123
+ await this.db
124
+ .deleteFrom("builder_account_members")
125
+ .where("builder_account_id", "=", documentId)
126
+ .where("eth_address", "=", action.input.ethAddress)
127
+ .execute();
128
+ }
129
+ // Spaces operations
130
+ async handleAddSpace(documentId, action, state) {
131
+ await this.dbHelpers.ensureBuilderAccount(documentId);
132
+ const spaceId = toPascalCase(action.input.title);
133
+ await this.db
134
+ .insertInto("builder_spaces")
135
+ .values({
136
+ id: spaceId,
137
+ builder_account_id: documentId,
138
+ title: action.input.title,
139
+ description: action.input.description || null,
140
+ sort_order: 0,
141
+ created_at: new Date(),
142
+ updated_at: new Date(),
143
+ })
144
+ .onConflict((oc) => oc.column("id").doNothing())
145
+ .execute();
146
+ }
147
+ async handleDeleteSpace(documentId, action, state) {
148
+ await this.db
149
+ .deleteFrom("builder_spaces")
150
+ .where("id", "=", action.input.id)
151
+ .where("builder_account_id", "=", documentId)
152
+ .execute();
153
+ }
154
+ async handleSetSpaceTitle(documentId, action, state) {
155
+ await this.dbHelpers.updateBuilderSpace(action.input.id, documentId, {
156
+ title: action.input.newTitle,
157
+ });
158
+ }
159
+ async handleSetSpaceDescription(documentId, action, state) {
160
+ await this.dbHelpers.updateBuilderSpace(action.input.id, documentId, {
161
+ description: action.input.description,
162
+ });
163
+ }
164
+ async handleReorderSpaces(documentId, action, state) {
165
+ const { ids, insertAfter } = action.input;
166
+ for (let i = 0; i < ids.length; i++) {
167
+ const spaceId = ids[i];
168
+ const sortOrder = insertAfter !== null ? Number(insertAfter) + i + 1 : i;
169
+ await this.dbHelpers.updateBuilderSpace(spaceId, documentId, {
170
+ sort_order: sortOrder,
171
+ });
172
+ }
173
+ }
174
+ // Packages operations
175
+ async handleAddPackage(documentId, action, state) {
176
+ const packageId = action.input.spaceId + "-" + toPascalCase(action.input.name);
177
+ await this.db
178
+ .insertInto("builder_packages")
179
+ .values({
180
+ id: `${packageId}`,
181
+ space_id: action.input.spaceId,
182
+ name: action.input.name,
183
+ description: action.input.description || null,
184
+ category: action.input.category || null,
185
+ author_name: action.input.author?.name || "",
186
+ author_website: action.input.author?.website || null,
187
+ github_url: action.input.github || null,
188
+ npm_url: action.input.npm || null,
189
+ vetra_drive_url: action.input.vetraDriveUrl || null,
190
+ drive_id: null,
191
+ sort_order: 0,
192
+ created_at: new Date(),
193
+ updated_at: new Date(),
194
+ })
195
+ .onConflict((oc) => oc.column("id").doNothing())
196
+ .execute();
197
+ // Add keywords if provided
198
+ if (action.input.keywords && action.input.keywords.length > 0) {
199
+ for (const keyword of action.input.keywords) {
200
+ await this.db
201
+ .insertInto("builder_package_keywords")
202
+ .values({
203
+ id: `${packageId}-${keyword}`,
204
+ package_id: packageId,
205
+ label: keyword,
206
+ created_at: new Date(),
207
+ })
208
+ .execute();
209
+ }
210
+ }
211
+ }
212
+ async handleSetPackageDriveId(documentId, action, state) {
213
+ await this.dbHelpers.updateBuilderPackage(action.input.packageId, {
214
+ drive_id: action.input.driveId,
215
+ });
216
+ }
217
+ async handleUpdatePackage(documentId, action, state) {
218
+ const updates = {};
219
+ if (action.input.title !== undefined) {
220
+ updates.name = action.input.title;
221
+ }
222
+ if (action.input.description !== undefined) {
223
+ updates.description = action.input.description;
224
+ }
225
+ await this.dbHelpers.updateBuilderPackage(action.input.id, updates);
226
+ }
227
+ async handleReorderPackages(documentId, action, state) {
228
+ const { ids, insertAfter, spaceId } = action.input;
229
+ for (let i = 0; i < ids.length; i++) {
230
+ const packageId = ids[i];
231
+ const sortOrder = insertAfter !== null ? Number(insertAfter) + i + 1 : i;
232
+ await this.db
233
+ .updateTable("builder_packages")
234
+ .set({
235
+ sort_order: sortOrder,
236
+ updated_at: new Date(),
237
+ })
238
+ .where("id", "=", packageId)
239
+ .where("space_id", "=", spaceId)
240
+ .execute();
241
+ }
242
+ }
243
+ async handleDeletePackage(documentId, action, state) {
244
+ await this.db
245
+ .deleteFrom("builder_packages")
246
+ .where("id", "=", action.input.id)
247
+ .execute();
248
+ }
249
+ }
@@ -0,0 +1,34 @@
1
+ import type { IRelationalDb } from "document-drive";
2
+ import type { DB } from "./schema.js";
3
+ export declare class DatabaseHelpers {
4
+ private db;
5
+ constructor(db: IRelationalDb<DB>);
6
+ /**
7
+ * Ensures a package exists in the database, creating it if it doesn't
8
+ */
9
+ ensurePackageExists(documentId: string, driveId: string): Promise<void>;
10
+ /**
11
+ * Ensures a builder account exists in the database, creating it if it doesn't
12
+ */
13
+ ensureBuilderAccount(documentId: string): Promise<void>;
14
+ /**
15
+ * Updates a package with the provided data
16
+ */
17
+ updatePackage(documentId: string, updates: Record<string, any>): Promise<void>;
18
+ /**
19
+ * Updates a builder account with the provided data
20
+ */
21
+ updateBuilderAccount(documentId: string, updates: Record<string, any>): Promise<void>;
22
+ /**
23
+ * Updates a builder space with the provided data
24
+ */
25
+ updateBuilderSpace(spaceId: string, documentId: string, updates: Record<string, any>): Promise<void>;
26
+ /**
27
+ * Updates a builder package with the provided data
28
+ */
29
+ updateBuilderPackage(packageId: string, updates: Record<string, any>): Promise<void>;
30
+ /**
31
+ * Checks if a member already exists for a builder account
32
+ */
33
+ memberExists(documentId: string, ethAddress: string): Promise<boolean>;
34
+ }
@@ -0,0 +1,121 @@
1
+ export class DatabaseHelpers {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ /**
7
+ * Ensures a package exists in the database, creating it if it doesn't
8
+ */
9
+ async ensurePackageExists(documentId, driveId) {
10
+ const existing = await this.db
11
+ .selectFrom("builder_packages")
12
+ .select("id")
13
+ .where("id", "=", documentId)
14
+ .executeTakeFirst();
15
+ if (!existing) {
16
+ await this.db
17
+ .insertInto("builder_packages")
18
+ .values({
19
+ id: documentId,
20
+ drive_id: driveId,
21
+ author_name: "",
22
+ name: "",
23
+ space_id: "",
24
+ })
25
+ .execute();
26
+ }
27
+ }
28
+ /**
29
+ * Ensures a builder account exists in the database, creating it if it doesn't
30
+ */
31
+ async ensureBuilderAccount(documentId) {
32
+ const existing = await this.db
33
+ .selectFrom("builder_accounts")
34
+ .select("id")
35
+ .where("id", "=", documentId)
36
+ .executeTakeFirst();
37
+ if (!existing) {
38
+ await this.db
39
+ .insertInto("builder_accounts")
40
+ .values({
41
+ id: documentId,
42
+ profile_name: "",
43
+ profile_slug: "",
44
+ profile_logo: null,
45
+ profile_description: null,
46
+ profile_socials_x: null,
47
+ profile_socials_github: null,
48
+ profile_socials_website: null,
49
+ created_at: new Date(),
50
+ updated_at: new Date(),
51
+ })
52
+ .onConflict((oc) => oc.column("id").doNothing())
53
+ .execute();
54
+ }
55
+ }
56
+ /**
57
+ * Updates a package with the provided data
58
+ */
59
+ async updatePackage(documentId, updates) {
60
+ await this.db
61
+ .updateTable("builder_packages")
62
+ .set({
63
+ ...updates,
64
+ updated_at: new Date(),
65
+ })
66
+ .where("id", "=", documentId)
67
+ .execute();
68
+ }
69
+ /**
70
+ * Updates a builder account with the provided data
71
+ */
72
+ async updateBuilderAccount(documentId, updates) {
73
+ await this.db
74
+ .updateTable("builder_accounts")
75
+ .set({
76
+ ...updates,
77
+ updated_at: new Date(),
78
+ })
79
+ .where("id", "=", documentId)
80
+ .execute();
81
+ }
82
+ /**
83
+ * Updates a builder space with the provided data
84
+ */
85
+ async updateBuilderSpace(spaceId, documentId, updates) {
86
+ await this.db
87
+ .updateTable("builder_spaces")
88
+ .set({
89
+ ...updates,
90
+ updated_at: new Date(),
91
+ })
92
+ .where("id", "=", spaceId)
93
+ .where("builder_account_id", "=", documentId)
94
+ .execute();
95
+ }
96
+ /**
97
+ * Updates a builder package with the provided data
98
+ */
99
+ async updateBuilderPackage(packageId, updates) {
100
+ await this.db
101
+ .updateTable("builder_packages")
102
+ .set({
103
+ ...updates,
104
+ updated_at: new Date(),
105
+ })
106
+ .where("id", "=", packageId)
107
+ .execute();
108
+ }
109
+ /**
110
+ * Checks if a member already exists for a builder account
111
+ */
112
+ async memberExists(documentId, ethAddress) {
113
+ const existing = await this.db
114
+ .selectFrom("builder_account_members")
115
+ .select("id")
116
+ .where("builder_account_id", "=", documentId)
117
+ .where("eth_address", "=", ethAddress)
118
+ .executeTakeFirst();
119
+ return !!existing;
120
+ }
121
+ }
@@ -0,0 +1,20 @@
1
+ import type { Action } from "document-model";
2
+ import type { BuilderAccountState } from "document-models/builder-account/index.js";
3
+ import type { DB } from "./schema.js";
4
+ import type { IRelationalDb } from "document-drive";
5
+ export declare class PackageHandlers {
6
+ private db;
7
+ private dbHelpers;
8
+ constructor(db: IRelationalDb<DB>);
9
+ handlePackageOperation(documentId: string, action: Action, state: BuilderAccountState, driveId?: string): Promise<void>;
10
+ private handleSetPackageName;
11
+ private handleSetPackageDescription;
12
+ private handleSetPackageCategory;
13
+ private handleSetPackageAuthor;
14
+ private handleSetPackageAuthorName;
15
+ private handleSetPackageAuthorWebsite;
16
+ private handleAddPackageKeyword;
17
+ private handleRemovePackageKeyword;
18
+ private handleSetPackageGithubUrl;
19
+ private handleSetPackageNpmUrl;
20
+ }
@@ -0,0 +1,116 @@
1
+ import { DatabaseHelpers } from "./database-helpers.js";
2
+ export class PackageHandlers {
3
+ db;
4
+ dbHelpers;
5
+ constructor(db) {
6
+ this.db = db;
7
+ this.dbHelpers = new DatabaseHelpers(db);
8
+ }
9
+ async handlePackageOperation(documentId, action, state, driveId) {
10
+ const packageDriveId = driveId || "";
11
+ switch (action.type) {
12
+ case "SET_PACKAGE_NAME":
13
+ await this.handleSetPackageName(documentId, packageDriveId, action, state);
14
+ break;
15
+ case "SET_PACKAGE_DESCRIPTION":
16
+ await this.handleSetPackageDescription(documentId, packageDriveId, action, state);
17
+ break;
18
+ case "SET_PACKAGE_CATEGORY":
19
+ await this.handleSetPackageCategory(documentId, packageDriveId, action, state);
20
+ break;
21
+ case "SET_PACKAGE_AUTHOR":
22
+ await this.handleSetPackageAuthor(documentId, packageDriveId, action, state);
23
+ break;
24
+ case "SET_PACKAGE_AUTHOR_NAME":
25
+ await this.handleSetPackageAuthorName(documentId, packageDriveId, action, state);
26
+ break;
27
+ case "SET_PACKAGE_AUTHOR_WEBSITE":
28
+ await this.handleSetPackageAuthorWebsite(documentId, packageDriveId, action, state);
29
+ break;
30
+ case "ADD_PACKAGE_KEYWORD":
31
+ await this.handleAddPackageKeyword(documentId, packageDriveId, action, state);
32
+ break;
33
+ case "REMOVE_PACKAGE_KEYWORD":
34
+ await this.handleRemovePackageKeyword(documentId, packageDriveId, action, state);
35
+ break;
36
+ case "SET_PACKAGE_GITHUB_URL":
37
+ await this.handleSetPackageGithubUrl(documentId, packageDriveId, action, state);
38
+ break;
39
+ case "SET_PACKAGE_NPM_URL":
40
+ await this.handleSetPackageNpmUrl(documentId, packageDriveId, action, state);
41
+ break;
42
+ }
43
+ }
44
+ async handleSetPackageName(documentId, driveId, action, state) {
45
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
46
+ await this.dbHelpers.updatePackage(documentId, {
47
+ name: action.input.name,
48
+ });
49
+ }
50
+ async handleSetPackageDescription(documentId, driveId, action, state) {
51
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
52
+ await this.dbHelpers.updatePackage(documentId, {
53
+ description: action.input.description,
54
+ });
55
+ }
56
+ async handleSetPackageCategory(documentId, driveId, action, state) {
57
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
58
+ await this.dbHelpers.updatePackage(documentId, {
59
+ category: action.input.category,
60
+ });
61
+ }
62
+ async handleSetPackageAuthor(documentId, driveId, action, state) {
63
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
64
+ const input = action.input;
65
+ await this.dbHelpers.updatePackage(documentId, {
66
+ author_name: input.name,
67
+ author_website: input.website,
68
+ });
69
+ }
70
+ async handleSetPackageAuthorName(documentId, driveId, action, state) {
71
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
72
+ await this.dbHelpers.updatePackage(documentId, {
73
+ author_name: action.input.name,
74
+ });
75
+ }
76
+ async handleSetPackageAuthorWebsite(documentId, driveId, action, state) {
77
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
78
+ await this.dbHelpers.updatePackage(documentId, {
79
+ author_website: action.input.website,
80
+ });
81
+ }
82
+ async handleAddPackageKeyword(documentId, driveId, action, state) {
83
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
84
+ const input = action.input;
85
+ await this.db
86
+ .insertInto("builder_package_keywords")
87
+ .values({
88
+ id: input.id,
89
+ package_id: documentId,
90
+ label: input.label,
91
+ created_at: new Date(),
92
+ })
93
+ .onConflict((oc) => oc.column("id").doNothing())
94
+ .execute();
95
+ }
96
+ async handleRemovePackageKeyword(documentId, driveId, action, state) {
97
+ const input = action.input;
98
+ await this.db
99
+ .deleteFrom("builder_package_keywords")
100
+ .where("id", "=", input.id)
101
+ .where("package_id", "=", documentId)
102
+ .execute();
103
+ }
104
+ async handleSetPackageGithubUrl(documentId, driveId, action, state) {
105
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
106
+ await this.dbHelpers.updatePackage(documentId, {
107
+ github_url: action.input.url,
108
+ });
109
+ }
110
+ async handleSetPackageNpmUrl(documentId, driveId, action, state) {
111
+ await this.dbHelpers.ensurePackageExists(documentId, driveId);
112
+ await this.dbHelpers.updatePackage(documentId, {
113
+ npm_url: action.input.url,
114
+ });
115
+ }
116
+ }
@@ -1,56 +1,59 @@
1
- export interface BuilderAccount {
1
+ import type { ColumnType } from "kysely";
2
+ export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
3
+ export type Timestamp = ColumnType<Date, Date | string, Date | string>;
4
+ export interface BuilderAccountMembers {
5
+ builder_account_id: string;
6
+ created_at: Generated<Timestamp>;
7
+ eth_address: string;
2
8
  id: string;
9
+ }
10
+ export interface BuilderAccounts {
11
+ created_at: Generated<Timestamp>;
12
+ id: string;
13
+ profile_description: string | null;
14
+ profile_logo: string | null;
3
15
  profile_name: string;
4
16
  profile_slug: string;
5
- profile_logo: string | null;
6
- profile_description: string | null;
7
- profile_socials_x: string | null;
8
17
  profile_socials_github: string | null;
9
18
  profile_socials_website: string | null;
10
- created_at: Date;
11
- updated_at: Date;
12
- }
13
- export interface BuilderAccountMember {
14
- id: string;
15
- builder_account_id: string;
16
- eth_address: string;
17
- created_at: Date;
19
+ profile_socials_x: string | null;
20
+ updated_at: Generated<Timestamp>;
18
21
  }
19
- export interface BuilderSpace {
22
+ export interface BuilderPackageKeywords {
23
+ created_at: Generated<Timestamp>;
20
24
  id: string;
21
- builder_account_id: string;
22
- title: string;
23
- description: string | null;
24
- sort_order: number;
25
- created_at: Date;
26
- updated_at: Date;
25
+ label: string;
26
+ package_id: string;
27
27
  }
28
- export interface BuilderPackage {
29
- id: string;
30
- space_id: string;
31
- name: string;
32
- description: string | null;
33
- category: string | null;
28
+ export interface BuilderPackages {
34
29
  author_name: string;
35
30
  author_website: string | null;
31
+ category: string | null;
32
+ created_at: Generated<Timestamp>;
33
+ description: string | null;
34
+ drive_id: string | null;
36
35
  github_url: string | null;
36
+ id: string;
37
+ name: string;
37
38
  npm_url: string | null;
39
+ sort_order: Generated<number>;
40
+ space_id: string;
41
+ updated_at: Generated<Timestamp>;
38
42
  vetra_drive_url: string | null;
39
- drive_id: string | null;
40
- sort_order: number;
41
- created_at: Date;
42
- updated_at: Date;
43
43
  }
44
- export interface BuilderPackageKeyword {
44
+ export interface BuilderSpaces {
45
+ builder_account_id: string;
46
+ created_at: Generated<Timestamp>;
47
+ description: string | null;
45
48
  id: string;
46
- package_id: string;
47
- label: string;
48
- created_at: Date;
49
+ sort_order: Generated<number>;
50
+ title: string;
51
+ updated_at: Generated<Timestamp>;
49
52
  }
50
53
  export interface DB {
51
- builder_accounts: BuilderAccount;
52
- builder_account_members: BuilderAccountMember;
53
- builder_spaces: BuilderSpace;
54
- builder_packages: BuilderPackage;
55
- builder_package_keywords: BuilderPackageKeyword;
54
+ builder_account_members: BuilderAccountMembers;
55
+ builder_accounts: BuilderAccounts;
56
+ builder_package_keywords: BuilderPackageKeywords;
57
+ builder_packages: BuilderPackages;
58
+ builder_spaces: BuilderSpaces;
56
59
  }
@@ -0,0 +1,32 @@
1
+ export interface SetPackageNameInput {
2
+ name: string;
3
+ }
4
+ export interface SetPackageDescriptionInput {
5
+ description: string;
6
+ }
7
+ export interface SetPackageCategoryInput {
8
+ category: string;
9
+ }
10
+ export interface SetPackageAuthorInput {
11
+ name?: string | null;
12
+ website?: string | null;
13
+ }
14
+ export interface SetPackageAuthorNameInput {
15
+ name: string;
16
+ }
17
+ export interface SetPackageAuthorWebsiteInput {
18
+ website: string;
19
+ }
20
+ export interface AddPackageKeywordInput {
21
+ id: string;
22
+ label: string;
23
+ }
24
+ export interface RemovePackageKeywordInput {
25
+ id: string;
26
+ }
27
+ export interface SetPackageGithubUrlInput {
28
+ url: string;
29
+ }
30
+ export interface SetPackageNpmUrlInput {
31
+ url: string;
32
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/style.css CHANGED
@@ -528,6 +528,13 @@
528
528
  }
529
529
  }
530
530
  }
531
+ .hover\:underline {
532
+ &:hover {
533
+ @media (hover: hover) {
534
+ text-decoration-line: underline;
535
+ }
536
+ }
537
+ }
531
538
  .focus\:border-blue-500 {
532
539
  &:focus {
533
540
  border-color: var(--color-blue-500);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/vetra-builder-package",
3
3
  "description": "",
4
- "version": "0.0.10",
4
+ "version": "0.0.11",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [