- 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.
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { query, mutation } from "./_generated/server";
|
|
import { v } from "convex/values";
|
|
|
|
const SEED_CATEGORIES = [
|
|
{ slug: "majstor-za-se", name: "Мајстор за сѐ", icon: "🔧", sortOrder: 0 },
|
|
{ slug: "vodoinstalater", name: "Водоинсталатер", icon: "🚿", sortOrder: 1 },
|
|
{ slug: "elektrichar", name: "Електричар", icon: "⚡", sortOrder: 2 },
|
|
{ slug: "teskar", name: "Тескар", icon: "🔨", sortOrder: 3 },
|
|
{ slug: "farbar", name: "Фарбар", icon: "🖌️", sortOrder: 4 },
|
|
{ slug: "keramichar", name: "Керамичар", icon: "🧱", sortOrder: 5 },
|
|
{ slug: "zidar", name: "Зидар", icon: "🏗️", sortOrder: 6 },
|
|
{ slug: "gradezhnik", name: "Градежник", icon: "🏢", sortOrder: 7 },
|
|
{ slug: "stolar", name: "Столар", icon: "🪵", sortOrder: 8 },
|
|
{ slug: "moler", name: "Молер", icon: "🎨", sortOrder: 9 },
|
|
{ slug: "klima-montazher", name: "Клима монтажер", icon: "❄️", sortOrder: 10 },
|
|
{ slug: "drugo", name: "Друго", icon: "📋", sortOrder: 11 },
|
|
];
|
|
|
|
export const list = query({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
return await ctx.db.query("categories").withIndex("by_slug").order("asc").collect();
|
|
},
|
|
});
|
|
|
|
export const getBySlug = query({
|
|
args: { slug: v.string() },
|
|
handler: async (ctx, args) => {
|
|
return await ctx.db
|
|
.query("categories")
|
|
.withIndex("by_slug", (q) => q.eq("slug", args.slug))
|
|
.first();
|
|
},
|
|
});
|
|
|
|
export const seedCategories = mutation({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
for (const cat of SEED_CATEGORIES) {
|
|
const existing = await ctx.db
|
|
.query("categories")
|
|
.withIndex("by_slug", (q) => q.eq("slug", cat.slug))
|
|
.first();
|
|
if (!existing) {
|
|
await ctx.db.insert("categories", cat);
|
|
}
|
|
}
|
|
},
|
|
}); |