mirror of
https://github.com/jcreek/SvelteKitSaasBoilerplate.git
synced 2026-07-13 02:53:50 +00:00
feat(#34): display message in place of add to basket for prior purchase
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
import { hasProductAccess } from '$lib/utils/supabase/admin';
|
||||||
|
|
||||||
|
export const load = async ({ params, locals: { safeGetSession }, fetch }) => {
|
||||||
|
const { session } = await safeGetSession();
|
||||||
|
if (!session) {
|
||||||
|
throw redirect(303, '/login'); // Redirect unauthenticated users to login
|
||||||
|
}
|
||||||
|
|
||||||
|
const productResponse = await fetch(`/products/${params.productId}`);
|
||||||
|
const product = await productResponse.json();
|
||||||
|
|
||||||
|
// Create the item object
|
||||||
|
const item = {
|
||||||
|
id: product.id,
|
||||||
|
name: product.name,
|
||||||
|
categoryDescription: product.description,
|
||||||
|
imgAlt: product.description,
|
||||||
|
imgSrc: product.images[0],
|
||||||
|
price: 0,
|
||||||
|
priceId: product.default_price,
|
||||||
|
quantity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the price of the product
|
||||||
|
const priceResponse = await fetch(`/products/prices/${product.default_price}`);
|
||||||
|
const price = await priceResponse.json();
|
||||||
|
// Set the price of the product
|
||||||
|
item.price = price.unit_amount / 100;
|
||||||
|
|
||||||
|
// Check if the user has access to the 'EXAMPLE PRODUCT' product
|
||||||
|
const hasPurchasedProduct = await hasProductAccess(session.user.id, params.productId);
|
||||||
|
|
||||||
|
return { params, hasPurchasedProduct, item };
|
||||||
|
};
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
import { basket, type Basket, type Item } from '$lib/stores/basket.js';
|
import { basket, type Basket, type Item } from '$lib/stores/basket.js';
|
||||||
import { general } from '$lib/stores/generalStore.js';
|
import { general } from '$lib/stores/generalStore.js';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
|
let { supabase, session, hasPurchasedProduct, item } = data;
|
||||||
|
$: ({ supabase, session, hasPurchasedProduct, item } = data);
|
||||||
|
|
||||||
let localBasket: Basket;
|
let localBasket: Basket;
|
||||||
const unsubscribeToBasket = basket.subscribe((value) => {
|
const unsubscribeToBasket = basket.subscribe((value) => {
|
||||||
localBasket = value;
|
localBasket = value;
|
||||||
@@ -16,6 +20,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function addToBasket() {
|
function addToBasket() {
|
||||||
|
if (!session) {
|
||||||
|
redirect(303, '/');
|
||||||
|
}
|
||||||
basket.update((value) => {
|
basket.update((value) => {
|
||||||
const existingItemIndex = value.items.findIndex((basketItem) => basketItem.id === item.id);
|
const existingItemIndex = value.items.findIndex((basketItem) => basketItem.id === item.id);
|
||||||
|
|
||||||
@@ -43,32 +50,6 @@
|
|||||||
});
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = {};
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
fetch(`/products/${data.productId}`)
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((product) => {
|
|
||||||
item = {
|
|
||||||
id: product.id,
|
|
||||||
name: product.name,
|
|
||||||
categoryDescription: product.description,
|
|
||||||
imgAlt: product.description,
|
|
||||||
imgSrc: product.images[0],
|
|
||||||
price: 0,
|
|
||||||
priceId: product.default_price,
|
|
||||||
quantity: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fetch the price of the product
|
|
||||||
fetch(`/products/prices/${product.default_price}`)
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((price) => {
|
|
||||||
item.price = price.unit_amount / 100;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="relative">
|
<section class="relative">
|
||||||
@@ -370,27 +351,50 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
{#if !hasPurchasedProduct}
|
||||||
class="group py-4 px-5 rounded-full bg-indigo-50 text-indigo-600 font-semibold text-lg w-full flex items-center justify-center gap-2 transition-all duration-500 hover:bg-indigo-100"
|
<button
|
||||||
on:click={addToBasket}
|
class="group py-4 px-5 rounded-full bg-indigo-50 text-indigo-600 font-semibold text-lg w-full flex items-center justify-center gap-2 transition-all duration-500 hover:bg-indigo-100"
|
||||||
>
|
on:click={addToBasket}
|
||||||
<svg
|
|
||||||
class="stroke-indigo-600"
|
|
||||||
width="22"
|
|
||||||
height="22"
|
|
||||||
viewBox="0 0 22 22"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M10.7394 17.875C10.7394 18.6344 10.1062 19.25 9.32511 19.25C8.54402 19.25 7.91083 18.6344 7.91083 17.875M16.3965 17.875C16.3965 18.6344 15.7633 19.25 14.9823 19.25C14.2012 19.25 13.568 18.6344 13.568 17.875M4.1394 5.5L5.46568 12.5908C5.73339 14.0221 5.86724 14.7377 6.37649 15.1605C6.88573 15.5833 7.61377 15.5833 9.06984 15.5833H15.2379C16.6941 15.5833 17.4222 15.5833 17.9314 15.1605C18.4407 14.7376 18.5745 14.0219 18.8421 12.5906L19.3564 9.84059C19.7324 7.82973 19.9203 6.8243 19.3705 6.16215C18.8207 5.5 17.7979 5.5 15.7522 5.5H4.1394ZM4.1394 5.5L3.66797 2.75"
|
class="stroke-indigo-600"
|
||||||
stroke=""
|
width="22"
|
||||||
stroke-width="1.6"
|
height="22"
|
||||||
stroke-linecap="round"
|
viewBox="0 0 22 22"
|
||||||
/>
|
fill="none"
|
||||||
</svg>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
Add to basket</button
|
>
|
||||||
>
|
<path
|
||||||
|
d="M10.7394 17.875C10.7394 18.6344 10.1062 19.25 9.32511 19.25C8.54402 19.25 7.91083 18.6344 7.91083 17.875M16.3965 17.875C16.3965 18.6344 15.7633 19.25 14.9823 19.25C14.2012 19.25 13.568 18.6344 13.568 17.875M4.1394 5.5L5.46568 12.5908C5.73339 14.0221 5.86724 14.7377 6.37649 15.1605C6.88573 15.5833 7.61377 15.5833 9.06984 15.5833H15.2379C16.6941 15.5833 17.4222 15.5833 17.9314 15.1605C18.4407 14.7376 18.5745 14.0219 18.8421 12.5906L19.3564 9.84059C19.7324 7.82973 19.9203 6.8243 19.3705 6.16215C18.8207 5.5 17.7979 5.5 15.7522 5.5H4.1394ZM4.1394 5.5L3.66797 2.75"
|
||||||
|
stroke=""
|
||||||
|
stroke-width="1.6"
|
||||||
|
stroke-linecap="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Add to basket
|
||||||
|
</button>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
class="group py-4 px-5 rounded-full bg-indigo-50 text-indigo-600 font-semibold text-lg w-full flex items-center justify-center gap-2 transition-all duration-500 hover:bg-indigo-100"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="stroke-indigo-600"
|
||||||
|
width="22"
|
||||||
|
height="22"
|
||||||
|
viewBox="0 0 22 22"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10.7394 17.875C10.7394 18.6344 10.1062 19.25 9.32511 19.25C8.54402 19.25 7.91083 18.6344 7.91083 17.875M16.3965 17.875C16.3965 18.6344 15.7633 19.25 14.9823 19.25C14.2012 19.25 13.568 18.6344 13.568 17.875M4.1394 5.5L5.46568 12.5908C5.73339 14.0221 5.86724 14.7377 6.37649 15.1605C6.88573 15.5833 7.61377 15.5833 9.06984 15.5833H15.2379C16.6941 15.5833 17.4222 15.5833 17.9314 15.1605C18.4407 14.7376 18.5745 14.0219 18.8421 12.5906L19.3564 9.84059C19.7324 7.82973 19.9203 6.8243 19.3705 6.16215C18.8207 5.5 17.7979 5.5 15.7522 5.5H4.1394ZM4.1394 5.5L3.66797 2.75"
|
||||||
|
stroke=""
|
||||||
|
stroke-width="1.6"
|
||||||
|
stroke-linecap="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
You own this already
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
/** @type {import('./$types').PageLoad} */
|
|
||||||
export function load({ params }) {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user