Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 5x 5x 5x 5x 5x 5x 5x 5x 5x 4x 4x 4x 4x 4x 4x 4x 4x 8x 2x 2x 2x 2x 2x 2x 2x 2x 3x 1x 1x 8x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 2x 2x 3x 5x 3x 3x 2x 2x 2x 1x 1x | import { NextRequest, NextResponse } from 'next/server';
import { Session } from "next-auth";
import {
createReview,
getProductReviews,
getProductRating,
getUserReviews } from "@/lib/ecommerce";
import {
withErrorHandling,
withUser,
successResponse,
ApiError,
ApiSuccessResponse } from "@/lib/api";
import { RouteContext } from "@/lib/api/middleware";
import type { AuthenticatedUser } from '@/lib/api/middleware/types';
interface ReviewsResponse {
reviews?: unknown[];
data?: unknown[];
pagination: {
page: number;
limit: number;
total: number;
pages: number;
};
rating?: unknown;
}
/**
* GET /api/reviews
* Get reviews with filters
*
* Query Parameters:
* - productId: Filter by product
* - userId: Filter by user
* - page: Page number
* - limit: Results per page
* - rating: Filter by rating (1-5)
* - sortBy: newest, helpful, rating_high, rating_low
*/
async function handleGet(
request: NextRequest
): Promise<NextResponse<ApiSuccessResponse<ReviewsResponse>>> {
const searchParams = request.nextUrl.searchParams;
const productId = searchParams.get("productId");
const userId = searchParams.get("userId");
const page = searchParams.get("page") ? parseInt(searchParams.get("page")!) : 1;
const limit = searchParams.get("limit") ? parseInt(searchParams.get("limit")!) : 10;
const rating = searchParams.get("rating") ? parseInt(searchParams.get("rating")!) : undefined;
const sortBy = (searchParams.get("sortBy") || "newest") as "newest" | "helpful" | "rating_high" | "rating_low";
if (productId) {
// Get reviews for a product
const { reviews, pagination } = await getProductReviews(
parseInt(productId),
{
page,
limit,
rating,
sortBy}
);
// Get product rating summary
const ratingData = await getProductRating(parseInt(productId));
return successResponse({
data: reviews,
pagination,
rating: ratingData});
} else if (userId) {
// Get reviews by user
const { reviews, pagination } = await getUserReviews(parseInt(userId), {
page,
limit});
return successResponse({
data: reviews,
pagination});
} else {
throw ApiError.validation("Either productId or userId is required");
}
}
export const GET = withErrorHandling(handleGet);
/**
* POST /api/reviews
* Create a new review (requires authentication)
*/
async function handlePost(
request: NextRequest,
_context: RouteContext | undefined,
_session: Session,
user: AuthenticatedUser
): Promise<NextResponse> {
const body = await request.json();
const { productId, rating, comment } = body;
if (!productId || !rating) {
throw ApiError.validation("productId and rating are required");
}
if (rating < 1 || rating > 5) {
throw ApiError.validation("Rating must be between 1 and 5");
}
const review = await createReview(productId, user.id, rating, comment);
return successResponse(review);
}
export const POST = withErrorHandling(withUser(handlePost));
|