245 lines
No EOL
7.6 KiB
JavaScript
245 lines
No EOL
7.6 KiB
JavaScript
import { NextResponse } from 'next/server';
|
|
import { sql } from '@vercel/postgres';
|
|
import { verifyToken } from '../auth-utils.js';
|
|
|
|
// GET /api/collections - Get user collections
|
|
export async function GET(request) {
|
|
try {
|
|
const token = request.headers.get('authorization')?.replace('Bearer ', '');
|
|
const user = await verifyToken(token);
|
|
|
|
if (!user) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const { searchParams } = new URL(request.url);
|
|
const collectionId = searchParams.get('id');
|
|
|
|
if (collectionId) {
|
|
// Get specific collection with cards
|
|
const result = await sql.query(`
|
|
SELECT
|
|
c.id,
|
|
c.name,
|
|
c.description,
|
|
c.is_public,
|
|
c.created_at,
|
|
c.updated_at,
|
|
cc.quantity,
|
|
cc.condition,
|
|
cc.notes,
|
|
cc.purchase_price,
|
|
cc.purchase_date,
|
|
card.id as card_id,
|
|
card.name as card_name,
|
|
card.set_name,
|
|
card.set_code,
|
|
card.card_number,
|
|
card.rarity,
|
|
card.game,
|
|
card.card_type,
|
|
card.mana_cost,
|
|
card.cmc,
|
|
card.colors,
|
|
card.oracle_text,
|
|
card.power,
|
|
card.toughness,
|
|
card.image_url,
|
|
card.stock_image_url,
|
|
card.current_price,
|
|
card.market_price
|
|
FROM user_collections c
|
|
LEFT JOIN collection_cards cc ON c.id = cc.collection_id
|
|
LEFT JOIN cards card ON cc.card_id = card.id
|
|
WHERE c.id = $1 AND c.user_id = $2
|
|
ORDER BY card.name ASC
|
|
`, [collectionId, user.id]);
|
|
|
|
if (result.rows.length === 0) {
|
|
return NextResponse.json({ error: 'Collection not found' }, { status: 404 });
|
|
}
|
|
|
|
const collection = {
|
|
id: result.rows[0].id,
|
|
name: result.rows[0].name,
|
|
description: result.rows[0].description,
|
|
is_public: result.rows[0].is_public,
|
|
created_at: result.rows[0].created_at,
|
|
updated_at: result.rows[0].updated_at,
|
|
cards: result.rows
|
|
.filter(row => row.card_id)
|
|
.map(row => ({
|
|
quantity: row.quantity,
|
|
condition: row.condition,
|
|
notes: row.notes,
|
|
purchase_price: row.purchase_price,
|
|
purchase_date: row.purchase_date,
|
|
card: {
|
|
id: row.card_id,
|
|
name: row.card_name,
|
|
set_name: row.set_name,
|
|
set_code: row.set_code,
|
|
card_number: row.card_number,
|
|
rarity: row.rarity,
|
|
game: row.game,
|
|
card_type: row.card_type,
|
|
mana_cost: row.mana_cost,
|
|
cmc: row.cmc,
|
|
colors: row.colors ? JSON.parse(row.colors) : [],
|
|
oracle_text: row.oracle_text,
|
|
power: row.power,
|
|
toughness: row.toughness,
|
|
image_url: row.image_url,
|
|
stock_image_url: row.stock_image_url,
|
|
current_price: row.current_price,
|
|
market_price: row.market_price
|
|
}
|
|
}))
|
|
};
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
data: collection
|
|
});
|
|
} else {
|
|
// Get all user collections
|
|
const result = await sql.query(`
|
|
SELECT
|
|
c.id,
|
|
c.name,
|
|
c.description,
|
|
c.is_public,
|
|
c.created_at,
|
|
c.updated_at,
|
|
COUNT(cc.card_id) as card_count
|
|
FROM user_collections c
|
|
LEFT JOIN collection_cards cc ON c.id = cc.collection_id
|
|
WHERE c.user_id = $1
|
|
GROUP BY c.id, c.name, c.description, c.is_public, c.created_at, c.updated_at
|
|
ORDER BY c.created_at DESC
|
|
`, [user.id]);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
data: result.rows.map(row => ({
|
|
id: row.id,
|
|
name: row.name,
|
|
description: row.description,
|
|
is_public: row.is_public,
|
|
created_at: row.created_at,
|
|
updated_at: row.updated_at,
|
|
card_count: parseInt(row.card_count)
|
|
}))
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching collections:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to fetch collections', details: error.message },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
// POST /api/collections - Create collection or add card to collection
|
|
export async function POST(request) {
|
|
try {
|
|
const token = request.headers.get('authorization')?.replace('Bearer ', '');
|
|
const user = await verifyToken(token);
|
|
|
|
if (!user) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const { searchParams } = new URL(request.url);
|
|
const action = searchParams.get('action');
|
|
|
|
if (action === 'create') {
|
|
// Create new collection
|
|
const { name, description, is_public } = await request.json();
|
|
|
|
if (!name) {
|
|
return NextResponse.json({ error: 'Collection name is required' }, { status: 400 });
|
|
}
|
|
|
|
const result = await sql.query(`
|
|
INSERT INTO user_collections (user_id, name, description, is_public)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING *
|
|
`, [user.id, name, description || '', is_public || false]);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
data: result.rows[0],
|
|
message: 'Collection created successfully'
|
|
});
|
|
}
|
|
|
|
if (action === 'add-card') {
|
|
// Add card to collection
|
|
const { collection_id, card_id, quantity, condition, notes, purchase_price, purchase_date } = await request.json();
|
|
|
|
if (!collection_id || !card_id) {
|
|
return NextResponse.json({ error: 'Collection ID and card ID are required' }, { status: 400 });
|
|
}
|
|
|
|
// Verify collection belongs to user
|
|
const collectionCheck = await sql.query(`
|
|
SELECT id FROM user_collections WHERE id = $1 AND user_id = $2
|
|
`, [collection_id, user.id]);
|
|
|
|
if (collectionCheck.rows.length === 0) {
|
|
return NextResponse.json({ error: 'Collection not found or access denied' }, { status: 404 });
|
|
}
|
|
|
|
// Check if card already exists in collection
|
|
const existingCard = await sql.query(`
|
|
SELECT id, quantity FROM collection_cards
|
|
WHERE collection_id = $1 AND card_id = $2
|
|
`, [collection_id, card_id]);
|
|
|
|
if (existingCard.rows.length > 0) {
|
|
// Update existing card quantity
|
|
const newQuantity = (existingCard.rows[0].quantity || 0) + (quantity || 1);
|
|
await sql.query(`
|
|
UPDATE collection_cards
|
|
SET quantity = $1, updated_at = NOW()
|
|
WHERE id = $2
|
|
`, [newQuantity, existingCard.rows[0].id]);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: 'Card quantity updated in collection'
|
|
});
|
|
} else {
|
|
// Add new card to collection
|
|
await sql.query(`
|
|
INSERT INTO collection_cards (
|
|
collection_id, card_id, quantity, condition, notes, purchase_price, purchase_date
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
`, [
|
|
collection_id,
|
|
card_id,
|
|
quantity || 1,
|
|
condition || 'near-mint',
|
|
notes || '',
|
|
purchase_price || null,
|
|
purchase_date || null
|
|
]);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: 'Card added to collection'
|
|
});
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({ error: 'Invalid action' }, { status: 400 });
|
|
} catch (error) {
|
|
console.error('Error with collections:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to process collection action', details: error.message },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|