From d23f6adeff0146b0004c4e407c8b5f87ead1aeef Mon Sep 17 00:00:00 2001 From: Torwent Date: Tue, 9 Jan 2024 13:19:16 +0100 Subject: [PATCH] fix: read notes - reworked the dashboard so it's less overwhelming. it now has tabs for each "category" of thing you are looking at. - added front-end for editing stripe's business name (aka doing business as) - made the default for new connect accounts to have their business name as their discord username --- src/lib/backend/data.server.ts | 32 +++ src/lib/backend/schemas.ts | 4 + src/routes/dashboard/Table.svelte | 3 +- src/routes/dashboard/[slug]/+page.server.ts | 52 ++++- src/routes/dashboard/[slug]/+page.svelte | 237 ++++++++++++++------ src/routes/dashboard/[slug]/+page.ts | 7 + 6 files changed, 255 insertions(+), 80 deletions(-) diff --git a/src/lib/backend/data.server.ts b/src/lib/backend/data.server.ts index 0123e1d..c0c24f6 100644 --- a/src/lib/backend/data.server.ts +++ b/src/lib/backend/data.server.ts @@ -292,6 +292,7 @@ export async function createStripeConnectAccount( }, business_profile: { mcc: "5734", + name: scripter.profiles.username, support_url: "https://waspscripts.com/scripters/" + scripter.url, url: "https://waspscripts.com/scripters/" + scripter.url, support_email: "support@waspscripts.com" @@ -352,6 +353,37 @@ export async function finishStripeAccountSetup(baseURL: string, account: string) return accountLink.url } +export async function getStripeAccount(id: string) { + let stripeAccount: Stripe.Response | null = null + + try { + stripeAccount = await stripe.accounts.retrieve(id) + } catch (error) { + console.error( + "An error occurred when calling the Stripe API to create an account session", + error + ) + } + + return stripeAccount +} + +export async function updateStripeAccount(id: string, dba: string) { + let stripeAccount: Stripe.Response | null = null + + try { + stripeAccount = await stripe.accounts.update(id, { business_profile: { name: dba } }) + } catch (error) { + console.error( + "An error occurred when calling the Stripe API to create an account session", + error + ) + return false + } + + return true +} + export async function getStripeSession(account: string) { let accountSession: Stripe.Response | null = null diff --git a/src/lib/backend/schemas.ts b/src/lib/backend/schemas.ts index e4479d2..692eb7b 100644 --- a/src/lib/backend/schemas.ts +++ b/src/lib/backend/schemas.ts @@ -359,6 +359,10 @@ export const countryCodeSchema = z.object({ code: z.string().length(2, "Country codes have to be only 2 letters") }) +export const dbaSchema = z.object({ + dba: z.string().min(3, "Your name needs to be longer") +}) + export type PriceSchema = z.infer export type BundleSchema = z.infer export type NewScriptSchema = z.infer diff --git a/src/routes/dashboard/Table.svelte b/src/routes/dashboard/Table.svelte index c57fdfd..e09a40b 100644 --- a/src/routes/dashboard/Table.svelte +++ b/src/routes/dashboard/Table.svelte @@ -25,8 +25,7 @@ multipleSubmits: "prevent", clearOnSubmit: "errors-and-message", validators: schema, - resetForm: true, - invalidateAll: true + resetForm: true }) const btnText = action.includes("dd") ? "Add" : "Save" diff --git a/src/routes/dashboard/[slug]/+page.server.ts b/src/routes/dashboard/[slug]/+page.server.ts index 5f9a4ea..900904c 100644 --- a/src/routes/dashboard/[slug]/+page.server.ts +++ b/src/routes/dashboard/[slug]/+page.server.ts @@ -8,11 +8,14 @@ import { finishStripeAccountSetup, updateStripePrice, updateStripeProduct, - getStripeSession + getStripeSession, + getStripeAccount, + updateStripeAccount } from "$lib/backend/data.server" import { bundleArraySchema, countryCodeSchema, + dbaSchema, newBundleSchema, newScriptArraySchema, scriptArraySchema @@ -35,6 +38,7 @@ export const load = async (event) => { const promises = await Promise.all([ superValidate(event, countryCodeSchema), + superValidate(event, dbaSchema), superValidate(event, bundleArraySchema), superValidate(event, newBundleSchema), superValidate(event, scriptArraySchema), @@ -43,15 +47,21 @@ export const load = async (event) => { ]) event.depends("dashboard:stripe_session") - const stripeSession = promises[5].stripe ? await getStripeSession(promises[5].stripe) : null + + const scripter = promises[6] + + const stripeAccount = scripter.stripe ? await getStripeAccount(scripter.stripe) : null + const stripeSession = scripter.stripe ? await getStripeSession(scripter.stripe) : null return { countryForm: promises[0], - bundlesForm: promises[1], - newBundleForm: promises[2], - scriptsForm: promises[3], - newScriptForm: promises[4], - stripeSession: stripeSession + dbaForm: promises[1], + bundlesForm: promises[2], + newBundleForm: promises[3], + scriptsForm: promises[4], + newScriptForm: promises[5], + stripeAccount, + stripeSession } } @@ -108,6 +118,34 @@ export const actions = { return }, + displayName: async ({ + request, + locals: { supabaseServer, getSession, getProfile }, + url: { origin }, + params: { slug } + }) => { + const promises = await Promise.all([getSession(), getProfile(), request.formData()]) + const profile = promises[1] + + if (!promises[0] || !profile) { + return await doLogin(supabaseServer, origin, new URLSearchParams("login&provider=discord")) + } + + if (!UUID_V4_REGEX.test(slug)) throw error(403, "Invalid dashboard UUID.") + if (profile.id !== slug && !profile.roles.administrator) + throw error(403, "You cannot access another scripter dashboard.") + + const scripter = await getScripterDashboard(supabaseServer, slug) + + const form = await superValidate(promises[2], dbaSchema) + if (!form.valid) return setError(form, "", "The name you set is not valid!") + if (!scripter.stripe) return setError(form, "", "The user is missing a stripe profile!") + + const success = await updateStripeAccount(scripter.stripe, form.data.dba) + if (!success) return setError(form, "", "Failed to update stripe's business name") + return + }, + bundleEdit: async ({ request, locals: { supabaseServer, getSession, getProfile }, diff --git a/src/routes/dashboard/[slug]/+page.svelte b/src/routes/dashboard/[slug]/+page.svelte index cad7615..d1dbb3f 100644 --- a/src/routes/dashboard/[slug]/+page.svelte +++ b/src/routes/dashboard/[slug]/+page.svelte @@ -1,11 +1,12 @@ @@ -75,12 +107,17 @@ Scripter profile {#if !scripter.stripe} -
+

Stripe Account

- @@ -125,18 +162,18 @@
- {#if $errors && $errors.code} + {#if $countryErrors && $countryErrors.code}
- {$errors.code} + {$countryErrors.code}
{/if} - {#if $allErrors} + {#if $countryAllErrors}
- {#each $allErrors as error, i} + {#each $countryAllErrors as error, i} {#if i === 0} Errors: {/if} @@ -149,7 +186,7 @@ {/each}
{/if} -
@@ -198,57 +235,115 @@ {#if scripter.stripe} -

Bundles

- - - -
- -

Premium scripts

- -
- -
- -
-

Stripe Dashboard

- -
Payments
-
-
Payouts
-
+
+ + +
Stripe
+
+ +
Bundles
+
+ +
Scripts
+
+ + + {#if tabSet === 0} +
+
+ + + {#if $dbaErrors && $dbaErrors.dba} +
+ {$dbaErrors.dba} +
+ {/if} + {#if $dbaAllErrors} +
+ {#each $dbaAllErrors as error, i} + {#if i === 0} + Errors: + {/if} + + Error path: {error.path} + {#each error.messages as messages} + {messages} + {/each} + + {/each} +
+ {/if} +
+ + + +
Payments
+
+
Payouts
+
+ {:else if tabSet === 1} +
+ +
+ {:else if tabSet === 2} +
+ +
+ {/if} + + {/if} diff --git a/src/routes/dashboard/[slug]/+page.ts b/src/routes/dashboard/[slug]/+page.ts index 969deae..480f628 100644 --- a/src/routes/dashboard/[slug]/+page.ts +++ b/src/routes/dashboard/[slug]/+page.ts @@ -279,9 +279,16 @@ export const load = async ({ parent, data, depends, url, params: { slug } }) => { amount: 50, currency: "eur", interval: "year" } ] + const stripeAccount = data.stripeAccount + const dbaForm = data.dbaForm + + dbaForm.data.dba = stripeAccount?.business_profile?.name ?? "" + return { + stripeAccount, stripeSession: data.stripeSession, countryForm: data.countryForm, + dbaForm, bundlesForm, newBundleForm, scriptsForm,