fix chatbox

This commit is contained in:
2026-08-06 15:43:46 +05:30
parent e5f8144fb3
commit b23ea760c8
15 changed files with 475 additions and 97 deletions

View File

@@ -4,9 +4,20 @@ import {useCallback, useState} from 'react';
import {useRouter, useSearchParams} from 'next/navigation';
import {useToast} from '@astryxdesign/core/Toast';
import {useSession} from '@/features/auth/providers/SessionProvider';
import {
LOGIN_ERROR_PARAM,
loginErrorFromCode,
} from '@/features/auth/services/loginErrorCodes';
import {resolveRedirectTarget} from '@/features/auth/services/redirectTarget';
import type {LoginError} from '@/features/auth/types/auth';
/**
* Where credentials are POSTed. Exported because the form element itself needs
* it for `action` — the no-JavaScript path submits straight here, bypassing
* this hook, authService and the repository entirely.
*/
export const LOGIN_ENDPOINT = '/api/auth/login';
/**
* Every behaviour of the sign-in form, with no markup attached.
*
@@ -39,12 +50,30 @@ export function useLoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [rememberMe, setRememberMe] = useState(false);
const [errors, setErrors] = useState<LoginFormState['errors']>({});
/**
* Seeded from `?error=` so a sign-in that failed on the no-JavaScript path
* still shows its message once the page hydrates. The code is looked up in a
* fixed table — an unrecognised one yields nothing, so the URL cannot be
* used to write arbitrary text onto the sign-in screen.
*
* Seeding in useState rather than an effect keeps the message present in the
* first render, server and client alike, so there is no flash and no
* hydration mismatch to patch up.
*/
const [errors, setErrors] = useState<LoginFormState['errors']>(() => {
const seeded = loginErrorFromCode(searchParams.get(LOGIN_ERROR_PARAM));
return seeded ? {[seeded.field]: seeded.message} : {};
});
const [isSubmitting, setIsSubmitting] = useState(false);
// Raw, for the hidden field the native form path posts back. Unvalidated
// here on purpose: the server validates it through resolveRedirectTarget,
// which is the only side that can be trusted to.
const next = searchParams.get('next');
// Shared with GuestGuard, which redirects on the same event — see
// resolveRedirectTarget for why that matters and how `next` is validated.
const destination = resolveRedirectTarget(searchParams.get('next'));
const destination = resolveRedirectTarget(next);
const submit = useCallback(
async (event: React.FormEvent) => {
@@ -106,6 +135,7 @@ export function useLoginForm() {
rememberMe,
errors,
isSubmitting,
next,
setEmail: updateEmail,
setPassword: updatePassword,
setRememberMe,