feat: implement market page with QueryProvider and dynamic listings

- wrap root layout with QueryProvider for React Query
- replace market UnderConstruction placeholder with MarketClient and real data fetching
- implement search, pagination, and sort via search params using getActiveListings
- add necessary client components and queries
- update dependencies (e.g., prisma, pkg-types)
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-05 01:58:03 -03:00
1 parent 55eebde0ba
commit ab37b477df
106 files changed
+15261 -301

No files matched your search

+72
View File
@@ -0,0 +1,72 @@
/**
* Queries de favoritos usando Prisma
*/
import { prisma } from "../app";
/**
* Verifica se um anúncio está favoritado por um usuário
*/
export async function isFavorite(userId: number, listingId: number): Promise<boolean> {
const favorite = await prisma.userFavorite.findUnique({
where: {
user_id_ad_id: {
user_id: userId,
ad_id: listingId,
},
},
});
return !!favorite;
}
/**
* Favorita um anúncio
*/
export async function addFavorite(userId: number, listingId: number): Promise<void> {
await prisma.userFavorite.upsert({
where: {
user_id_ad_id: {
user_id: userId,
ad_id: listingId,
},
},
create: {
user_id: userId,
ad_id: listingId,
},
update: {}, // Se já existe, não faz nada
});
}
/**
* Remove favorito de um anúncio
*/
export async function removeFavorite(userId: number, listingId: number): Promise<void> {
await prisma.userFavorite.delete({
where: {
user_id_ad_id: {
user_id: userId,
ad_id: listingId,
},
},
}).catch(() => {
// Ignorar erro se não existir (idempotente)
});
}
/**
* Toggle favorite (favorita se não estiver, desfavorita se estiver)
*/
export async function toggleFavorite(userId: number, listingId: number): Promise<boolean> {
const isFavorited = await isFavorite(userId, listingId);
if (isFavorited) {
await removeFavorite(userId, listingId);
return false;
} else {
await addFavorite(userId, listingId);
return true;
}
}