deckhearth/pages/api/cards/search.js

212 lines
7.7 KiB
JavaScript
Raw Normal View History

import { sql } from '@vercel/postgres';
export default async function handler(req, res) {
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const {
query = '',
game = '',
rarity = '',
set = '',
minPrice = '',
maxPrice = '',
page = 1,
limit = 50
} = req.query;
let result;
let countResult;
// Build query based on filters
if (query && query.trim() && game && game !== 'all' && rarity && rarity !== 'all' && set && set !== 'all') {
// All filters applied
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
AND rarity = ${rarity}
AND set_name = ${set}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
AND rarity = ${rarity}
AND set_name = ${set}
`;
} else if (query && query.trim() && game && game !== 'all' && rarity && rarity !== 'all') {
// Query, game, and rarity filters
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
AND rarity = ${rarity}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
AND rarity = ${rarity}
`;
} else if (query && query.trim() && game && game !== 'all') {
// Query and game filters
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE (name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`})
AND game = ${game}
`;
} else if (query && query.trim()) {
// Only query filter
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE name ILIKE ${`%${query.trim()}%`} OR oracle_text ILIKE ${`%${query.trim()}%`}
`;
} else if (game && game !== 'all') {
// Only game filter
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE game = ${game}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE game = ${game}
`;
} else if (rarity && rarity !== 'all') {
// Only rarity filter
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE rarity = ${rarity}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE rarity = ${rarity}
`;
} else if (set && set !== 'all') {
// Only set filter
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
WHERE set_name = ${set}
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
WHERE set_name = ${set}
`;
} else {
// No filters - get all cards
result = await sql`
SELECT
id, name, set_name, set_code, card_number, rarity, game,
mana_cost, cmc, card_type, colors, oracle_text,
power, toughness, image_url, stock_image_url,
current_price, market_price, scryfall_id, verified,
created_at, updated_at
FROM cards
ORDER BY name ASC
LIMIT ${parseInt(limit)} OFFSET ${(parseInt(page) - 1) * parseInt(limit)}
`;
countResult = await sql`
SELECT COUNT(*) as total FROM cards
`;
}
const total = parseInt(countResult.rows[0]?.total || 0);
// Get unique values for filters
const [gamesResult, raritiesResult, setsResult] = await Promise.all([
sql`SELECT DISTINCT game FROM cards WHERE game IS NOT NULL ORDER BY game`,
sql`SELECT DISTINCT rarity FROM cards WHERE rarity IS NOT NULL ORDER BY rarity`,
sql`SELECT DISTINCT set_name FROM cards WHERE set_name IS NOT NULL ORDER BY set_name`
]);
res.status(200).json({
success: true,
cards: result.rows || [],
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
},
filters: {
games: Array.isArray(gamesResult.rows) ? gamesResult.rows.map(row => row.game) : [],
rarities: Array.isArray(raritiesResult.rows) ? raritiesResult.rows.map(row => row.rarity) : [],
sets: Array.isArray(setsResult.rows) ? setsResult.rows.map(row => row.set_name) : []
}
});
} catch (error) {
console.error('Card search error:', error);
res.status(500).json({
error: 'Search failed',
details: error.message
});
}
}