Bring back ability to find out provider for profile page

This commit is contained in:
2026-01-13 15:09:10 -06:00
parent 8f71a22d2b
commit 09b191eb64
5 changed files with 34 additions and 17 deletions

View File

@@ -14,6 +14,7 @@ import { Card, Separator } from '@gib/ui';
const Profile = async () => { const Profile = async () => {
const preloadedUser = await preloadQuery(api.auth.getUser, {}); const preloadedUser = await preloadQuery(api.auth.getUser, {});
const preloadedUserProvider = await preloadQuery(api.auth.getUserProvider, {});
return ( return (
<main className="container mx-auto px-4 py-12 md:py-16"> <main className="container mx-auto px-4 py-12 md:py-16">
<div className="mx-auto max-w-3xl"> <div className="mx-auto max-w-3xl">
@@ -32,9 +33,8 @@ const Profile = async () => {
<ProfileHeader preloadedUser={preloadedUser} /> <ProfileHeader preloadedUser={preloadedUser} />
<AvatarUpload preloadedUser={preloadedUser} /> <AvatarUpload preloadedUser={preloadedUser} />
<Separator className="my-6" /> <Separator className="my-6" />
<UserInfoForm preloadedUser={preloadedUser} /> <UserInfoForm preloadedUser={preloadedUser} preloadedProvider={preloadedUserProvider} />
<Separator className="my-6" /> <ResetPasswordForm preloadedProvider={preloadedUserProvider} />
<ResetPasswordForm preloadedUser={preloadedUser} />
<Separator className="my-6" /> <Separator className="my-6" />
<SignOutForm /> <SignOutForm />
</Card> </Card>

View File

@@ -14,7 +14,9 @@ const ProfileHeader = ({ preloadedUser }: ProfileCardProps) => {
const user = usePreloadedQuery(preloadedUser); const user = usePreloadedQuery(preloadedUser);
return ( return (
<CardHeader> <CardHeader>
<CardTitle className="text-xl">Account Settings</CardTitle> <CardTitle className="text-xl">
Account Settings
</CardTitle>
<CardDescription> <CardDescription>
Update your profile information and manage your account preferences Update your profile information and manage your account preferences
</CardDescription> </CardDescription>

View File

@@ -66,12 +66,12 @@ const formSchema = z
path: ['confirmPassword'], path: ['confirmPassword'],
}); });
type ResetFormProps = { interface ResetFormProps {
preloadedUser: Preloaded<typeof api.auth.getUser>; preloadedProvider: Preloaded<typeof api.auth.getUserProvider>;
}; };
export const ResetPasswordForm = ({ preloadedUser }: ResetFormProps) => { export const ResetPasswordForm = ({ preloadedProvider }: ResetFormProps) => {
const user = usePreloadedQuery(preloadedUser); const userProvider = usePreloadedQuery(preloadedProvider);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const changePassword = useAction(api.auth.updateUserPassword); const changePassword = useAction(api.auth.updateUserPassword);
@@ -104,12 +104,13 @@ export const ResetPasswordForm = ({ preloadedUser }: ResetFormProps) => {
} }
}; };
// Only show password reset for email/password auth users // Only show password reset for email/password auth users
if (!user?.email) { if (userProvider !== 'email') {
return null; return null;
} }
return ( return (
<> <>
<Separator />
<CardHeader> <CardHeader>
<CardTitle>Change Password</CardTitle> <CardTitle>Change Password</CardTitle>
<CardDescription> <CardDescription>

View File

@@ -40,12 +40,14 @@ const formSchema = z.object({
}), }),
}); });
type UserInfoFormProps = { interface UserInfoFormProps {
preloadedUser: Preloaded<typeof api.auth.getUser>; preloadedUser: Preloaded<typeof api.auth.getUser>;
preloadedProvider: Preloaded<typeof api.auth.getUserProvider>;
}; };
export const UserInfoForm = ({ preloadedUser }: UserInfoFormProps) => { export const UserInfoForm = ({ preloadedUser, preloadedProvider }: UserInfoFormProps) => {
const user = usePreloadedQuery(preloadedUser); const user = usePreloadedQuery(preloadedUser);
const userProvider = usePreloadedQuery(preloadedProvider);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const updateUser = useMutation(api.auth.updateUser); const updateUser = useMutation(api.auth.updateUser);
@@ -132,7 +134,7 @@ export const UserInfoForm = ({ preloadedUser }: UserInfoFormProps) => {
{...field} {...field}
type="email" type="email"
placeholder="john@example.com" placeholder="john@example.com"
disabled={!user?.email} disabled={userProvider !== 'email'}
/> />
</FormControl> </FormControl>
<FormDescription> <FormDescription>

View File

@@ -25,13 +25,25 @@ const getUserById = async (
if (!user) throw new ConvexError('User not found.'); if (!user) throw new ConvexError('User not found.');
return user; return user;
}; };
const isSignedIn = async (ctx: QueryCtx): Promise<Doc<'users'> | null> => { const getAuthAccountById = async (ctx: QueryCtx, userId: Id<'users'>) => {
const userId = await getAuthUserId(ctx);
if (!userId) return null;
const user = await ctx.db.get(userId); const user = await ctx.db.get(userId);
if (!user) return null; if (!user) throw new ConvexError('User not found.');
return user; const authAccount = await ctx.db
.query('authAccounts')
.withIndex('userIdAndProvider', (q) => q.eq('userId', userId))
.first();
if (!authAccount) throw new ConvexError('Auth account not found');
return authAccount;
}; };
export const getUserProvider = query({
args: { userId: v.optional(v.id('users')) },
handler: async (ctx, args) => {
const userId = args.userId ?? (await getAuthUserId(ctx));
if (!userId) return null;
const authAccount = await getAuthAccountById(ctx, userId);
return authAccount.provider;
},
});
export const getUser = query({ export const getUser = query({
args: { userId: v.optional(v.id('users')) }, args: { userId: v.optional(v.id('users')) },