feat(market): add Minha Intenções tab with panel, hook, and badge
- Introduced "Minhas Intenções" tab visible only to logged-in users. - Integrated MyPurchaseIntentionsPanel and useMyPurchaseIntentions hook. - Added tab badge showing count of pending intentions. - Extended session API to include user’s main character for downstream features.
This commit is contained in:
1 parent
f35fee944d
commit
7f42def478
55 files changed
+4906
-95
No files matched your search
@@ -20,6 +20,7 @@ export interface PurchaseIntention {
|
||||
listing_id: number;
|
||||
buyer_id: number;
|
||||
payment_method: string;
|
||||
payment_method_change_count: number;
|
||||
status: PurchaseIntentionStatus;
|
||||
buyer_message: string | null;
|
||||
seller_response: string | null;
|
||||
@@ -251,3 +252,123 @@ export async function hasPendingIntention(
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca intenção pendente de um comprador para um listing específico
|
||||
*/
|
||||
export async function getPendingIntentionByBuyerAndListing(
|
||||
listingId: number,
|
||||
buyerId: number
|
||||
): Promise<PurchaseIntention | null> {
|
||||
return await prisma.purchaseIntention.findFirst({
|
||||
where: {
|
||||
listing_id: listingId,
|
||||
buyer_id: buyerId,
|
||||
status: "pending",
|
||||
},
|
||||
include: {
|
||||
listing: {
|
||||
select: {
|
||||
listing_id: true,
|
||||
item_name: true,
|
||||
seller_id: true,
|
||||
},
|
||||
},
|
||||
buyer: {
|
||||
select: {
|
||||
user_id: true,
|
||||
username: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
created_at: "desc",
|
||||
},
|
||||
}) as PurchaseIntention | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza o método de pagamento de uma intenção
|
||||
*/
|
||||
export async function updatePurchaseIntentionPaymentMethod(
|
||||
intentionId: number,
|
||||
newPaymentMethod: PaymentMethod
|
||||
): Promise<PurchaseIntention> {
|
||||
// Buscar intenção atual
|
||||
const intention = await prisma.purchaseIntention.findUnique({
|
||||
where: { intention_id: intentionId },
|
||||
});
|
||||
|
||||
if (!intention) {
|
||||
throw new Error("Intenção não encontrada");
|
||||
}
|
||||
|
||||
// Verificar se pode trocar (máximo 1 troca)
|
||||
if (intention.payment_method_change_count >= 1) {
|
||||
throw new Error("Você já atingiu o limite de trocas de método de pagamento");
|
||||
}
|
||||
|
||||
// Verificar se o novo método é diferente
|
||||
if (intention.payment_method === newPaymentMethod) {
|
||||
throw new Error("O novo método de pagamento deve ser diferente do atual");
|
||||
}
|
||||
|
||||
// Atualizar
|
||||
return await prisma.purchaseIntention.update({
|
||||
where: { intention_id: intentionId },
|
||||
data: {
|
||||
payment_method: newPaymentMethod,
|
||||
payment_method_change_count: intention.payment_method_change_count + 1,
|
||||
updated_at: new Date(),
|
||||
},
|
||||
include: {
|
||||
listing: {
|
||||
select: {
|
||||
listing_id: true,
|
||||
item_name: true,
|
||||
seller_id: true,
|
||||
},
|
||||
},
|
||||
buyer: {
|
||||
select: {
|
||||
user_id: true,
|
||||
username: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}) as PurchaseIntention;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna os IDs de anúncios com intenções pendentes para um comprador
|
||||
*/
|
||||
export async function getPendingIntentionListingIdsForBuyer(
|
||||
buyerId: number,
|
||||
listingIds: number[]
|
||||
): Promise<number[]> {
|
||||
if (listingIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const intentions = await prisma.purchaseIntention.findMany({
|
||||
where: {
|
||||
buyer_id: buyerId,
|
||||
status: "pending",
|
||||
listing_id: {
|
||||
in: listingIds,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
listing_id: true,
|
||||
},
|
||||
});
|
||||
|
||||
const uniqueIds = new Set<number>();
|
||||
intentions.forEach((intention) => {
|
||||
uniqueIds.add(intention.listing_id);
|
||||
});
|
||||
|
||||
return Array.from(uniqueIds);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user