Add comprehensive plant trading marketplace with: - Prisma schema with marketplace models (Listing, Offer, SellerProfile, WishlistItem) - Service layer for listings, offers, search, and matching - API endpoints for CRUD operations, search, and recommendations - Marketplace pages: home, listing detail, create, my-listings, my-offers - Reusable UI components: ListingCard, ListingGrid, OfferForm, SearchFilters, etc. Features: - Browse and search listings by category, price, tags - Create and manage listings (draft, active, sold, cancelled) - Make and manage offers on listings - Seller and buyer views with statistics - Featured and recommended listings - In-memory store (ready for database migration via Agent 2)
71 lines
2 KiB
TypeScript
71 lines
2 KiB
TypeScript
// API: My Offers
|
|
// GET /api/marketplace/my-offers - Get current user's offers (as buyer or seller)
|
|
|
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import { offerService, listingService } from '@/lib/marketplace';
|
|
import { OfferStatus } from '@/lib/marketplace/types';
|
|
|
|
export default async function handler(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse
|
|
) {
|
|
if (req.method !== 'GET') {
|
|
res.setHeader('Allow', ['GET']);
|
|
return res.status(405).json({ error: `Method ${req.method} Not Allowed` });
|
|
}
|
|
|
|
try {
|
|
const userId = req.headers['x-user-id'] as string;
|
|
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'Authentication required' });
|
|
}
|
|
|
|
const { role, status } = req.query;
|
|
|
|
// Default to buyer role
|
|
const userRole = role === 'seller' ? 'seller' : 'buyer';
|
|
|
|
let offers;
|
|
|
|
if (userRole === 'buyer') {
|
|
// Get offers made by this user
|
|
offers = await offerService.getOffersByBuyer(userId);
|
|
|
|
// Attach listing info
|
|
offers = await Promise.all(
|
|
offers.map(async (offer) => {
|
|
const listing = await listingService.getListingById(offer.listingId);
|
|
return { ...offer, listing };
|
|
})
|
|
);
|
|
} else {
|
|
// Get offers on this user's listings
|
|
offers = await offerService.getOffersForSeller(userId);
|
|
}
|
|
|
|
// Filter by status if provided
|
|
if (status && typeof status === 'string') {
|
|
offers = offers.filter(o => o.status === status as OfferStatus);
|
|
}
|
|
|
|
// Sort by most recent first
|
|
offers.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
|
|
// Get statistics
|
|
const stats = await offerService.getOfferStats(userId, userRole);
|
|
|
|
return res.status(200).json({
|
|
offers,
|
|
total: offers.length,
|
|
role: userRole,
|
|
stats,
|
|
});
|
|
} catch (error) {
|
|
console.error('My offers API error:', error);
|
|
return res.status(500).json({
|
|
error: 'Internal server error',
|
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
});
|
|
}
|
|
}
|