|
20 | 20 | }),
|
21 | 21 | );
|
22 | 22 |
|
| 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 | + }); |
23 | 29 | async function postPreference() {
|
24 | 30 | formState = "submitting";
|
25 | 31 | try {
|
26 | 32 | const projectId = data.project.id;
|
27 | 33 | const preference = safeParse(PreferenceSchema, {
|
28 | 34 | participantName,
|
29 |
| - rolesCount: data.project.multiple_roles === 1 ? rolesCount : null, |
| 35 | + rolesCount, |
30 | 36 | ratings: ratings.map((rating) => ({
|
31 | 37 | roleId: rating.role.id,
|
32 | 38 | score: rating.score,
|
33 | 39 | })),
|
34 | 40 | });
|
35 | 41 | // 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 | + } |
37 | 46 |
|
38 |
| - if (data.prev) { |
| 47 | + if (prev_data) { |
39 | 48 | // PUT
|
| 49 | + console.log("doing a PUT"); |
40 | 50 | const res = await client.projects[":projectId"].preferences.$put({
|
41 | 51 | json: preference.output,
|
42 | 52 | param: { projectId },
|
|
47 | 57 | );
|
48 | 58 | } else {
|
49 | 59 | // POST
|
| 60 | + console.log("doing a POST"); |
50 | 61 | const res = await client.projects[":projectId"].preferences.$post({
|
51 | 62 | json: preference.output,
|
52 | 63 | param: { projectId },
|
|
68 | 79 | }
|
69 | 80 |
|
70 | 81 | let formState = $state<"ready" | "submitting" | "error" | "done">("ready");
|
71 |
| - const closed = $derived.by(() => { |
| 82 | + const isClosed = $derived.by(() => { |
72 | 83 | if (data.project.closed_at === null) return false;
|
73 | 84 | return new Date(data.project.closed_at).getTime() < Date.now();
|
74 | 85 | });
|
75 | 86 | const maxRoles = $derived(data.roles.length);
|
76 | 87 |
|
77 |
| - const formVerb = $derived(data.prev ? "更新" : "送信"); |
78 |
| -
|
79 | 88 | const resultLink = $derived(
|
80 | 89 | generateURL({
|
81 | 90 | pathname: `${data.project.id}/result`,
|
|
84 | 93 | </script>
|
85 | 94 |
|
86 | 95 | <div>
|
87 |
| - {#if closed} |
| 96 | + {#if isClosed} |
88 | 97 | <div role="alert" class="alert alert-error m-6">
|
89 | 98 | 既に締め切られています
|
90 | 99 | <a class="btn btn-primary" href={resultLink}> 結果を見る </a>
|
|
97 | 106 | {:else}
|
98 | 107 | {@const p = data.project}
|
99 | 108 | <form
|
100 |
| - method="POST" |
101 | 109 | onsubmit={async (e) => {
|
102 | 110 | e.preventDefault();
|
103 | 111 | await postPreference();
|
|
119 | 127 | required
|
120 | 128 | minlength="1"
|
121 | 129 | bind:value={participantName}
|
122 |
| - disabled={closed} |
| 130 | + disabled={isClosed} |
123 | 131 | />
|
124 | 132 | </div>
|
125 | 133 | {#if p.multiple_roles == 1}
|
|
130 | 138 | class="input validator bg-white text-base"
|
131 | 139 | bind:value={rolesCount}
|
132 | 140 | max={data.roles.length}
|
133 |
| - disabled={closed} |
| 141 | + disabled={isClosed} |
134 | 142 | />
|
135 | 143 | <div class="w-full max-w-xs">
|
136 | 144 | <input
|
|
154 | 162 | </div>
|
155 | 163 | </div>
|
156 | 164 | {/if}
|
157 |
| - <RolesSelector bind:ratings {closed} /> |
| 165 | + <RolesSelector bind:ratings closed={isClosed} /> |
158 | 166 | <div class="flex justify-end">
|
159 | 167 | <button
|
160 | 168 | type="submit"
|
161 | 169 | class="btn btn-primary"
|
162 |
| - disabled={closed || formState !== "ready"} |
| 170 | + disabled={isClosed || formState !== "ready"} |
163 | 171 | >
|
164 |
| - {#if closed} |
| 172 | + {#if isClosed} |
165 | 173 | 既に締め切られています
|
166 | 174 | {:else if formState === "ready"}
|
167 | 175 | {formVerb}
|
|
0 commit comments