Add login and register dialogs, user dropdown menu with profile link and logout option, and integrate with session management hook. Prevent hydration mismatches by conditionally rendering auth elements after mount. Update package-lock.json with new @esbuild dependencies for build tooling.
112 lines
2.1 KiB
TypeScript
112 lines
2.1 KiB
TypeScript
/**
|
|
* Queries de bids (lances em leilões)
|
|
* Operações para a tabela bids
|
|
*/
|
|
|
|
import { query } from "../index";
|
|
|
|
export interface Bid {
|
|
bid_id: number;
|
|
listing_id: number;
|
|
bidder_id: number;
|
|
bid_amount: number;
|
|
bid_type: "pix" | "tibia_coins" | "gold_coins" | null;
|
|
created_at: Date;
|
|
is_active: boolean;
|
|
}
|
|
|
|
export interface CreateBidData {
|
|
listing_id: number;
|
|
bidder_id: number;
|
|
bid_amount: number;
|
|
bid_type?: "pix" | "tibia_coins" | "gold_coins";
|
|
}
|
|
|
|
/**
|
|
* Cria um novo lance
|
|
*/
|
|
export async function createBid(data: CreateBidData): Promise<Bid> {
|
|
const result = await query<Bid>(
|
|
`
|
|
INSERT INTO bids (listing_id, bidder_id, bid_amount, bid_type)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING *
|
|
`,
|
|
[data.listing_id, data.bidder_id, data.bid_amount, data.bid_type || null]
|
|
);
|
|
|
|
return result.rows[0];
|
|
}
|
|
|
|
/**
|
|
* Busca lances de um anúncio
|
|
*/
|
|
export async function getBidsByListing(
|
|
listingId: number,
|
|
activeOnly: boolean = true
|
|
): Promise<Bid[]> {
|
|
let sql = `
|
|
SELECT * FROM bids
|
|
WHERE listing_id = $1
|
|
`;
|
|
|
|
const params: any[] = [listingId];
|
|
|
|
if (activeOnly) {
|
|
sql += ` AND is_active = TRUE`;
|
|
}
|
|
|
|
sql += ` ORDER BY bid_amount DESC, created_at DESC`;
|
|
|
|
const result = await query<Bid>(sql, params);
|
|
return result.rows;
|
|
}
|
|
|
|
/**
|
|
* Busca o maior lance de um anúncio
|
|
*/
|
|
export async function getHighestBid(listingId: number): Promise<Bid | null> {
|
|
const result = await query<Bid>(
|
|
`
|
|
SELECT * FROM bids
|
|
WHERE listing_id = $1 AND is_active = TRUE
|
|
ORDER BY bid_amount DESC, created_at DESC
|
|
LIMIT 1
|
|
`,
|
|
[listingId]
|
|
);
|
|
|
|
return result.rows[0] || null;
|
|
}
|
|
|
|
/**
|
|
* Cancela um lance (desativa)
|
|
*/
|
|
export async function cancelBid(bidId: number): Promise<boolean> {
|
|
const result = await query(
|
|
`
|
|
UPDATE bids
|
|
SET is_active = FALSE
|
|
WHERE bid_id = $1
|
|
`,
|
|
[bidId]
|
|
);
|
|
|
|
return result.rowCount > 0;
|
|
}
|
|
|
|
/**
|
|
* Busca lance por ID
|
|
*/
|
|
export async function getBidById(bidId: number): Promise<Bid | null> {
|
|
const result = await query<Bid>(
|
|
`
|
|
SELECT * FROM bids WHERE bid_id = $1
|
|
`,
|
|
[bidId]
|
|
);
|
|
|
|
return result.rows[0] || null;
|
|
}
|
|
|