Skip to content

Commit 4472a68

Browse files
committed
ui: improve ui for submit page
1 parent 0416949 commit 4472a68

File tree

4 files changed

+34
-23
lines changed

4 files changed

+34
-23
lines changed

service/routes/projects/index.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const route = new Hono<HonoOptions>()
5151
async (c) => {
5252
const browser_id = await getBrowserID(c);
5353
const projectId = c.req.valid("param").projectId;
54-
const project_resp = db(c)
54+
const d = db(c);
55+
const project_resp = d
5556
.select()
5657
.from(projects)
5758
.where(eq(projects.id, projectId))
@@ -65,7 +66,7 @@ const route = new Hono<HonoOptions>()
6566
});
6667

6768
const prev_participant_data = (
68-
await db(c)
69+
await d
6970
.select({
7071
id: participants.id,
7172
name: participants.name,
@@ -80,7 +81,7 @@ const route = new Hono<HonoOptions>()
8081
)
8182
)[0];
8283
// エンティティの roles と被るため role_resp
83-
const role_resp = db(c)
84+
const role_resp = d
8485
.select({
8586
id: roles.id,
8687
name: roles.name,
@@ -130,7 +131,7 @@ const route = new Hono<HonoOptions>()
130131
{
131132
roles_count: 0,
132133
id: crypto.randomUUID(),
133-
name: "admin",
134+
name: "",
134135
browser_id,
135136
project_id: project_id,
136137
is_admin: 1,

web/src/providers/toast/toast-control.svelte.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type InternalToast = Toast & {
88
class: string;
99
};
1010

11-
export const DEFAULT_TIMEOUT = 1500;
11+
export const DEFAULT_TIMEOUT = 2000;
1212
export class ToastController {
1313
toasts: InternalToast[] = $state([]);
1414

web/src/routes/[projectId]/config/actions.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { modal, toast } from "~/globals.svelte";
22
import { createClient } from "~/api/client";
3+
import { goto, replaceState } from "$app/navigation";
34

45
const client = createClient({ fetch });
56

@@ -21,7 +22,7 @@ export async function close(projectId: string) {
2122
projectId,
2223
},
2324
});
24-
location.assign(`/${projectId}/config?closed`);
25+
replaceState(`/${projectId}/config?closed`, {});
2526
},
2627
},
2728
],
@@ -44,11 +45,12 @@ export async function deleteProject(projectId: string) {
4445
},
4546
});
4647
if (resp.ok) {
47-
await toast.push({
48-
message: "削除しました。",
49-
kind: "success",
48+
toast.push({
49+
message: "プロジェクトを削除しました。",
50+
kind: "error",
51+
timeout: 4000,
5052
});
51-
location.assign("/");
53+
goto("/");
5254
} else {
5355
toast.push({
5456
message: "削除に失敗しました",

web/src/routes/[projectId]/submit/+page.svelte

+21-13
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,33 @@
2020
}),
2121
);
2222
23+
const prev_data = data.prev != null;
24+
const formVerb = $derived.by(() => {
25+
if (!prev_data) return "送信";
26+
if (!data.prev?.name) return "送信"; // admin & has not submitted
27+
return "更新";
28+
});
2329
async function postPreference() {
2430
formState = "submitting";
2531
try {
2632
const projectId = data.project.id;
2733
const preference = safeParse(PreferenceSchema, {
2834
participantName,
29-
rolesCount: data.project.multiple_roles === 1 ? rolesCount : null,
35+
rolesCount,
3036
ratings: ratings.map((rating) => ({
3137
roleId: rating.role.id,
3238
score: rating.score,
3339
})),
3440
});
3541
// TODO: handle it better
36-
if (!preference.success) throw new Error("failed to validate preference");
42+
if (!preference.success) {
43+
console.error(preference.issues);
44+
throw new Error("failed to validate preference");
45+
}
3746
38-
if (data.prev) {
47+
if (prev_data) {
3948
// PUT
49+
console.log("doing a PUT");
4050
const res = await client.projects[":projectId"].preferences.$put({
4151
json: preference.output,
4252
param: { projectId },
@@ -47,6 +57,7 @@
4757
);
4858
} else {
4959
// POST
60+
console.log("doing a POST");
5061
const res = await client.projects[":projectId"].preferences.$post({
5162
json: preference.output,
5263
param: { projectId },
@@ -68,14 +79,12 @@
6879
}
6980
7081
let formState = $state<"ready" | "submitting" | "error" | "done">("ready");
71-
const closed = $derived.by(() => {
82+
const isClosed = $derived.by(() => {
7283
if (data.project.closed_at === null) return false;
7384
return new Date(data.project.closed_at).getTime() < Date.now();
7485
});
7586
const maxRoles = $derived(data.roles.length);
7687
77-
const formVerb = $derived(data.prev ? "更新" : "送信");
78-
7988
const resultLink = $derived(
8089
generateURL({
8190
pathname: `${data.project.id}/result`,
@@ -84,7 +93,7 @@
8493
</script>
8594

8695
<div>
87-
{#if closed}
96+
{#if isClosed}
8897
<div role="alert" class="alert alert-error m-6">
8998
既に締め切られています
9099
<a class="btn btn-primary" href={resultLink}> 結果を見る </a>
@@ -97,7 +106,6 @@
97106
{:else}
98107
{@const p = data.project}
99108
<form
100-
method="POST"
101109
onsubmit={async (e) => {
102110
e.preventDefault();
103111
await postPreference();
@@ -119,7 +127,7 @@
119127
required
120128
minlength="1"
121129
bind:value={participantName}
122-
disabled={closed}
130+
disabled={isClosed}
123131
/>
124132
</div>
125133
{#if p.multiple_roles == 1}
@@ -130,7 +138,7 @@
130138
class="input validator bg-white text-base"
131139
bind:value={rolesCount}
132140
max={data.roles.length}
133-
disabled={closed}
141+
disabled={isClosed}
134142
/>
135143
<div class="w-full max-w-xs">
136144
<input
@@ -154,14 +162,14 @@
154162
</div>
155163
</div>
156164
{/if}
157-
<RolesSelector bind:ratings {closed} />
165+
<RolesSelector bind:ratings closed={isClosed} />
158166
<div class="flex justify-end">
159167
<button
160168
type="submit"
161169
class="btn btn-primary"
162-
disabled={closed || formState !== "ready"}
170+
disabled={isClosed || formState !== "ready"}
163171
>
164-
{#if closed}
172+
{#if isClosed}
165173
既に締め切られています
166174
{:else if formState === "ready"}
167175
{formVerb}

0 commit comments

Comments
 (0)