|
20 | 20 | let accountId = $state(form?.accountId ?? urlAccountId ?? ''); |
21 | 21 | let description = $state(form?.description ?? ''); |
22 | 22 |
|
| 23 | + // Form submission state |
| 24 | + let isSubmitting = $state(false); |
| 25 | +
|
23 | 26 | // Update local state if 'form' prop changes (e.g., after a failed form submission) |
24 | 27 | $effect(() => { |
25 | 28 | if (form) { |
|
99 | 102 | </div> |
100 | 103 | {/if} |
101 | 104 |
|
102 | | - <form method="POST" use:enhance class="p-6"> |
| 105 | + <form |
| 106 | + method="POST" |
| 107 | + use:enhance={() => { |
| 108 | + isSubmitting = true; |
| 109 | + return async ({ update }) => { |
| 110 | + await update(); |
| 111 | + isSubmitting = false; |
| 112 | + }; |
| 113 | + }} |
| 114 | + class="p-6" |
| 115 | + > |
103 | 116 | <!-- Hidden field for pre-selected account --> |
104 | 117 | {#if urlAccountId} |
105 | 118 | <input type="hidden" name="accountId" value={urlAccountId} /> |
|
140 | 153 | <div> |
141 | 154 | <label |
142 | 155 | for="status" |
143 | | - class="mb-1 block flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
| 156 | + class="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
144 | 157 | > |
145 | 158 | <Clock size={14} class="mr-1 text-gray-500 dark:text-gray-400" /> |
146 | 159 | Status |
|
162 | 175 | <div> |
163 | 176 | <label |
164 | 177 | for="priority" |
165 | | - class="mb-1 block flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
| 178 | + class="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
166 | 179 | > |
167 | 180 | <Flag size={14} class="mr-1 text-gray-500 dark:text-gray-400" /> |
168 | 181 | Priority |
|
182 | 195 | <div> |
183 | 196 | <label |
184 | 197 | for="dueDate" |
185 | | - class="mb-1 block flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
| 198 | + class="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
186 | 199 | > |
187 | 200 | <Calendar size={14} class="mr-1 text-gray-500 dark:text-gray-400" /> |
188 | 201 | Due Date |
|
235 | 248 | <div> |
236 | 249 | <label |
237 | 250 | for="accountId" |
238 | | - class="mb-1 block flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
| 251 | + class="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300" |
239 | 252 | > |
240 | 253 | <Building size={14} class="mr-1 text-gray-500 dark:text-gray-400" /> |
241 | 254 | Related Account |
|
299 | 312 | > |
300 | 313 | <button |
301 | 314 | type="button" |
302 | | - class="rounded-lg border border-gray-300 bg-white px-5 py-2.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 focus:ring-offset-white focus:outline-none dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-800" |
| 315 | + disabled={isSubmitting} |
| 316 | + class="rounded-lg border border-gray-300 bg-white px-5 py-2.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 focus:ring-offset-white focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-800" |
303 | 317 | onclick={handleCancel} |
304 | 318 | > |
305 | 319 | Cancel |
306 | 320 | </button> |
307 | 321 | <button |
308 | 322 | type="submit" |
309 | | - class="rounded-lg bg-blue-600 px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white focus:outline-none dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-400 dark:focus:ring-offset-gray-800" |
| 323 | + disabled={isSubmitting} |
| 324 | + class="rounded-lg bg-blue-600 px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-400 dark:focus:ring-offset-gray-800" |
310 | 325 | > |
311 | | - Create Task |
| 326 | + {#if isSubmitting} |
| 327 | + <svg class="inline-block w-4 h-4 mr-2 animate-spin" viewBox="0 0 24 24" fill="none"> |
| 328 | + <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" class="opacity-25"/> |
| 329 | + <path fill="currentColor" class="opacity-75" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/> |
| 330 | + </svg> |
| 331 | + Creating Task... |
| 332 | + {:else} |
| 333 | + Create Task |
| 334 | + {/if} |
312 | 335 | </button> |
313 | 336 | </div> |
314 | 337 | </form> |
|
0 commit comments