mojmajstor/convex/ads.ts
echo ce7e400720 feat: Phase 2 - home screen, categories, explore, AdCard
- Add seedCategories mutation (idempotent) and getBySlug query
- Add ad queries: list, getByCategory, getById, search, getByHandyman
- Home screen: search bar, CategoryGrid, recent ads list with real-time
  Convex queries and search-by-keyword
- Explore screen: category filter via search param, filtered ad list,
  full category grid when unfiltered
- AdCard component: title, category badge, location, rating stars,
  price range, navigation to ad detail
- CategoryGrid component: 3-column emoji grid linking to filtered explore
- Add CATEGORY_EMOJI map and getCategoryName() helper in constants

All UI text in Macedonian. TypeScript clean, Convex functions deployed.
2026-05-29 18:24:01 +02:00

62 lines
1.5 KiB
TypeScript

import { query } from "./_generated/server";
import { v } from "convex/values";
export const list = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("ads").order("desc").collect();
},
});
export const getByCategory = query({
args: { category: v.string() },
handler: async (ctx, args) => {
return await ctx.db
.query("ads")
.withIndex("by_category", (q) => q.eq("category", args.category))
.order("desc")
.collect();
},
});
export const getById = query({
args: { id: v.id("ads") },
handler: async (ctx, args) => {
return await ctx.db.get(args.id);
},
});
export const search = query({
args: { query: v.string(), category: v.optional(v.string()) },
handler: async (ctx, args) => {
const searchLower = args.query.toLowerCase();
let ads;
if (args.category) {
ads = await ctx.db
.query("ads")
.withIndex("by_category", (q) => q.eq("category", args.category!))
.collect();
} else {
ads = await ctx.db.query("ads").order("desc").collect();
}
return ads.filter(
(ad) =>
ad.title.toLowerCase().includes(searchLower) ||
ad.description.toLowerCase().includes(searchLower) ||
ad.location.toLowerCase().includes(searchLower)
);
},
});
export const getByHandyman = query({
args: { handymanId: v.id("users") },
handler: async (ctx, args) => {
return await ctx.db
.query("ads")
.withIndex("by_handyman", (q) => q.eq("handymanId", args.handymanId))
.order("desc")
.collect();
},
});