Improve auth ux
This commit is contained in:
parent
760f63f570
commit
da86fc601a
@ -4,12 +4,14 @@ import FieldSetWithStatus from '@/components/FieldSetWithStatus';
|
||||
import InfoBlock from '@/components/InfoBlock';
|
||||
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { getCurrentUser, signInAction } from './actions';
|
||||
import { getAuthAction, signInAction } from './actions';
|
||||
import { useFormState } from 'react-dom';
|
||||
import ErrorNote from '@/components/ErrorNote';
|
||||
import { KEY_CALLBACK_URL, KEY_CREDENTIALS_SIGN_IN_ERROR } from '.';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useAppState } from '@/state/AppState';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { FiLock } from 'react-icons/fi';
|
||||
|
||||
export default function SignInForm() {
|
||||
const params = useSearchParams();
|
||||
@ -28,7 +30,8 @@ export default function SignInForm() {
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
// Capture user email before unmounting
|
||||
getCurrentUser().then(user => setUserEmail?.(user?.email ?? undefined));
|
||||
getAuthAction().then(auth =>
|
||||
setUserEmail?.(auth?.user?.email ?? undefined));
|
||||
};
|
||||
}, [setUserEmail]);
|
||||
|
||||
@ -37,14 +40,29 @@ export default function SignInForm() {
|
||||
password.length > 0;
|
||||
|
||||
return (
|
||||
<InfoBlock>
|
||||
<form action={action}>
|
||||
<div className="space-y-8">
|
||||
<InfoBlock className={clsx(
|
||||
'w-[calc(100vw-1.5rem)] sm:w-[min(360px,90vw)]',
|
||||
'px-6 py-5',
|
||||
)}>
|
||||
<h1 className={clsx(
|
||||
'flex gap-3 items-center justify-center',
|
||||
'self-start text-2xl mb-3.5',
|
||||
)}>
|
||||
<FiLock className="text-main translate-y-[0.5px]" />
|
||||
<span className="text-main">
|
||||
Sign in
|
||||
</span>
|
||||
</h1>
|
||||
<form
|
||||
action={action}
|
||||
className="w-full"
|
||||
>
|
||||
<div className="space-y-6 w-full -translate-y-0.5">
|
||||
{response === KEY_CREDENTIALS_SIGN_IN_ERROR &&
|
||||
<ErrorNote>
|
||||
Invalid email/password
|
||||
</ErrorNote>}
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-4 w-full">
|
||||
<FieldSetWithStatus
|
||||
id="email"
|
||||
inputRef={emailRef}
|
||||
|
||||
@ -39,4 +39,4 @@ export const signInAction = async (
|
||||
export const signOutAndRedirectAction = async () =>
|
||||
signOut({ redirectTo: PATH_ROOT });
|
||||
|
||||
export const getCurrentUser = async () => (await auth())?.user;
|
||||
export const getAuthAction = () => auth();
|
||||
|
||||
@ -140,7 +140,11 @@ export default function FieldSetWithStatus({
|
||||
autoCapitalize={!capitalize ? 'off' : undefined}
|
||||
readOnly={readOnly || pending || loading}
|
||||
className={clsx(
|
||||
type === 'text' && 'w-full',
|
||||
(
|
||||
type === 'text' ||
|
||||
type === 'email' ||
|
||||
type === 'password'
|
||||
) && 'w-full',
|
||||
Boolean(error) && 'error',
|
||||
)}
|
||||
/>}
|
||||
|
||||
@ -26,9 +26,12 @@ export default function LoaderButton(props: {
|
||||
type={type}
|
||||
className={clsx(
|
||||
className,
|
||||
styleAsLink
|
||||
? 'link h-4 hover:text-dim active:text-medium'
|
||||
: 'h-9',
|
||||
...(styleAsLink
|
||||
? [
|
||||
'link h-4 hover:text-dim active:text-medium',
|
||||
'disabled:!bg-transparent',
|
||||
]
|
||||
: ['h-9']),
|
||||
'inline-flex items-center gap-2 self-start',
|
||||
)}
|
||||
disabled={isLoading || disabled}
|
||||
|
||||
@ -41,7 +41,7 @@ export default function Footer() {
|
||||
{isPathAdmin(pathname)
|
||||
? <>
|
||||
{userEmail === undefined &&
|
||||
<Spinner />}
|
||||
<Spinner size={14} className="translate-y-[2px]" />}
|
||||
{userEmail && <>
|
||||
<div className={clsx(
|
||||
'truncate max-w-full',
|
||||
|
||||
@ -4,7 +4,7 @@ import { useState, useEffect, ReactNode, useCallback } from 'react';
|
||||
import { AppStateContext } from './AppState';
|
||||
import { AnimationConfig } from '@/components/AnimateItems';
|
||||
import usePathnames from '@/utility/usePathnames';
|
||||
import { getCurrentUser } from '@/auth/actions';
|
||||
import { getAuthAction } from '@/auth/actions';
|
||||
import useSWR from 'swr';
|
||||
|
||||
export default function AppStateProvider({
|
||||
@ -34,8 +34,8 @@ export default function AppStateProvider({
|
||||
|
||||
const invalidateSwr = useCallback(() => setSwrTimestamp(Date.now()), []);
|
||||
|
||||
const { data } = useSWR('getCurrentUser', getCurrentUser);
|
||||
useEffect(() => setUserEmail(data?.email ?? undefined), [data]);
|
||||
const { data } = useSWR('getAuth', getAuthAction);
|
||||
useEffect(() => setUserEmail(data?.user?.email ?? undefined), [data]);
|
||||
|
||||
const registerAdminUpdate = useCallback(() =>
|
||||
setAdminUpdateTimes(updates => [...updates, new Date()])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user