refactor: use shared component for login callback pages
This commit is contained in:
		
							parent
							
								
									6d32d05d98
								
							
						
					
					
						commit
						1b949a013d
					
				
					 8 changed files with 253 additions and 248 deletions
				
			
		
							
								
								
									
										23
									
								
								frontend/src/lib/api/responses.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								frontend/src/lib/api/responses.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| import type { MeUser } from "./entities"; | ||||
| 
 | ||||
| export interface SignupResponse { | ||||
|   user: MeUser; | ||||
|   token: string; | ||||
| } | ||||
| 
 | ||||
| export interface MetaResponse { | ||||
|   git_repository: string; | ||||
|   git_commit: string; | ||||
|   users: number; | ||||
|   members: number; | ||||
|   require_invite: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface UrlsResponse { | ||||
|   discord: string; | ||||
| } | ||||
| 
 | ||||
| export interface ExportResponse { | ||||
|   path: string; | ||||
|   created_at: string; | ||||
| } | ||||
|  | @ -2,6 +2,7 @@ import { error } from "@sveltejs/kit"; | |||
| import type { LayoutServerLoad } from "./$types"; | ||||
| import type { APIError } from "$lib/api/entities"; | ||||
| import { apiFetch } from "$lib/api/fetch"; | ||||
| import type { MetaResponse } from "$lib/api/responses"; | ||||
| 
 | ||||
| export const load = (async (event) => { | ||||
|   try { | ||||
|  | @ -10,11 +11,3 @@ export const load = (async (event) => { | |||
|     throw error(500, (e as APIError).message); | ||||
|   } | ||||
| }) satisfies LayoutServerLoad; | ||||
| 
 | ||||
| interface MetaResponse { | ||||
|   git_repository: string; | ||||
|   git_commit: string; | ||||
|   users: number; | ||||
|   members: number; | ||||
|   require_invite: boolean; | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { apiFetch } from "$lib/api/fetch"; | ||||
| import { PUBLIC_BASE_URL } from "$env/static/public"; | ||||
| import type { UrlsResponse } from "$lib/api/responses"; | ||||
| 
 | ||||
| export const load = async () => { | ||||
|   const resp = await apiFetch<UrlsResponse>("/auth/urls", { | ||||
|  | @ -11,7 +12,3 @@ export const load = async () => { | |||
| 
 | ||||
|   return resp; | ||||
| }; | ||||
| 
 | ||||
| interface UrlsResponse { | ||||
|   discord: string; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										193
									
								
								frontend/src/routes/auth/login/CallbackPage.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								frontend/src/routes/auth/login/CallbackPage.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,193 @@ | |||
| <script lang="ts"> | ||||
|   import { goto } from "$app/navigation"; | ||||
|   import type { APIError, MeUser } from "$lib/api/entities"; | ||||
|   import { apiFetch } from "$lib/api/fetch"; | ||||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import { userStore } from "$lib/store"; | ||||
|   import { addToast } from "$lib/toast"; | ||||
|   import { onMount } from "svelte"; | ||||
|   import { | ||||
|     Alert, | ||||
|     Button, | ||||
|     FormGroup, | ||||
|     Icon, | ||||
|     Input, | ||||
|     Modal, | ||||
|     ModalBody, | ||||
|     ModalFooter, | ||||
|   } from "sveltestrap"; | ||||
| 
 | ||||
|   export let authType: string; | ||||
|   export let remoteName: string | undefined; | ||||
|   export let error: APIError | undefined; | ||||
|   export let requireInvite: boolean | undefined; | ||||
|   export let isDeleted: boolean | undefined; | ||||
|   export let ticket: string | undefined; | ||||
|   export let token: string | undefined; | ||||
|   export let user: MeUser | undefined; | ||||
|   export let deletedAt: string | undefined; | ||||
| 
 | ||||
|   onMount(() => { | ||||
|     if (!isDeleted && token && user) { | ||||
|       localStorage.setItem("pronouns-token", token); | ||||
|       localStorage.setItem("pronouns-user", JSON.stringify(user)); | ||||
|       userStore.set(user); | ||||
|       goto("/"); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   let deleteCancelled: boolean; | ||||
|   let deleteError: APIError | null; | ||||
| 
 | ||||
|   let username: string; | ||||
|   let inviteCode: string; | ||||
|   let forceDeleteName = ""; | ||||
|   let forceDeleteModalOpen = false; | ||||
|   let toggleForceDeleteModal = () => (forceDeleteModalOpen = !forceDeleteModalOpen); | ||||
| 
 | ||||
|   export let linkAccount: () => Promise<void>; | ||||
|   export let signupForm: (username: string, inviteCode: string) => Promise<void>; | ||||
| 
 | ||||
|   const forceDeleteAccount = async () => { | ||||
|     try { | ||||
|       await apiFetch<any>("/auth/force-delete", { | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           "X-Delete-Token": token!, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       deleteError = null; | ||||
|       addToast({ header: "Deleted account", body: "Successfully deleted your account" }); | ||||
|       goto("/"); | ||||
|     } catch (e) { | ||||
|       deleteError = e as APIError; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const cancelDelete = async () => { | ||||
|     try { | ||||
|       await apiFetch<any>("/auth/cancel-delete", { | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           "X-Delete-Token": token!, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       deleteCancelled = true; | ||||
|       deleteError = null; | ||||
|     } catch (e) { | ||||
|       deleteCancelled = false; | ||||
|       deleteError = e as APIError; | ||||
|     } | ||||
|   }; | ||||
| </script> | ||||
| 
 | ||||
| <svelte:head> | ||||
|   <title>Log in with the {authType} - pronouns.cc</title> | ||||
| </svelte:head> | ||||
| 
 | ||||
| <h1>Log in with the {authType}</h1> | ||||
| 
 | ||||
| {#if error} | ||||
|   <ErrorAlert {error} /> | ||||
| {/if} | ||||
| {#if ticket && $userStore} | ||||
|   <div> | ||||
|     <FormGroup floating label="{authType} username"> | ||||
|       <Input readonly value={remoteName} /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div class="my-2"> | ||||
|     <FormGroup floating label="pronouns.cc username"> | ||||
|       <Input readonly value={$userStore.name} /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div> | ||||
|     <Button on:click={linkAccount}>Link account</Button> | ||||
|     <Button color="secondary" href="/settings/auth">Cancel</Button> | ||||
|   </div> | ||||
| {:else if ticket} | ||||
|   <form on:submit|preventDefault={() => signupForm(username, inviteCode)}> | ||||
|     <div> | ||||
|       <FormGroup floating label="{authType} username"> | ||||
|         <Input readonly value={remoteName} /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     <div> | ||||
|       <FormGroup floating label="Username"> | ||||
|         <Input id="username" name="username" bind:value={username} /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     {#if requireInvite} | ||||
|       <div> | ||||
|         <FormGroup floating label="Invite code"> | ||||
|           <Input id="invite" name="invite" aria-describedby="invite-help" bind:value={inviteCode} /> | ||||
|         </FormGroup> | ||||
|         <div id="invite-help" class="form-text"> | ||||
|           <Icon name="info-circle-fill" /> You currently need an invite code to sign up. You can get | ||||
|           one from an existing user. | ||||
|         </div> | ||||
|       </div> | ||||
|     {/if} | ||||
|     <div class="form-text mb-1"> | ||||
|       By signing up, you agree to the <a href="/page/tos">terms of service</a> and the | ||||
|       <a href="/page/privacy">privacy policy</a>. | ||||
|     </div> | ||||
|     <Button type="submit" color="primary">Sign up</Button> | ||||
|   </form> | ||||
| {:else if isDeleted && token} | ||||
|   <p>Your account is pending deletion since {deletedAt}.</p> | ||||
|   <p>If you wish to cancel deletion, press the button below.</p> | ||||
|   <p> | ||||
|     <Button color="primary" on:click={cancelDelete} disabled={deleteCancelled} | ||||
|       >Cancel account deletion</Button | ||||
|     > | ||||
|   </p> | ||||
|   <p> | ||||
|     Alternatively, if you want your data wiped immediately, press the force delete link below. <b | ||||
|       >This is irreversible.</b | ||||
|     > | ||||
|   </p> | ||||
|   <p> | ||||
|     <Button color="link" on:click={toggleForceDeleteModal}>Force delete account</Button> | ||||
|   </p> | ||||
|   <Modal | ||||
|     header="Force delete account" | ||||
|     isOpen={forceDeleteModalOpen} | ||||
|     toggle={toggleForceDeleteModal} | ||||
|   > | ||||
|     <ModalBody> | ||||
|       <p> | ||||
|         If you want to delete your account, type your username below: | ||||
|         <br /> | ||||
|         <b> | ||||
|           This is irreversible! Your account <i>cannot</i> be recovered after you press "Force delete | ||||
|           account". | ||||
|         </b> | ||||
|       </p> | ||||
|       <p> | ||||
|         <input type="text" class="form-control" bind:value={forceDeleteName} /> | ||||
|       </p> | ||||
|       {#if deleteError} | ||||
|         <ErrorAlert error={deleteError} /> | ||||
|       {/if} | ||||
|     </ModalBody> | ||||
|     <ModalFooter> | ||||
|       <Button color="danger" on:click={forceDeleteAccount} disabled={forceDeleteName !== user?.name} | ||||
|         >Force delete account</Button | ||||
|       > | ||||
|       <Button color="secondary" on:click={toggleForceDeleteModal}>Cancel delete</Button> | ||||
|     </ModalFooter> | ||||
|   </Modal> | ||||
|   {#if deleteCancelled} | ||||
|     <Alert color="secondary" fade={false}> | ||||
|       Account deletion cancelled! You can now <a href="/auth/login">log in</a> again. | ||||
|     </Alert> | ||||
|   {/if} | ||||
|   {#if deleteError} | ||||
|     <ErrorAlert error={deleteError} /> | ||||
|   {/if} | ||||
| {:else} | ||||
|   Loading... | ||||
| {/if} | ||||
|  | @ -1,36 +1,16 @@ | |||
| <script lang="ts"> | ||||
|   import { onMount } from "svelte"; | ||||
|   import { Alert, Button, FormGroup, Icon, Input } from "sveltestrap"; | ||||
| 
 | ||||
|   import { goto } from "$app/navigation"; | ||||
|   import type { APIError, MeUser } from "$lib/api/entities"; | ||||
|   import { apiFetch, apiFetchClient } from "$lib/api/fetch"; | ||||
|   import { userStore } from "$lib/store"; | ||||
|   import type { PageData } from "./$types"; | ||||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import { addToast } from "$lib/toast"; | ||||
| 
 | ||||
|   interface SignupResponse { | ||||
|     user: MeUser; | ||||
|     token: string; | ||||
|   } | ||||
|   import CallbackPage from "../CallbackPage.svelte"; | ||||
|   import type { SignupResponse } from "$lib/api/responses"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
| 
 | ||||
|   onMount(() => { | ||||
|     if (!data.is_deleted && data.token && data.user) { | ||||
|       localStorage.setItem("pronouns-token", data.token); | ||||
|       localStorage.setItem("pronouns-user", JSON.stringify(data.user)); | ||||
|       userStore.set(data.user); | ||||
|       addToast({ header: "Logged in", body: "Successfully logged in!" }); | ||||
|       goto("/"); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   let username = ""; | ||||
|   let invite = ""; | ||||
| 
 | ||||
|   const signupForm = async () => { | ||||
|   const signupForm = async (username: string, invite: string) => { | ||||
|     try { | ||||
|       const resp = await apiFetch<SignupResponse>("/auth/discord/signup", { | ||||
|         method: "POST", | ||||
|  | @ -51,25 +31,6 @@ | |||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   let deleteCancelled = false; | ||||
|   let deleteError: APIError | null = null; | ||||
|   const cancelDelete = async () => { | ||||
|     try { | ||||
|       await apiFetch<any>("/auth/cancel-delete", { | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           "X-Delete-Token": data.token!, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       deleteCancelled = true; | ||||
|       deleteError = null; | ||||
|     } catch (e) { | ||||
|       deleteCancelled = false; | ||||
|       deleteError = e as APIError; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const linkAccount = async () => { | ||||
|     try { | ||||
|       const resp = await apiFetchClient<MeUser>("/auth/discord/add-provider", "POST", { | ||||
|  | @ -86,75 +47,16 @@ | |||
|   }; | ||||
| </script> | ||||
| 
 | ||||
| <svelte:head> | ||||
|   <title>Log in with Discord - pronouns.cc</title> | ||||
| </svelte:head> | ||||
| 
 | ||||
| <h1>Log in with Discord</h1> | ||||
| 
 | ||||
| {#if data.error} | ||||
|   <ErrorAlert error={data.error} /> | ||||
| {/if} | ||||
| {#if data.ticket && $userStore} | ||||
|   <div> | ||||
|     <FormGroup floating label="Discord username"> | ||||
|       <Input readonly value={data.discord} /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div class="my-2"> | ||||
|     <FormGroup floating label="pronouns.cc username"> | ||||
|       <Input readonly value={$userStore.name} /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div> | ||||
|     <Button on:click={linkAccount}>Link account</Button> | ||||
|     <Button color="secondary" href="/settings/auth">Cancel</Button> | ||||
|   </div> | ||||
| {:else if data.ticket} | ||||
|   <form on:submit|preventDefault={signupForm}> | ||||
|     <div> | ||||
|       <FormGroup floating label="Discord username"> | ||||
|         <Input readonly value={data.discord} /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     <div> | ||||
|       <FormGroup floating label="Username"> | ||||
|         <Input id="username" name="username" bind:value={username} /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     {#if data.require_invite} | ||||
|       <div> | ||||
|         <FormGroup floating label="Invite code"> | ||||
|           <Input id="invite" name="invite" aria-describedby="invite-help" bind:value={invite} /> | ||||
|         </FormGroup> | ||||
|         <div id="invite-help" class="form-text"> | ||||
|           <Icon name="info-circle-fill" /> You currently need an invite code to sign up. You can get | ||||
|           one from an existing user. | ||||
|         </div> | ||||
|       </div> | ||||
|     {/if} | ||||
|     <div class="form-text mb-1"> | ||||
|       By signing up, you agree to the <a href="/page/tos">terms of service</a> and the | ||||
|       <a href="/page/privacy">privacy policy</a>. | ||||
|     </div> | ||||
|     <Button type="submit" color="primary">Sign up</Button> | ||||
|   </form> | ||||
| {:else if data.is_deleted && data.token} | ||||
|   <p>Your account is pending deletion since {data.deleted_at}.</p> | ||||
|   <p>If you wish to cancel deletion, press the button below.</p> | ||||
|   <p> | ||||
|     <Button color="primary" on:click={cancelDelete} disabled={deleteCancelled} | ||||
|       >Cancel account deletion</Button | ||||
|     > | ||||
|   </p> | ||||
|   {#if deleteCancelled} | ||||
|     <Alert color="secondary" fade={false}> | ||||
|       Account deletion cancelled! You can now <a href="/auth/login">log in</a> again. | ||||
|     </Alert> | ||||
|   {/if} | ||||
|   {#if deleteError} | ||||
|     <ErrorAlert error={deleteError} /> | ||||
|   {/if} | ||||
| {:else} | ||||
|   Loading... | ||||
| {/if} | ||||
| <CallbackPage | ||||
|   authType="Discord" | ||||
|   remoteName={data.discord} | ||||
|   error={data.error} | ||||
|   requireInvite={data.require_invite} | ||||
|   isDeleted={data.is_deleted} | ||||
|   ticket={data.ticket} | ||||
|   token={data.token} | ||||
|   user={data.user} | ||||
|   deletedAt={data.deleted_at} | ||||
|   {linkAccount} | ||||
|   {signupForm} | ||||
| /> | ||||
|  |  | |||
|  | @ -1,35 +1,16 @@ | |||
| <script lang="ts"> | ||||
|   import { onMount } from "svelte"; | ||||
|   import { Alert, Button, FormGroup, Icon, Input } from "sveltestrap"; | ||||
| 
 | ||||
|   import { goto } from "$app/navigation"; | ||||
|   import type { APIError, MeUser } from "$lib/api/entities"; | ||||
|   import { apiFetch, apiFetchClient } from "$lib/api/fetch"; | ||||
|   import { userStore } from "$lib/store"; | ||||
|   import type { PageData } from "./$types"; | ||||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import { addToast } from "$lib/toast"; | ||||
| 
 | ||||
|   interface SignupResponse { | ||||
|     user: MeUser; | ||||
|     token: string; | ||||
|   } | ||||
|   import CallbackPage from "../../CallbackPage.svelte"; | ||||
|   import type { SignupResponse } from "$lib/api/responses"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
| 
 | ||||
|   onMount(() => { | ||||
|     if (!data.is_deleted && data.token && data.user) { | ||||
|       localStorage.setItem("pronouns-token", data.token); | ||||
|       localStorage.setItem("pronouns-user", JSON.stringify(data.user)); | ||||
|       userStore.set(data.user); | ||||
|       goto("/"); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   let username = ""; | ||||
|   let invite = ""; | ||||
| 
 | ||||
|   const signupForm = async () => { | ||||
|   const signupForm = async (username: string, invite: string) => { | ||||
|     try { | ||||
|       const resp = await apiFetch<SignupResponse>("/auth/mastodon/signup", { | ||||
|         method: "POST", | ||||
|  | @ -44,31 +25,13 @@ | |||
|       localStorage.setItem("pronouns-token", resp.token); | ||||
|       localStorage.setItem("pronouns-user", JSON.stringify(resp.user)); | ||||
|       userStore.set(resp.user); | ||||
|       addToast({ header: "Welcome!", body: "Signed up successfully!" }); | ||||
|       goto("/"); | ||||
|     } catch (e) { | ||||
|       data.error = e as APIError; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   let deleteCancelled = false; | ||||
|   let deleteError: APIError | null = null; | ||||
|   const cancelDelete = async () => { | ||||
|     try { | ||||
|       await apiFetch<any>("/auth/cancel-delete", { | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           "X-Delete-Token": data.token!, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       deleteCancelled = true; | ||||
|       deleteError = null; | ||||
|     } catch (e) { | ||||
|       deleteCancelled = false; | ||||
|       deleteError = e as APIError; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const linkAccount = async () => { | ||||
|     try { | ||||
|       const resp = await apiFetchClient<MeUser>("/auth/mastodon/add-provider", "POST", { | ||||
|  | @ -86,75 +49,16 @@ | |||
|   }; | ||||
| </script> | ||||
| 
 | ||||
| <svelte:head> | ||||
|   <title>Log in with the Fediverse - pronouns.cc</title> | ||||
| </svelte:head> | ||||
| 
 | ||||
| <h1>Log in with the Fediverse</h1> | ||||
| 
 | ||||
| {#if data.error} | ||||
|   <ErrorAlert error={data.error} /> | ||||
| {/if} | ||||
| {#if data.ticket && $userStore} | ||||
|   <div> | ||||
|     <FormGroup floating label="Fediverse username"> | ||||
|       <Input readonly value="{data.fediverse}@{data.instance}" /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div class="my-2"> | ||||
|     <FormGroup floating label="pronouns.cc username"> | ||||
|       <Input readonly value={$userStore.name} /> | ||||
|     </FormGroup> | ||||
|   </div> | ||||
|   <div> | ||||
|     <Button on:click={linkAccount}>Link account</Button> | ||||
|     <Button color="secondary" href="/settings/auth">Cancel</Button> | ||||
|   </div> | ||||
| {:else if data.ticket} | ||||
|   <form on:submit|preventDefault={signupForm}> | ||||
|     <div> | ||||
|       <FormGroup floating label="Fediverse username"> | ||||
|         <Input readonly value="{data.fediverse}@{data.instance}" /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     <div> | ||||
|       <FormGroup floating label="Username"> | ||||
|         <Input id="username" name="username" bind:value={username} /> | ||||
|       </FormGroup> | ||||
|     </div> | ||||
|     {#if data.require_invite} | ||||
|       <div> | ||||
|         <FormGroup floating label="Invite code"> | ||||
|           <Input id="invite" name="invite" aria-describedby="invite-help" bind:value={invite} /> | ||||
|         </FormGroup> | ||||
|         <div id="invite-help" class="form-text"> | ||||
|           <Icon name="info-circle-fill" /> You currently need an invite code to sign up. You can get | ||||
|           one from an existing user. | ||||
|         </div> | ||||
|       </div> | ||||
|     {/if} | ||||
|     <div class="form-text mb-1"> | ||||
|       By signing up, you agree to the <a href="/page/tos">terms of service</a> and the | ||||
|       <a href="/page/privacy">privacy policy</a>. | ||||
|     </div> | ||||
|     <Button type="submit" color="primary">Sign up</Button> | ||||
|   </form> | ||||
| {:else if data.is_deleted && data.token} | ||||
|   <p>Your account is pending deletion since {data.deleted_at}.</p> | ||||
|   <p>If you wish to cancel deletion, press the button below.</p> | ||||
|   <p> | ||||
|     <Button color="primary" on:click={cancelDelete} disabled={deleteCancelled} | ||||
|       >Cancel account deletion</Button | ||||
|     > | ||||
|   </p> | ||||
|   {#if deleteCancelled} | ||||
|     <Alert color="secondary" fade={false}> | ||||
|       Account deletion cancelled! You can now <a href="/auth/login">log in</a> again. | ||||
|     </Alert> | ||||
|   {/if} | ||||
|   {#if deleteError} | ||||
|     <ErrorAlert error={deleteError} /> | ||||
|   {/if} | ||||
| {:else} | ||||
|   Loading... | ||||
| {/if} | ||||
| <CallbackPage | ||||
|   authType="Fediverse" | ||||
|   remoteName="{data.fediverse}@{data.instance}" | ||||
|   error={data.error} | ||||
|   requireInvite={data.require_invite} | ||||
|   isDeleted={data.is_deleted} | ||||
|   ticket={data.ticket} | ||||
|   token={data.token} | ||||
|   user={data.user} | ||||
|   deletedAt={data.deleted_at} | ||||
|   {linkAccount} | ||||
|   {signupForm} | ||||
| /> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { PUBLIC_BASE_URL } from "$env/static/public"; | ||||
| import { apiFetch } from "$lib/api/fetch"; | ||||
| import type { UrlsResponse } from "$lib/api/responses"; | ||||
| 
 | ||||
| export const load = async () => { | ||||
|   const resp = await apiFetch<UrlsResponse>("/auth/urls", { | ||||
|  | @ -11,7 +12,3 @@ export const load = async () => { | |||
| 
 | ||||
|   return { urls: resp }; | ||||
| }; | ||||
| 
 | ||||
| interface UrlsResponse { | ||||
|   discord: string; | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { ErrorCode, type APIError } from "$lib/api/entities"; | ||||
| import { apiFetchClient } from "$lib/api/fetch"; | ||||
| import type { ExportResponse } from "$lib/api/responses"; | ||||
| import { error } from "@sveltejs/kit"; | ||||
| 
 | ||||
| export const load = async () => { | ||||
|  | @ -12,8 +13,3 @@ export const load = async () => { | |||
|     throw error((e as APIError).code, (e as APIError).message); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| interface ExportResponse { | ||||
|   path: string; | ||||
|   created_at: string; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue