diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index 6bc2bee..6f58851 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -15,6 +15,7 @@ import type { } from "convex/server"; import type * as CustomPassword from "../CustomPassword.js"; import type * as auth from "../auth.js"; +import type * as files from "../files.js"; import type * as http from "../http.js"; import type * as myFunctions from "../myFunctions.js"; @@ -29,6 +30,7 @@ import type * as myFunctions from "../myFunctions.js"; declare const fullApi: ApiFromModules<{ CustomPassword: typeof CustomPassword; auth: typeof auth; + files: typeof files; http: typeof http; myFunctions: typeof myFunctions; }>; diff --git a/convex/auth.ts b/convex/auth.ts index 5e91884..10dc097 100644 --- a/convex/auth.ts +++ b/convex/auth.ts @@ -1,5 +1,6 @@ +import { ConvexError, v } from 'convex/values'; import { convexAuth, getAuthUserId } from '@convex-dev/auth/server'; -import { query } from './_generated/server'; +import { mutation, query } from './_generated/server'; import Password from './CustomPassword'; export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({ @@ -10,7 +11,7 @@ export const getUser = query(async (ctx) => { const userId = await getAuthUserId(ctx); if (!userId) return null; const user = await ctx.db.get(userId); - if (!user) return null; + if (!user) throw new ConvexError('User not found.'); return { id: user._id, email: user.email ?? null, @@ -18,3 +19,15 @@ export const getUser = query(async (ctx) => { image: user.image ?? null, }; }); + +export const updateUserImage = mutation({ + args: { + storageId: v.id('_storage') + }, + handler: async (ctx, {storageId}) => { + const userId = await getAuthUserId(ctx); + if (!userId) throw new ConvexError('Not authenticated.'); + await ctx.db.patch(userId, { image: storageId }); + return { success: true }; + }, +}); diff --git a/convex/files.ts b/convex/files.ts new file mode 100644 index 0000000..bb76e28 --- /dev/null +++ b/convex/files.ts @@ -0,0 +1,13 @@ +import { mutation, query } from "./_generated/server"; +import { v } from "convex/values"; + +export const generateUploadUrl = mutation(async (ctx) => { + return await ctx.storage.generateUploadUrl(); +}); + +export const getImageUrl = query({ + args: { storageId: v.id("_storage") }, + handler: async (ctx, { storageId }) => { + return await ctx.storage.getUrl(storageId); + }, +}); diff --git a/src/app/(auth)/profile/page.tsx b/src/app/(auth)/profile/page.tsx index 958621c..647fb43 100644 --- a/src/app/(auth)/profile/page.tsx +++ b/src/app/(auth)/profile/page.tsx @@ -1,4 +1,16 @@ -const Profile = () => { - return
; +'use server'; +import { preloadQuery } from "convex/nextjs"; +import { api } from "~/convex/_generated/api"; +import { AvatarUpload, ProfileHeader } from "@/components/layout/profile"; +import { Card } from "@/components/ui"; + +const Profile = async () => { + const preloadedUser = await preloadQuery(api.auth.getUser); + return ( +