Skip to content

Commit

Permalink
Change verbiage and add purchased field (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmintey authored Feb 22, 2023
2 parents 5bacd84 + 6fbc50d commit 11b2f2d
Show file tree
Hide file tree
Showing 19 changed files with 242 additions and 76 deletions.
25 changes: 25 additions & 0 deletions prisma/migrations/20230221220353_add_item_purchased/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_items" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"price" TEXT,
"url" TEXT,
"note" TEXT,
"image_url" TEXT,
"userId" TEXT NOT NULL,
"addedById" TEXT NOT NULL,
"pledgedById" TEXT,
"approved" BOOLEAN NOT NULL DEFAULT true,
"purchased" BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT "items_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "items_addedById_fkey" FOREIGN KEY ("addedById") REFERENCES "user" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "items_pledgedById_fkey" FOREIGN KEY ("pledgedById") REFERENCES "user" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_items" ("addedById", "approved", "id", "image_url", "name", "note", "pledgedById", "price", "url", "userId") SELECT "addedById", "approved", "id", "image_url", "name", "note", "pledgedById", "price", "url", "userId" FROM "items";
DROP TABLE "items";
ALTER TABLE "new_items" RENAME TO "items";
CREATE UNIQUE INDEX "items_id_key" ON "items"("id");
CREATE INDEX "items_userId_idx" ON "items"("userId");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ model Item {
pledgedBy User? @relation(name: "PledgedItems", fields: [pledgedById], references: [id])
pledgedById String?
approved Boolean @default(true)
purchased Boolean @default(false)
@@index([userId])
@@map("items")
Expand Down
7 changes: 5 additions & 2 deletions src/lib/components/UserCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
</div>
</div>

<div class="p-4">
Items: {user._count ? `${user._count.items}/` : ""}{user.items.length}
<div class="flex flex-row space-x-2 p-4 items-center">
<iconify-icon icon="ri:gift-2-fill" />
<span>
{user._count ? `${user._count.items}/` : ""}{user.items.length}
</span>
</div>
</a>
54 changes: 43 additions & 11 deletions src/lib/components/wishlists/ItemCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,29 @@
};
modalStore.trigger(confirm);
};
const handlePurchased = async (itemId: number, value: boolean) => {
const resp = await fetch(`/api/items/${itemId}`, {
method: "PATCH",
headers: {
"content-type": "application/json",
accept: "application/json"
},
body: JSON.stringify({
purchased: value
})
});
if (resp.ok) {
invalidateAll();
}
};
</script>

<div class="card" class:variant-ghost-warning={!item.approved}>
<div class="flex flex-col space-y-2 p-4">
<div class="flex w-full">
<span class="truncate font-bold text-2xl">
<span class="truncate font-bold text-xl md:text-2xl">
{#if item.url}
<a class="dark:!text-primary-200" href={item.url}>{item.name}</a>
{:else}
Expand All @@ -187,7 +204,7 @@
<span class="text-lg font-semibold">${item.price}</span>
{/if}

<span class="text-lg">
<span class="text-base md:text-lg">
{#if showFor}
For <span class="text-secondary-700-200-token font-bold">{item.user?.name}</span>
{:else}
Expand All @@ -206,22 +223,35 @@
<div />
{:else if item.pledgedBy}
{#if item.pledgedBy.username === user.username}
<button
class="btn variant-ghost-secondary btn-sm md:btn"
on:click={() => handlePledge(item.id, true)}>Unpledge</button
>
<div class="flex flex-row space-x-2 md:space-x-4">
<button
class="btn variant-ghost-secondary btn-sm md:btn"
on:click={() => handlePledge(item.id, true)}
>
Unclaim
</button>
<label class="unstyled flex space-x-2 items-center text-sm md:text-base">
<input
class="checkbox"
type="checkbox"
bind:checked={item.purchased}
on:change={(event) => handlePurchased(item.id, event.currentTarget?.checked)}
/>
<span>Purchased</span>
</label>
</div>
{:else}
<span>Pledged by {item.pledgedBy?.name}</span>
<span>Claimed by {item.pledgedBy?.name}</span>
{/if}
{:else}
<button
class="btn variant-filled-secondary btn-sm md:btn"
on:click={() => handlePledge(item.id)}>Pledge</button
on:click={() => handlePledge(item.id)}>Claim</button
>
{/if}

{#if !item.approved}
<div class="flex flex-row space-x-4">
<div class="flex flex-row space-x-2 md:space-x-4">
<button
class="btn variant-filled-success btn-sm md:btn "
on:click={() => handleApproval(item.id, item.name, item.addedBy?.name)}>Approve</button
Expand All @@ -233,10 +263,12 @@
>
</div>
{:else if user.username === item.user?.username || user.username === item.addedBy?.username}
<div class="flex flex-row space-x-4">
<div class="flex flex-row space-x-2 md:space-x-4">
<button
class="btn variant-ghost-primary btn-sm md:btn "
on:click={() => goto(`${$page.url}/edit/${item.id}`)}>Edit</button
on:click={() =>
goto(`/wishlists/${item.user?.username}/edit/${item.id}?ref=${$page.url}`)}
>Edit</button
>
<button
class="btn variant-filled-error btn-sm md:btn "
Expand Down
8 changes: 3 additions & 5 deletions src/lib/components/wishlists/ItemForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
data.price = productData.price?.toString() || null;
} else {
console.log("invalid url");
console.log(await res.json());
}
loading = false;
urlChanged = false;
Expand All @@ -38,7 +37,7 @@
type="url"
id="url"
name="url"
placeholder="https://www.amazon.com/Litfun-Womens-Memory-Slippers-Outdoor/dp/B09JVQ84VG"
placeholder="Enter a URL to fetch the item data"
bind:value={data.url}
on:focusout={() => getInfo()}
on:change={() => (urlChanged = true)}
Expand All @@ -52,7 +51,6 @@
type="text"
id="name"
name="name"
placeholder="Really cool gift"
required
bind:value={data.name}
class:input-invalid={form?.missing}
Expand All @@ -78,12 +76,12 @@
</div>
</label>

<label for="image" class="col-span-1 md:col-span-2 2xl:col-span-1">
<label for="image" class="col-span-1 md:col-span-2">
<span>Upload Image</span>
<input class="input" type="file" accept="image/*" id="image" name="image" />
</label>

<label for="image_url" class="col-span-1 md:col-span-4 2xl:col-span-5">
<label for="image_url" class="col-span-1 md:col-span-4">
<span>Image URL</span>
<input
class="input"
Expand Down
33 changes: 33 additions & 0 deletions src/lib/components/wishlists/chips/ClaimFilter.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import { claimOption, CLAIM_OPTIONS } from "$lib/stores/filters";
import { menu } from "@skeletonlabs/skeleton";
let menuView = false;
const stateHandler = (response: { menu: string; state: boolean }): void => {
if (response.menu === "view") menuView = response.state;
};
</script>

<div class="flex flex-row space-x-4 pb-4">
<span class="relative">
<button
class="chip variant-ringed-primary"
class:variant-ghost-primary={$claimOption !== "All"}
use:menu={{ menu: "view", state: stateHandler }}
>
<span>{$claimOption}</span>
<iconify-icon icon="ri:arrow-down-s-fill" class:rotate-180={menuView} />
</button>
<nav class="list-nav card p-4 shadow-xl" data-menu="view">
<ul>
{#each CLAIM_OPTIONS as OPTION}
<li>
<button class="list-option w-full" on:click={() => ($claimOption = OPTION)}>
{OPTION}
</button>
</li>
{/each}
</ul>
</nav>
</span>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { viewOption } from "$lib/stores/view";
import { claimOption } from "$lib/stores/filters";
import { menu } from "@skeletonlabs/skeleton";
let menuView = false;
Expand All @@ -12,25 +12,25 @@
<span class="relative">
<button
class="chip variant-ringed-primary"
class:variant-ghost-primary={$viewOption !== "All"}
class:variant-ghost-primary={$claimOption !== "All"}
use:menu={{ menu: "view", state: stateHandler }}
>
<span>{$viewOption}</span>
<span>{$claimOption}</span>
<iconify-icon icon="ri:arrow-down-s-fill" class:rotate-180={menuView} />
</button>
<nav class="list-nav card p-4 shadow-xl" data-menu="view">
<ul>
<li>
<button class="list-option w-full" on:click={() => ($viewOption = "All")}>All</button>
<button class="list-option w-full" on:click={() => ($claimOption = "All")}>All</button>
</li>
<li>
<button class="list-option w-full" on:click={() => ($viewOption = "Unpledged")}
>Unpledged</button
<button class="list-option w-full" on:click={() => ($claimOption = "Unclaimed")}
>Unclaimed</button
>
</li>
<li>
<button class="list-option w-full" on:click={() => ($viewOption = "Pledged")}
>Pledged</button
<button class="list-option w-full" on:click={() => ($claimOption = "Claimed")}
>Claimed</button
>
</li>
</ul>
Expand Down
5 changes: 5 additions & 0 deletions src/lib/stores/filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { writable } from "svelte/store";

export const CLAIM_OPTIONS = ["All", "Claimed", "Unclaimed"] as const;
export type ClaimOption = (typeof CLAIM_OPTIONS)[number];
export const claimOption = writable<ClaimOption>("All");
4 changes: 0 additions & 4 deletions src/lib/stores/view.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
href: "/"
},
{
label: "My List",
label: "My Wishes",
href: `/wishlists/${$user?.username}`
},
{
label: "My Pledges",
href: "/pledges"
label: "My Claims",
href: "/claims"
}
];
</script>
Expand Down Expand Up @@ -72,7 +72,7 @@
<NavBar {navItems} />
</svelte:fragment>
<!-- Router Slot -->
<div class="px-4 md:px-8 py-4">
<div class="px-4 md:px-12 lg:px-32 xl:px-56 py-4">
<slot />
</div>
</AppShell>
Expand Down
3 changes: 2 additions & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script lang="ts">
import type { PageData } from "./$types";
import UserCard from "$lib/components/UserCard.svelte";
import { fade } from "svelte/transition";
export let data: PageData;
</script>

<div class="flex flex-col space-y-4">
<div in:fade class="flex flex-col space-y-4">
<h1>Lists</h1>
<UserCard user={data.me} />

Expand Down
21 changes: 13 additions & 8 deletions src/routes/api/items/[itemId]/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const PATCH: RequestHandler = async ({ params, locals, request }) => {

await validateItem(params?.itemId, session);

const body = await request.json();
const body = (await request.json()) as Record<string, unknown>;
const data: {
name?: string;
price?: string;
Expand All @@ -87,15 +87,20 @@ export const PATCH: RequestHandler = async ({ params, locals, request }) => {
image_url?: string;
pledgedById?: string;
approved?: boolean;
purchased?: boolean;
} = {};

if (body.name) data.name = body.name;
if (body.price) data.price = body.price;
if (body.url) data.url = body.url;
if (body.note) data.note = body.note;
if (body.image_url) data.image_url = body.image_url;
if (body.pledgedById) data.pledgedById = body.pledgedById === "0" ? null : body.pledgedById;
if (body.approved) data.approved = body.approved;
if (body.name && typeof body.name === "string") data.name = body.name;
if (body.price && typeof body.price === "string") data.price = body.price;
if (body.url && typeof body.url === "string") data.url = body.url;
if (body.note && typeof body.note === "string") data.note = body.note;
if (body.image_url && typeof body.image_url === "string") data.image_url = body.image_url;
if (body.pledgedById && typeof body.pledgedById === "string")
data.pledgedById = body.pledgedById === "0" ? undefined : body.pledgedById;
if (Object.keys(body).includes("approved") && typeof body.approved === "boolean")
data.approved = body.approved;
if (Object.keys(body).includes("purchased") && typeof body.purchased === "boolean")
data.purchased = body.purchased;

try {
const item = await client.item.update({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { client } from "$lib/server/prisma";
export const load: PageServerLoad = async ({ locals }) => {
const { session, user } = await locals.validateUser();
if (!session) {
throw redirect(302, `/login?ref=/pledges`);
throw redirect(302, `/login?ref=/claims`);
}

const wishlistItems = await client.item.findMany({
Expand Down
Loading

0 comments on commit 11b2f2d

Please sign in to comment.