export const getPaginatedTransactions = query({
args: {
paginationOpts: paginationOptsValidator,
categoryFilter: v.array(v.string()),
typeFilter: v.array(v.string()),
sortKey: v.string(),
sortOrder: v.string(),
searchTerm: v.optional(v.string())
},
handler: async (ctx, args) => {
const userId = (await ctx.auth.getUserIdentity())?.subject;
const baseQuery = ctx.db.query("transactions").filter(q => q.eq(q.field("userId"), userId));
const searchedOrSorted = args.searchTerm
? baseQuery.withSearchIndex("search_title", q =>
q.search("title", args.searchTerm!)
)
: baseQuery
.withIndex(args.sortKey as "by_date" | "by_category" | "by_type")
.order(args.sortOrder as "asc" | "desc");
let query = searchedOrSorted;
if (args.categoryFilter.length > 0 || args.typeFilter.length > 0) {
query = query.filter(q =>
q.and(
args.categoryFilter.length > 0
? q.or(...args.categoryFilter.map(category => q.eq(q.field("category"), category)))
: q.eq(1, 1),
args.typeFilter.length > 0
? q.or(...args.typeFilter.map(type => q.eq(q.field("type"), type)))
: q.eq(1, 1)
)
);
}
const paginatedTransactions = await query.paginate(args.paginationOpts);
console.log("Number of transactions retrieved:", paginatedTransactions.page.length);
return paginatedTransactions;
},
});
here is the schema
transactions: defineTable({
userId: v.optional(v.string()),
amount: v.float64(),
category: v.string(),
date: v.string(),
title: v.string(),
type: v.string(),
imageUrl: v.optional(v.string()),
})
.index("by_user_and_date", ["userId", "date"])
.index("by_date", ["date"])
.index("by_category", ["category"])
.index("by_type", ["type"])
.index("by_amount", ["amount"])
.searchIndex("search_title", { searchField: "title" }),