aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-02-20 19:53:49 -0800
committerAdam Soltys <[email protected]>2024-02-20 19:53:49 -0800
commitfbf3cef47c612b9c334917f10c810c797fc77da6 (patch)
treef10d545fae7305e624c91f5333f513d5dc95d413 /src/components
parent3fbd2514e38d29ff02cd7765d89476bed6530d37 (diff)
downloadcoinos-ui-fbf3cef47c612b9c334917f10c810c797fc77da6.tar.gz
coinos-ui-fbf3cef47c612b9c334917f10c810c797fc77da6.zip
items
Diffstat (limited to 'src/components')
-rw-r--r--src/components/DeleteItem.svelte47
-rw-r--r--src/components/ItemForm.svelte86
2 files changed, 103 insertions, 30 deletions
diff --git a/src/components/DeleteItem.svelte b/src/components/DeleteItem.svelte
new file mode 100644
index 00000000..8f7f97ca
--- /dev/null
+++ b/src/components/DeleteItem.svelte
@@ -0,0 +1,47 @@
+<script>
+ import Icon from "$comp/Icon.svelte";
+ import { fail, post } from "$lib/utils";
+ import { invalidate } from "$app/navigation";
+
+ export let item;
+
+ let cancel = () => (item = null);
+
+ let submit = async () => {
+ try {
+ await post("/api/items/delete", { item });
+ invalidate("app:items");
+ item = null;
+ } catch (e) {
+ fail("Failed to delete item");
+ }
+ };
+</script>
+
+<div
+ class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-20"
+>
+ <div
+ class="relative top-1/3 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white space-y-5"
+ >
+ <h1 class="text-center text-2xl font-semibold">Delete item</h1>
+ <form on:submit|preventDefault={submit}>
+ <div class="w-full flex">
+ <button
+ type="button"
+ class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
+ on:click={cancel}
+ on:keydown={cancel}
+ >
+ <div class="my-auto">No</div>
+ </button>
+ <button
+ type="submit"
+ class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto bg-black text-white"
+ >
+ <div class="my-auto">Yes</div>
+ </button>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/src/components/ItemForm.svelte b/src/components/ItemForm.svelte
index 044020b7..71114c29 100644
--- a/src/components/ItemForm.svelte
+++ b/src/components/ItemForm.svelte
@@ -1,9 +1,12 @@
<script>
import { t } from "$lib/translations";
import { upload } from "$lib/upload";
- export let item, token;
+ import { fail } from "$lib/utils";
+ import { applyAction, deserialize } from "$app/forms";
+ import Spinner from "$comp/Spinner.svelte";
+ export let item;
- let fileInput, formElement, file;
+ let fileInput, formElement, file, submitting, progress;
let select = () => fileInput.click();
let src;
@@ -30,14 +33,12 @@
if (src) {
try {
- let { hash } = JSON.parse(
- await upload(file, "item", progress, token)
- );
+ let { hash } = JSON.parse(await upload(file, "item", progress));
data.set("image", hash);
await fetch(`/api/public/${hash}.webp`, {
- cache: "reload",
+ cache: "reload",
mode: "no-cors",
});
} catch (e) {
@@ -68,41 +69,66 @@
on:submit|preventDefault={handleSubmit}
bind:this={formElement}
>
+ <input type="hidden" name="id" bind:value={item.id} />
+ <input type="hidden" name="image" bind:value={item.image} />
+
<div>
<label for="name" class="font-bold mb-1 block">{$t("items.name")}</label>
<input name="name" bind:value={item.name} />
</div>
+
<div>
+ <label for="price" class="font-bold mb-1 block">{$t("items.price")}</label>
+ <input name="price" bind:value={item.price} />
+ </div>
+
+ <div class="w-full">
<label for="img" class="font-bold mb-1 block">{$t("items.image")}</label>
- <div class="relative w-full h-64">
- {#if item.hash}
- <img
- src={`/api/public/${item.hash}.webp`}
- alt={item.name}
- class="mx-auto object-cover h-full w-full"
- />
- {:else if src}
- <img {src} alt={item.name} class="mx-auto object-cover h-full w-full" />
- {:else}
- <div
- class="bg-gradient-to-r from-primary to-gradient w-full h-48 mb-4 cursor-pointer hover:opacity-80"
- on:click={select}
- on:keydown={select}
- alt="Banner"
- />
- {/if}
- <input
- type="file"
- class="hidden"
- bind:this={fileInput}
- on:change={(e) => handleFile(e, "item")}
- />
+
+ <div class="grid grid-cols-2 gap-4">
+ <div class="h-64 rounded-2xl overflow-hidden">
+ {#if src}
+ <img
+ {src}
+ alt={item.name}
+ class="object-cover w-full h-full"
+ on:click={select}
+ on:keydown={select}
+ />
+ {:else if item.image}
+ <img
+ src={`/api/public/${item.image}.webp`}
+ alt={item.name}
+ class="object-cover w-full h-full"
+ on:click={select}
+ on:keydown={select}
+ />
+ {:else}
+ <div
+ class="bg-gradient-to-r from-primary to-gradient mb-4 cursor-pointer hover:opacity-80 w-full h-full"
+ on:click={select}
+ on:keydown={select}
+ alt="Banner"
+ />
+ {/if}
+ </div>
</div>
+
+ <input
+ type="file"
+ class="hidden"
+ bind:this={fileInput}
+ on:change={(e) => handleFile(e, "item")}
+ />
</div>
<button
class="rounded-full py-5 px-6 font-bold hover:opacity-80 flex bg-black text-white text-2xl"
>
- {$t("items.submit")}
+ {#if submitting}
+ <Spinner />
+ {:else}
+ {$t("items.submit")}
+ {/if}
</button>
</form>