Skip to content

Commit 16af024

Browse files
committed
Make workspace/create/instance
1 parent d9b5c3b commit 16af024

2 files changed

Lines changed: 209 additions & 0 deletions

File tree

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// DrFed: A web-based platform for developing and debugging ActivityPub apps
2+
// Copyright (C) 2026 DrFed team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
import { faker } from "@faker-js/faker";
18+
// DrFed: A web-based platform for developing and debugging ActivityPub apps
19+
// Copyright (C) 2026 DrFed team
20+
//
21+
// This program is free software: you can redistribute it and/or modify
22+
// it under the terms of the GNU Affero General Public License as published by
23+
// the Free Software Foundation, either version 3 of the License, or
24+
// (at your option) any later version.
25+
//
26+
// This program is distributed in the hope that it will be useful,
27+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
28+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29+
// GNU Affero General Public License for more details.
30+
//
31+
// You should have received a copy of the GNU Affero General Public License
32+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
33+
import { Title } from "@solidjs/meta";
34+
import { action, redirect, useSubmission } from "@solidjs/router";
35+
import { commitMutation, graphql } from "relay-runtime";
36+
import { getRequestEvent } from "solid-js/web";
37+
38+
import { createRelayEnvironment } from "~/RelayEnvironment";
39+
40+
import type { CreateInstanceMutation } from "./__generated__/CreateInstanceMutation.graphql";
41+
42+
const createInstanceMutation = graphql`
43+
mutation CreateInstanceMutation(
44+
$slug: String! # $name: String
45+
) {
46+
createInstance(slug: $slug) {
47+
... on Instance {
48+
slug
49+
}
50+
}
51+
}
52+
`;
53+
54+
type CreateInstanceResult =
55+
| {
56+
payload: {
57+
slug: string;
58+
};
59+
status: "success";
60+
}
61+
| {
62+
message: string;
63+
status: "error";
64+
};
65+
66+
const createInstanceAction = action(async (formData: FormData) => {
67+
"use server";
68+
69+
const slug = formData.get("slug");
70+
if (typeof slug !== "string" || slug === "") {
71+
return {
72+
message: "Enter a valid slug.",
73+
status: "error",
74+
} satisfies CreateInstanceResult;
75+
}
76+
77+
const request = getRequestEvent()?.request;
78+
if (request === undefined) {
79+
return {
80+
message: "Unable to determine the application URL.",
81+
status: "error",
82+
} satisfies CreateInstanceResult;
83+
}
84+
85+
const environment = createRelayEnvironment();
86+
87+
const result = await new Promise<CreateInstanceResult>((resolve) => {
88+
commitMutation<CreateInstanceMutation>(environment, {
89+
mutation: createInstanceMutation,
90+
variables: { slug },
91+
onCompleted: (response, errors) => {
92+
const errorMessage = errors?.map((e) => e.message).join("\n");
93+
94+
if (typeof errorMessage == "string") {
95+
resolve({
96+
message: errorMessage,
97+
status: "error",
98+
});
99+
} else if (response.createInstance.slug === undefined) {
100+
resolve({
101+
message: "Empty Slug Returned",
102+
status: "error",
103+
});
104+
} else {
105+
resolve({
106+
payload: {
107+
slug: response.createInstance.slug,
108+
},
109+
status: "success",
110+
});
111+
}
112+
},
113+
onError: (error) => {
114+
resolve({
115+
message: error.message,
116+
status: "error",
117+
});
118+
},
119+
});
120+
});
121+
122+
if (result.status === "error") {
123+
return result;
124+
}
125+
126+
return redirect(`/workspace/`);
127+
}, "create-instance");
128+
129+
export default function CreateInstancePage() {
130+
const createInstanceSubmission = useSubmission(createInstanceAction);
131+
132+
const buttonLabel = () => {
133+
if (createInstanceSubmission.pending === true) {
134+
return "Making an instance";
135+
}
136+
return "Done.";
137+
};
138+
139+
return (
140+
<main class="create-page">
141+
<Title>Create An Instance — DrFed</Title>
142+
143+
<section
144+
class="panel create-panel"
145+
aria-labelledby="create-instance-title"
146+
>
147+
<header class="panel-header">
148+
<h1 id="create-instance-title">Create Instance</h1>
149+
<p>Enter your instance name.</p>
150+
</header>
151+
152+
<form action={createInstanceAction} method="post">
153+
<label class="field">
154+
Name
155+
<input
156+
name="name"
157+
type="text"
158+
inputmode="text"
159+
placeholder="Your Instance Name"
160+
required
161+
/>
162+
</label>
163+
<label class="field">
164+
Slug
165+
<input
166+
name="slug"
167+
type="text"
168+
value={`${faker.word.noun()}-${faker.word.noun()}-${faker.word.noun()}`}
169+
readOnly
170+
required
171+
/>
172+
</label>
173+
<button
174+
class="button primary"
175+
type="submit"
176+
disabled={createInstanceSubmission.pending}
177+
>
178+
{buttonLabel()}
179+
</button>
180+
</form>
181+
</section>
182+
</main>
183+
);
184+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// DrFed: A web-based platform for developing and debugging ActivityPub apps
2+
// Copyright (C) 2026 DrFed team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
export default function WorkspacePage() {
18+
return (
19+
<main>
20+
<section>
21+
<p>Nothing Yet but it is a workspace for you.</p>
22+
</section>
23+
</main>
24+
);
25+
}

0 commit comments

Comments
 (0)