diff --git a/src/lib/utils/supabase/admin.ts b/src/lib/utils/supabase/admin.ts index 4052695..4ae82d2 100644 --- a/src/lib/utils/supabase/admin.ts +++ b/src/lib/utils/supabase/admin.ts @@ -480,6 +480,96 @@ const getProductById = async (productId: string) => { return product as Product; }; +const getUserSubscriptions = async (userId: string) => { + try { + // Step 1: Retrieve subscription data + const { data: subscriptions, error } = await supabaseAdmin + .from('subscriptions') + .select('*') + .eq('user_id', userId); + + if (error) { + console.error('Error retrieving subscriptions:', error.message); + throw new Error('Failed to fetch subscriptions'); + } + + // Step 2: Map through each subscription and fetch product and price details + const subscriptionDetails = await Promise.all( + subscriptions.map(async (sub) => { + // Fetch product and price details from Stripe + const product = await stripeClient.products.retrieve(sub.product_id); + const price = await stripeClient.prices.retrieve(sub.price_id); + + console.log(sub); + + const expiryDate = new Date(sub.current_period_end); + + // Format output data + return { + productName: product.name, + amount: (price.unit_amount / 100).toFixed(2), + currency: price.currency.toUpperCase(), + interval: price.recurring?.interval || 'one-time', + expiryDate: expiryDate.toLocaleDateString('en-GB', { + day: '2-digit', + month: '2-digit', + year: 'numeric' + }), + status: sub.status + }; + }) + ); + + return subscriptionDetails; + } catch (error) { + console.error('An error occurred while retrieving subscription details:', error); + throw new Error('Could not retrieve subscription details'); + } +}; + +const getUserTransactions = async (userId: string) => { + try { + // Step 1: Retrieve the customer ID associated with the user + const { data, error } = await supabaseAdmin + .from('customers') + .select('stripe_customer_id') + .eq('id', userId) + .single(); + + if (error) { + console.error('Error retrieving user data:', error.message); + throw new Error('Failed to fetch user data'); + } + + const customerId = data?.stripe_customer_id; + if (!customerId) { + throw new Error('No Stripe customer ID found for this user'); + } + + // Step 2: Fetch charge transactions from Stripe + const charges = await stripeClient.charges.list({ customer: customerId }); + + // Step 3: Format transaction data + const transactions = charges.data.map((charge) => ({ + amount: (charge.amount / 100).toFixed(2), + currency: charge.currency.toUpperCase(), + description: charge.description ?? 'No description provided', + status: charge.status, + created: new Date(charge.created * 1000).toLocaleDateString('en-GB', { + day: '2-digit', + month: '2-digit', + year: 'numeric' + }), + receipt_url: charge.receipt_url + })); + + return transactions; + } catch (error) { + console.error('An error occurred while retrieving transactions:', error); + throw new Error('Could not retrieve transactions'); + } +}; + export { upsertProductRecord, upsertPriceRecord, @@ -495,5 +585,7 @@ export { getActiveProductsWithPrices, getProductById, upsertCustomerToSupabase, - getStripeCustomerId + getStripeCustomerId, + getUserSubscriptions, + getUserTransactions }; diff --git a/src/routes/account/+page.server.ts b/src/routes/account/+page.server.ts index d839775..ba26c6a 100644 --- a/src/routes/account/+page.server.ts +++ b/src/routes/account/+page.server.ts @@ -1,5 +1,6 @@ import { fail, redirect } from '@sveltejs/kit'; import type { Actions, PageServerLoad } from './$types'; +import { getUserSubscriptions, getUserTransactions } from '$lib/utils/supabase/admin'; export const load: PageServerLoad = async ({ locals: { supabase, safeGetSession } }) => { const { session } = await safeGetSession(); @@ -14,7 +15,11 @@ export const load: PageServerLoad = async ({ locals: { supabase, safeGetSession .eq('id', session.user.id) .single(); - return { session, user }; + const subscriptions = await getUserSubscriptions(session.user.id); + + const transactions = await getUserTransactions(session.user.id); + + return { session, user, subscriptions, transactions }; }; export const actions: Actions = { @@ -27,20 +32,23 @@ export const actions: Actions = { if (!session) { return fail(401, { name }); } - const { error } = await supabase.from('users').update({ - name: name, - }).eq('id', session?.user.id); + const { error } = await supabase + .from('users') + .update({ + name: name + }) + .eq('id', session?.user.id); console.error(error); if (error) { return fail(500, { - name, + name }); } return { - name, + name }; }, signout: async ({ locals: { supabase, safeGetSession } }) => { diff --git a/src/routes/account/+page.svelte b/src/routes/account/+page.svelte index 5435c0d..a97b25e 100644 --- a/src/routes/account/+page.svelte +++ b/src/routes/account/+page.svelte @@ -5,7 +5,7 @@ export let data; export let form; - let { session, supabase, user } = data; + let { session, user, subscriptions, transactions } = data; $: ({ session, supabase, user } = data); let profileForm: HTMLFormElement; @@ -18,16 +18,6 @@ loading = false; }; }; - - const subscriptions = [ - { name: 'Premium Plan', nextBillingDate: '12th August 2021' }, - { name: 'Basic Plan', nextBillingDate: '12th August 2021' } - ]; - - const billingHistory = [ - { id: 123, date: '12th August 2021', amount: 9.99, downloadLink: '#' }, - { id: 122, date: '12th July 2021', amount: 9.99, downloadLink: '#' } - ];
{subscription.name}
-Renewal Date: {subscription.nextBillingDate}
+You do not have any subscriptions.
+ {:else} +{subscription.productName}
++ Price: {subscription.amount} + {subscription.currency} / {subscription.interval} +
++ Expiry Date: {subscription.expiryDate} +
++ Status: {subscription.status} +
+Invoice #{invoice.id}
-Date: {invoice.date}
-Amount: £{invoice.amount}
+Date: {transaction.created}
++ Amount: {transaction.amount} + {transaction.currency} +