Skip to content

Commit

Permalink
Stream consumable database calls to client
Browse files Browse the repository at this point in the history
  • Loading branch information
danieladugyan committed Aug 24, 2024
1 parent 5e7cf82 commit 83e3661
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 57 deletions.
14 changes: 6 additions & 8 deletions src/lib/server/shop/countUserShopItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,31 @@ import { dbIdentification } from "$lib/server/shop/types";
import type { PrismaClient } from "@prisma/client";
import type { AuthUser } from "@zenstackhq/runtime";

export type UserShopItemCounts = Awaited<ReturnType<typeof countUserShopItems>>;
export const countUserShopItems = async (
prisma: PrismaClient,
user: AuthUser,
) => {
export type UserShopItemCounts = ReturnType<typeof countUserShopItems>;

export const countUserShopItems = (prisma: PrismaClient, user: AuthUser) => {
if (!user) return;
if (!user.memberId && !user.externalCode) return;
const identification = dbIdentification(
user.memberId
? { memberId: user.memberId }
: { externalCode: user.externalCode! },
);
const unconsumed = await prisma.consumable.count({
const unconsumed = prisma.consumable.count({
where: {
purchasedAt: { not: null },
consumedAt: null,
...identification,
},
});
const inCart = await prisma.consumable.count({
const inCart = prisma.consumable.count({
where: {
purchasedAt: null,
OR: [{ expiresAt: null }, { expiresAt: { gt: new Date() } }],
...identification,
},
});
const reserved = await prisma.consumableReservation.count({
const reserved = prisma.consumableReservation.count({
where: {
...identification,
},
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/+layout.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const load = loadFlash(async ({ locals, depends }) => {
? await getMyGroupedNotifications(user, prisma)
: null;
depends("cart");
const shopItemCounts = await countUserShopItems(prisma, user);
const shopItemCounts = countUserShopItems(prisma, user);

if (hasCacheExpired(alertsCache)) {
alertsCache.alerts = await prisma.alert.findMany({
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/shop/tickets/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const load: PageServerLoad = async ({ locals, depends }) => {
};
const allTickets = await getTickets(prisma, identification);
if (locals.isApp && memberId) {
const shopItemCounts = await countUserShopItems(prisma, user);
const shopItemCounts = countUserShopItems(prisma, user);
return {
shopItemCounts,
tickets: allTickets,
Expand Down
32 changes: 18 additions & 14 deletions src/routes/(app)/shop/tickets/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,25 @@

{m.navbar_userMenu_inventory()}
<!-- checks both not undefined and not 0 (since it's falsy) -->
{#if data.shopItemCounts?.unconsumed}
<span class="badge badge-primary badge-sm">
{data.shopItemCounts.unconsumed}
</span>
{/if}
{#await data.shopItemCounts?.unconsumed then unconsumed}
{#if unconsumed}
<span class="badge badge-primary badge-sm">
{unconsumed}
</span>
{/if}
{/await}
</a>
{#if data.shopItemCounts?.inCart}
<a class="btn" href="cart">
<NavIcon icon="i-mdi-cart" />
{m.navbar_userMenu_cart()}
<span class="badge badge-error badge-sm">
{data.shopItemCounts.inCart}
</span>
</a>
{/if}
{#await data.shopItemCounts?.inCart then inCart}
{#if inCart}
<a class="btn" href="cart">
<NavIcon icon="i-mdi-cart" />
{m.navbar_userMenu_cart()}
<span class="badge badge-error badge-sm">
{inCart}
</span>
</a>
{/if}
{/await}
</div>
{/if}
{#if isAuthorized(apiNames.WEBSHOP.CREATE, data.user)}
Expand Down
33 changes: 20 additions & 13 deletions src/routes/AppBottomNav.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,29 @@
style="left: {currentRouteIndex * (100 / routesToShow.length) + 2.5}%;"
/>
{#each routesToShow as route (route.path)}
{#if shopItemCounts?.inCart && route.specialBehaviour === "cart-badge"}
<!-- shop icon -->
<a href={route.path}>
<div class="indicator">
<NavIcon icon={route.icon} />
<span class="badge indicator-item badge-error">
{shopItemCounts.inCart}
</span>
<!-- <span class="btm-nav-label text-[0.5rem] uppercase">{route.title}</span> -->
</div>
</a>
{:else}
{#await shopItemCounts?.inCart}
<a href={route.path}>
<NavIcon icon={route.icon} />
<!-- <span class="btm-nav-label text-[0.5rem] uppercase">{route.title}</span> -->
</a>
{/if}
{:then inCart}
{#if inCart && route.specialBehaviour === "cart-badge"}
<!-- shop icon -->
<a href={route.path}>
<div class="indicator">
<NavIcon icon={route.icon} />
<span class="badge indicator-item badge-error">
{inCart}
</span>
<!-- <span class="btm-nav-label text-[0.5rem] uppercase">{route.title}</span> -->
</div>
</a>
{:else}
<a href={route.path}>
<NavIcon icon={route.icon} />
<!-- <span class="btm-nav-label text-[0.5rem] uppercase">{route.title}</span> -->
</a>
{/if}
{/await}
{/each}
</nav>
45 changes: 25 additions & 20 deletions src/routes/UserMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,29 @@
export let user: AuthUser;
export let shopItemCounts: UserShopItemCounts;
$: amountInCart =
(shopItemCounts?.inCart ?? 0) + (shopItemCounts?.reserved ?? 0);
$: userIndicatorAmount = amountInCart > 0 ? amountInCart : undefined;
$: amountInCart = Promise.all([
shopItemCounts?.inCart,
shopItemCounts?.reserved,
]).then(([inCart, reserved]) => (inCart ?? 0) + (reserved ?? 0));
</script>

<div class="dropdown dropdown-end dropdown-hover">
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<!-- svelte-ignore a11y-label-has-associated-control -->
<label tabindex="0" class="btn btn-ghost">
{#if userIndicatorAmount !== undefined}
<div class="indicator">
<span
class="badge indicator-item badge-primary badge-sm indicator-start indicator-top"
>{amountInCart}</span
>
{#await amountInCart then amountInCart}
{#if amountInCart > 0}
<div class="indicator">
<span
class="badge indicator-item badge-primary badge-sm indicator-start indicator-top"
>{amountInCart}
</span>
<span class="i-mdi-account-circle text-2xl" />
</div>
{:else}
<span class="i-mdi-account-circle text-2xl" />
</div>
{:else}
<span class="i-mdi-account-circle text-2xl" />
{/if}
{/if}
{/await}
</label>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div
Expand Down Expand Up @@ -61,13 +64,15 @@
<span class="i-mdi-treasure-chest size-6 text-primary" />
{m.navbar_userMenu_inventory()}
</a>
{#if amountInCart > 0}
<a href="/shop/cart" class="btn btn-ghost w-full justify-start">
<span class="i-mdi-cart size-6 text-primary" />
<span>{m.navbar_userMenu_cart()}</span>
<span class="badge badge-primary badge-sm">{amountInCart}</span>
</a>
{/if}
{#await amountInCart then amountInCart}
{#if amountInCart > 0}
<a href="/shop/cart" class="btn btn-ghost w-full justify-start">
<span class="i-mdi-cart size-6 text-primary" />
<span>{m.navbar_userMenu_cart()}</span>
<span class="badge badge-primary badge-sm">{amountInCart}</span>
</a>
{/if}
{/await}
</div>
<span class="divider m-1" />
<LoadingButton
Expand Down

0 comments on commit 83e3661

Please sign in to comment.