feat(auth): add loading state to login modal for improved user experience

- Enhanced the LoginModalContent component to include a loading state while fetching authentication providers.
- Implemented skeleton loaders to prevent content layout shifts during loading.
- Improved user feedback by displaying loading indicators before the authentication options are available.

These changes enhance the overall user experience during the login process.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-05-16 00:01:34 +08:00
parent e69d120bd9
commit 1ace59308b
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
1 changed files with 30 additions and 20 deletions

View File

@ -29,7 +29,7 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
const { canClose = true, runtime } = props
const { t } = useTranslation()
const { data: authProviders } = useAuthProviders()
const { data: authProviders, isLoading } = useAuthProviders()
const isMobile = useMobile()
@ -79,25 +79,35 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
)
) : (
<div className="mb-3 flex flex-col items-center justify-center gap-4">
{providers.map(([key, provider]) => (
<MotionButtonBase
key={key}
onClick={() => {
if (key === "credential") {
setIsEmail(true)
} else {
loginHandler(key, "app")
}
}}
className="center hover:bg-material-medium relative w-full gap-2 rounded-xl border py-3 pl-5 font-semibold duration-200"
>
<img
className="absolute left-9 h-5 dark:brightness-[0.85] dark:hue-rotate-180 dark:invert"
src={provider.icon64}
/>
<span>{t("login.continueWith", { provider: provider.name })}</span>
</MotionButtonBase>
))}
{isLoading
? // Skeleton loaders to prevent CLS
Array.from({ length: 4 })
.fill(0)
.map((_, index) => (
<div
key={index}
className="bg-material-ultra-thick border-material-medium relative h-12 w-full animate-pulse rounded-xl border"
/>
))
: providers.map(([key, provider]) => (
<MotionButtonBase
key={key}
onClick={() => {
if (key === "credential") {
setIsEmail(true)
} else {
loginHandler(key, "app")
}
}}
className="center hover:bg-material-medium relative w-full gap-2 rounded-xl border py-3 pl-5 font-semibold duration-200"
>
<img
className="absolute left-9 h-5 dark:brightness-[0.85] dark:hue-rotate-180 dark:invert"
src={provider.icon64}
/>
<span>{t("login.continueWith", { provider: provider.name })}</span>
</MotionButtonBase>
))}
</div>
)}
<Divider className="mb-5 mt-6" />