Files
classroomio/apps/dashboard/src/routes/reset/+page.svelte
T
Rotimi Best a3924100dd feat: migrate auth from supabase to better auth (#596)
* feat: add README for @cio/db package and remove existingAccounts.json

* load session, load profile and organization, add create profile hook

* chore: cache session request

The trick was passing all the cookies to the backend. Previously I was only passing the better-auth.session_token and not better-auth.session_data. Read about the difference here https://www.better-auth.com/docs/concepts/cookies#custom-cookies

* feat: login, logout, onboarding, verify email, reset password.

* feat: complete change email and email verification

* feat: standardise how we make rpc calls and create org endpoints

* fix ui errors

* fix: handle potential undefined customerId and standardize avatar URL property

* refactor: standardize custom domain handling and update telegram chat ID references

* chore: add tailwind prefix to @cio/ui

this fixed the media query issues because  @cio/ui classes were overriding this dashboard tailwind build

* chore: clean up org sidebar

* chore: persist mode state

* feat: implement order breadcrumbs

* chore: upgrade to better auth 1.4

* chore: address common auth flow bugs and setup app for others to setup locally.
2025-11-24 01:00:50 +01:00

97 lines
2.8 KiB
Svelte

<script lang="ts">
import { onMount, untrack } from 'svelte';
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { page } from '$app/state';
import TextField from '$lib/components/Form/TextField.svelte';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import { getConfirmPasswordError } from '$lib/utils/functions/validator';
import AuthUI from '$lib/components/AuthUI/index.svelte';
import { resetApi } from '$lib/features/auth/api/reset.svelte';
import type { TResetPasswordForm } from '$lib/features/auth/utils/types';
import { snackbar } from '$lib/components/Snackbar/store';
let fields: TResetPasswordForm = $state({
password: '',
confirmPassword: '',
token: ''
});
const isSubmitDisabled = $derived!!(
fields.password && fields.confirmPassword && fields.password !== fields.confirmPassword
);
const token = $derived(new URLSearchParams(page.url.search).get('token'));
onMount(() => {
if (token) return;
snackbar.error('Invalid Token');
setTimeout(() => {
goto(resolve('/login', {}));
}, 2000);
});
function setConfirmPasswordError(fields: TResetPasswordForm) {
untrack(() => {
const errors = { ...resetApi.errors };
errors.confirmPassword = getConfirmPasswordError(fields) ?? '';
resetApi.setError(errors);
});
}
$effect(() => {
setConfirmPasswordError(fields);
});
</script>
<svelte:head>
<title>Reset Password - ClassroomIO</title>
</svelte:head>
<AuthUI
isLogin={false}
handleSubmit={() => resetApi.submit({ ...fields, token: token ?? '' })}
showOnlyContent={true}
isLoading={resetApi.isLoading}
showLogo={true}
>
<div class="mt-4 w-full">
<h3 class="my-3 text-xl font-semibold dark:text-white">New Password</h3>
<p class="mb-6 text-sm dark:text-white">Enter your new password details</p>
<TextField
label="Your Password"
bind:value={fields.password}
type="password"
placeholder="************"
className="mb-6"
inputClassName="w-full"
isDisabled={resetApi.isLoading}
errorMessage={resetApi.errors.password}
helperMessage="Password must be more than 8 characters"
isRequired
/>
<TextField
label="Confirm Password"
bind:value={fields.confirmPassword}
type="password"
placeholder="************"
className="mb-6"
inputClassName="w-full"
isDisabled={resetApi.isLoading}
errorMessage={resetApi.errors.confirmPassword}
isRequired
/>
</div>
<div class="my-4 flex w-full items-center justify-end">
<PrimaryButton
label="Reset Password"
type="submit"
className="sm:w-full w-full"
isDisabled={isSubmitDisabled || resetApi.isLoading}
isLoading={resetApi.isLoading}
/>
</div>
</AuthUI>