Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

Keep up with the latest updates here :D

## 2025-08-24

### Fixed

- Submit button no longer loads infinitely when signing in with an existing username through Google ([#107](https://github.com/beatcode-official/client/pull/107))

---

## 2025-04-30

## Fixed
Expand Down
15 changes: 12 additions & 3 deletions src/routes/(auth)/login/google/callback/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,25 @@ export const actions = {

try {
const response = await registerWithGoogle(form.data, cookies);
if (response.status === 400) {
const message: string = response.error.detail;
if (message.toLowerCase().includes("username")) {
form.errors.username = [message];
} else if (message.toLowerCase().includes("email")) {
form.errors.email = [message];
}
return fail(400, { form, message });
}
Comment on lines +50 to +58
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message parsing using toLowerCase().includes() is fragile and could fail if the error message format changes. Consider using more specific error codes or structured error responses from the registerWithGoogle function instead of string matching.

Copilot uses AI. Check for mistakes.
if (response.status >= 400) {
return fail(response.status, { form, error: response.error.detail });
return fail(response.status, { form, message: response.error.detail });
}
redirect(302, "/");
} catch (e: unknown) {
if (isRedirect(e)) throw e;
if (isHttpError(e)) {
return fail(e.status, { form, error: "Something went wrong in the server" });
return fail(e.status, { form, message: "Something went wrong in the server" });
}
return fail(500, { form, error: "An unexpected error occurred" });
return fail(500, { form, message: "An unexpected error occurred" });
}
}
};
94 changes: 49 additions & 45 deletions src/routes/(auth)/login/google/callback/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { PageProps } from "./$types";

import { type Infer, superForm } from "sveltekit-superforms";
import { type RegisterWithGoogleData, RegisterWithGoogleSchema } from "$models/auth";
import { RegisterWithGoogleSchema } from "$models/auth";

import * as Card from "$components/ui/card";
import { Button } from "$components/ui/button";
Expand All @@ -15,22 +15,28 @@

import { announce } from "$lib/utils";
import { onMount } from "svelte";
import { fromStore } from "svelte/store";

let { data }: PageProps = $props();

let registerForm = $state<any>();
let isSubmitting = $state<boolean>(false);
let form = $state<any>();
let formData = $state<any>();
let submitting = $state<any>();
let enhance = $state<any>();

onMount(() => {
if (data.status === "success" && data.form) {
registerForm = superForm<Infer<typeof RegisterWithGoogleSchema>>(data.form, {
const registerForm = superForm<Infer<typeof RegisterWithGoogleSchema>>(data.form, {
onResult: async ({ result }) => {
if (result.type === "redirect") {
announce(result, "Account created successfully");
}
}
});
form = registerForm;
const { form: fd, submitting: sub, enhance: enh } = registerForm;
formData = fd;
submitting = sub;
enhance = enh;
}
});
</script>
Expand All @@ -54,63 +60,61 @@
{/if}
</div>
</Card.Header>
<Card.Content class="text-center">
{#if registerForm}
{@const { enhance } = registerForm}
{@const registerFormData = fromStore<RegisterWithGoogleData>(
registerForm.form
).current}
<form method="POST" use:enhance onsubmit={() => (isSubmitting = true)}>
<Card.Content>
{#if form && formData}
<form method="POST" use:enhance>
<div class="space-y-4">
<Form.Field form={registerForm} name="username">
<Form.Field {form} name="username">
<Form.Control>
<Input
value={registerFormData.username}
name="username"
type="text"
placeholder="Username"
required
/>
{#snippet children({ props })}
<Input
{...props}
bind:value={$formData.username}
type="text"
placeholder="Username"
required
/>
{/snippet}
</Form.Control>
<Form.FieldErrors />
</Form.Field>

<Form.Field form={registerForm} name="display_name">
<Form.Field {form} name="display_name">
<Form.Control>
<Input
value={registerFormData.display_name}
name="display_name"
type="text"
placeholder="Display Name"
required
/>
{#snippet children({ props })}
<Input
{...props}
bind:value={$formData.display_name}
type="text"
placeholder="Display Name"
required
/>
{/snippet}
</Form.Control>
<Form.FieldErrors />
</Form.Field>

<Form.Field form={registerForm} name="email">
<Form.Field {form} name="email">
<Form.Control>
<Input
value={registerFormData.email}
name="email"
type="email"
placeholder="Email"
required
readonly
/>
{#snippet children({ props })}
<Input
{...props}
bind:value={$formData.email}
type="email"
placeholder="Email"
required
readonly
/>
{/snippet}
</Form.Control>
<Form.FieldErrors />
</Form.Field>

<input type="hidden" name="google_id" value={registerFormData.google_id} />
<input
type="hidden"
name="avatar_url"
value={registerFormData.avatar_url}
/>
<input type="hidden" name="google_id" bind:value={$formData.google_id} />
<input type="hidden" name="avatar_url" bind:value={$formData.avatar_url} />

<Button type="submit" disabled={isSubmitting}>
{#if isSubmitting}
<Button type="submit" disabled={submitting ? $submitting : false}>
{#if submitting && $submitting}
<Loader2 class="mr-2 h-4 w-4 animate-spin" />
Saving...
{:else}
Expand Down