refactor: implement conditional rendering for password update when user has account with credential provider

- Replaced `UpdatePasswordCard` with `ConditionalUpdatePasswordCard` in `SettingsAccountPage` to ensure the password update option is only available for users with a credential provider.
- Added `ConditionalUpdatePasswordCard` component to handle the logic for checking user credentials and rendering the password update form accordingly.
- Updated documentation in `UpdatePasswordCard` to clarify its usage and the need for credential providers.
This commit is contained in:
javayhu 2025-03-16 23:00:25 +08:00
parent 8abb393c3e
commit 4f8b6d56c9
3 changed files with 63 additions and 6 deletions

View File

@ -1,7 +1,7 @@
import { DashboardHeader } from '@/components/dashboard/dashboard-header';
import { UpdateAvatarCard } from '@/components/settings/account/update-avatar-card';
import { UpdateNameCard } from '@/components/settings/account/update-name-card';
import { UpdatePasswordCard } from '@/components/settings/account/update-password-card';
import { ConditionalUpdatePasswordCard } from '@/components/settings/account/conditional-update-password-card';
import { DeleteAccountCard } from '@/components/settings/account/delete-account-card';
import { useTranslations } from 'next-intl';
@ -19,6 +19,8 @@ export default function SettingsAccountPage() {
},
];
return (
<>
<DashboardHeader breadcrumbs={breadcrumbs} />
@ -28,7 +30,7 @@ export default function SettingsAccountPage() {
<div className="space-y-6">
<UpdateAvatarCard />
<UpdateNameCard />
<UpdatePasswordCard />
<ConditionalUpdatePasswordCard />
<DeleteAccountCard />
</div>
</div>

View File

@ -0,0 +1,52 @@
'use client';
import { UpdatePasswordCard } from '@/components/settings/account/update-password-card';
import { authClient } from '@/lib/auth-client';
import { useEffect, useState } from 'react';
/**
* Conditionally renders the UpdatePasswordCard component
* only if the user has a credential provider (email/password login)
*/
export function ConditionalUpdatePasswordCard() {
const { data: session } = authClient.useSession();
const [hasCredentialProvider, setHasCredentialProvider] = useState(false);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const checkCredentialProvider = async () => {
if (!session?.user) {
setIsLoading(false);
return;
}
try {
// Get the user's linked accounts
const accounts = await authClient.listAccounts();
// console.log('accounts', accounts);
// Check if the response is successful and contains accounts data
if ('data' in accounts && Array.isArray(accounts.data)) {
// Check if any account has a credential provider (provider === 'credentials')
const hasCredentials = accounts.data.some(
(account) => account.provider === 'credential'
);
setHasCredentialProvider(hasCredentials);
}
} catch (error) {
console.error('Error checking credential provider:', error);
} finally {
setIsLoading(false);
}
};
checkCredentialProvider();
}, [session]);
// Don't render anything while loading or if user doesn't have credential provider
if (isLoading || !hasCredentialProvider) {
return null;
}
return <UpdatePasswordCard />;
}

View File

@ -30,9 +30,14 @@ import { toast } from 'sonner';
import { z } from 'zod';
/**
* update user password
* Update user password
*
* https://www.better-auth.com/docs/authentication/email-password#update-password
* This component allows users to update their password.
* NOTE: This should only be used for users with credential providers (email/password login).
* For conditional rendering based on provider type, use ConditionalUpdatePasswordCard instead.
*
* @see ConditionalUpdatePasswordCard
* @see https://www.better-auth.com/docs/authentication/email-password#update-password
*/
export function UpdatePasswordCard() {
const router = useLocaleRouter();
@ -68,8 +73,6 @@ export function UpdatePasswordCard() {
return null;
}
// TODO: if user account provider is not credential, we should not allow user to update password
// Handle form submission
const onSubmit = async (values: z.infer<typeof formSchema>) => {
const { data, error } = await authClient.changePassword(