import { query, mutation } from "./_generated/server"; import { v } from "convex/values"; import * as Users from "./model/users"; import * as Categories from "./model/categories"; export const list = query({ args: { parentId: v.optional(v.id("categories")), }, handler: async (ctx, args) => { let items; console.log("args in list", args); if (args.parentId !== undefined) { items = await ctx.db .query("categories") .withIndex("by_parent", (q) => q.eq("parentId", args.parentId!)) .collect(); } else { items = await ctx.db.query("categories").collect(); } items.sort((a, b) => a.name.localeCompare(b.name)); return items; }, }); export const getById = query({ args: { id: v.id("categories") }, handler: async (ctx, { id }) => { return await ctx.db.get(id); }, }); export const getBySlug = query({ args: { slug: v.string() }, handler: async (ctx, { slug }) => { return await ctx.db .query("categories") .withIndex("by_slug", (q) => q.eq("slug", slug)) .unique(); }, }); export const getByPath = query({ args: { categorySlug: v.string(), subCategorySlug: v.string(), }, handler: async (ctx, { categorySlug, subCategorySlug }) => { const parent = await ctx.db .query("categories") .withIndex("by_slug", (q) => q.eq("slug", categorySlug)) .unique(); if (!parent) return null; return await ctx.db .query("categories") .withIndex("by_parent_slug", (q) => q.eq("parentId", parent._id).eq("slug", subCategorySlug), ) .unique(); }, }); export const listByTopCategory = query({ args: { slug: v.string() }, handler: async (ctx, { slug }) => { const items = await ctx.db .query("categories") .withIndex("by_top_category_slug", (q) => q.eq("topCategorySlug", slug), ) .collect(); items.sort((a, b) => a.name.localeCompare(b.name)); return items; }, }); export const create = mutation({ args: { name: v.string(), slug: v.string(), description: v.optional(v.string()), parentId: v.optional(v.id("categories")), topCategorySlug: v.optional(v.string()), seoTitle: v.optional(v.string()), seoDescription: v.optional(v.string()), }, handler: async (ctx, args) => { await Users.requireAdmin(ctx); const existing = await ctx.db .query("categories") .withIndex("by_slug", (q) => q.eq("slug", args.slug)) .unique(); if (existing) throw new Error("Category slug already exists"); return await ctx.db.insert("categories", args); }, }); export const update = mutation({ args: { id: v.id("categories"), name: v.optional(v.string()), slug: v.optional(v.string()), description: v.optional(v.string()), topCategorySlug: v.optional(v.string()), seoTitle: v.optional(v.string()), seoDescription: v.optional(v.string()), }, handler: async (ctx, { id, ...updates }) => { await Users.requireAdmin(ctx); await Categories.getCategoryOrThrow(ctx, id); const fields: Record = {}; for (const [key, value] of Object.entries(updates)) { if (value !== undefined) fields[key] = value; } if (Object.keys(fields).length > 0) { await ctx.db.patch(id, fields); } return id; }, });