export const get = query({ args: { includeEnded: v.optional(v.boolean()), category: v.optional(v.string()), sort: v.optional(v.string()), listingType: v.optional(v.string()), // NEW search: v.optional(v.string()), // Add search argument own: v.optional(v.id("users")), }, handler: async (ctx, args) => { let auctions: Doc<"auctions">[] = []; let q; // Not own: use existing query logic if (args.search) { q = ctx.db.query("auctions").withSearchIndex("search_title", (q) => { return q.search("lore", args.search as string); }); } else { q = ctx.db.query("auctions"); switch (args.sort) { case SortOptions.PRICE_LOW: q = q.withIndex("by_price").order("asc"); break; case SortOptions.PRICE_HIGH: q = q.withIndex("by_price").order("desc"); break; case SortOptions.NEWEST: q = q.withIndex("by_creation_time").order("desc"); break; case SortOptions.MOST_BIDS: q = q.withIndex("by_bidcount").order("desc"); break; case SortOptions.ENDING_SOON: default: q = q.withIndex("by_end").order("asc"); break; } } // Filter by category if provided and not "all" if (args.category && args.category !== "all") { q = q.filter((p) => p.eq(p.field("category"), args.category)); } // Filter by listing type if (args.listingType === "bin") { q = q.filter((row) => row.and( row.neq(row.field("buyNowPrice"), undefined), row.neq(row.field("buyNowPrice"), null), ), ); } else if (args.listingType === "auctions") { q = q.filter((row) => row.not( row.or( row.eq(row.field("currentBid"), undefined), row.eq(row.field("currentBid"), null), ), ), ); } // Filter out ended auctions if includeEnded is false const now = Date.now(); if (args.includeEnded === false) { q = q.filter((row) => row.gt(row.field("end"), now)); q = q.filter((row) => row.gt(row.field("buyNowPrice"), row.field("currentBid")), ); } auctions = await q.collect(); if (args.search) { switch (args.sort) { case SortOptions.PRICE_LOW: auctions.sort((a, b) => { const aBid = typeof a.currentBid === "number" && !isNaN(a.currentBid) ? a.currentBid : typeof a.buyNowPrice === "number" && !isNaN(a.buyNowPrice) ? a.buyNowPrice : Infinity; const bBid = typeof b.currentBid === "number" && !isNaN(b.currentBid) ? b.currentBid : typeof b.buyNowPrice === "number" && !isNaN(b.buyNowPrice) ? b.buyNowPrice : Infinity; return aBid - bBid; }); break; case SortOptions.PRICE_HIGH: auctions.sort((a, b) => { const aBid = typeof a.currentBid === "number" && !isNaN(a.currentBid) ? a.currentBid : typeof a.buyNowPrice === "number" && !isNaN(a.buyNowPrice) ? a.buyNowPrice : -Infinity; const bBid = typeof b.currentBid === "number" && !isNaN(b.currentBid) ? b.currentBid : typeof b.buyNowPrice === "number" && !isNaN(b.buyNowPrice) ? b.buyNowPrice : -Infinity; return bBid - aBid; }); break; case SortOptions.NEWEST: auctions.sort((a, b) => b._creationTime - a._creationTime); break; case SortOptions.MOST_BIDS: auctions.sort((a, b) => b.bidcount - a.bidcount); break; case SortOptions.ENDING_SOON: default: auctions.sort((a, b) => a.end - b.end); break; } } return auctions; }, });