feat: display user's posts on profile page

This commit is contained in:
Stevan Freeborn
2023-09-11 00:40:14 -05:00
parent 8b350c9809
commit 4b74f47e75
18 changed files with 397 additions and 67 deletions
+13 -1
View File
@@ -1,5 +1,6 @@
import { paginationOptsValidator } from 'convex/server';
import { v } from 'convex/values';
import { mutation } from './_generated/server';
import { mutation, query } from './_generated/server';
import { userQuery } from './users';
export const createPost = mutation({
@@ -31,3 +32,14 @@ export const createPost = mutation({
});
},
});
export const getUsersPostById = query({
args: { userId: v.id('users'), paginationOpts: paginationOptsValidator },
handler: async (ctx, args) => {
return await ctx.db
.query('posts')
.withIndex('by_user_id', q => q.eq('userId', args.userId))
.order('desc')
.paginate(args.paginationOpts);
},
});
+31 -1
View File
@@ -3,7 +3,37 @@ import { v } from 'convex/values';
export default defineSchema(
{
users: defineTable({
clerkUser: v.any(),
clerkUser: v.object({
id: v.string(),
object: v.string(),
username: v.union(v.string(), v.null()),
first_name: v.string(),
last_name: v.string(),
gender: v.string(),
birthday: v.string(),
profile_image_url: v.string(),
image_url: v.string(),
has_image: v.boolean(),
primary_email_address_id: v.boolean(),
primary_phone_number_id: v.union(v.string(), v.null()),
primary_web3_wallet_id: v.union(v.string(), v.null()),
password_enabled: v.boolean(),
totp_enabled: v.boolean(),
backup_code_enabled: v.boolean(),
two_factor_enabled: v.boolean(),
banned: v.boolean(),
email_addresses: v.any(),
phone_numbers: v.any(),
web3_wallets: v.any(),
external_accounts: v.any(),
external_id: v.union(v.string(), v.null()),
last_sign_in_at: v.union(v.number(), v.null()),
public_metadata: v.any(),
private_metadata: v.any(),
unsafe_metadata: v.any(),
created_at: v.number(),
updated_at: v.number(),
}),
}).index('by_clerk_id', ['clerkUser.id']),
posts: defineTable({
parentPostId: v.optional(v.id('posts')),
+34 -14
View File
@@ -1,7 +1,37 @@
import { UserJSON } from '@clerk/nextjs/dist/types/server';
import { v } from 'convex/values';
import { Doc } from './_generated/dataModel';
import { QueryCtx, internalMutation, internalQuery } from './_generated/server';
import {
QueryCtx,
internalMutation,
internalQuery,
query,
} from './_generated/server';
export async function userQuery(ctx: QueryCtx, clerkUserId: string) {
return await ctx.db
.query('users')
.withIndex('by_clerk_id', q => q.eq('clerkUser.id', clerkUserId))
.unique();
}
export const getUserByClerkId = query({
args: { clerkUserId: v.string() },
async handler(ctx, args) {
return await userQuery(ctx, args.clerkUserId);
},
});
export const getUserById = query({
args: { id: v.id('users') },
async handler(ctx, args) {
const user = await ctx.db.get(args.id);
if (user === null) {
return 'USER_NOT_FOUND';
}
return user;
},
});
export const getUser = internalQuery({
args: { subject: v.string() },
@@ -10,19 +40,9 @@ export const getUser = internalQuery({
},
});
export async function userQuery(
ctx: QueryCtx,
clerkUserId: string
): Promise<(Omit<Doc<'users'>, 'clerkUser'> & { clerkUser: UserJSON }) | null> {
return await ctx.db
.query('users')
.withIndex('by_clerk_id', q => q.eq('clerkUser.id', clerkUserId))
.unique();
}
export const updateOrCreateUser = internalMutation({
args: { clerkUser: v.any() },
async handler(ctx, { clerkUser }: { clerkUser: UserJSON }) {
async handler(ctx, { clerkUser }) {
const userRecord = await userQuery(ctx, clerkUser.id);
if (userRecord === null) {