init commit,

This commit is contained in:
louiscklaw
2025-05-28 09:55:51 +08:00
commit efe70ceb69
8042 changed files with 951668 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import { headers } from 'next/headers';
import { verify } from 'src/utils/jwt';
import { STATUS, response, handleError } from 'src/utils/response';
import { _users, JWT_SECRET } from 'src/_mock/_auth';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/**
* This API is used for demo purpose only
* You should use a real database
* You should hash the password before saving to database
* You should not save the password in the database
* You should not expose the JWT_SECRET in the client side
*/
export async function GET() {
try {
const headersList = headers();
const authorization = headersList.get('authorization');
if (!authorization || !authorization.startsWith('Bearer ')) {
return response({ message: 'Authorization token missing or invalid' }, STATUS.UNAUTHORIZED);
}
const accessToken = `${authorization}`.split(' ')[1];
const data = await verify(accessToken, JWT_SECRET);
const currentUser = _users.find((user) => user.id === data.userId);
if (!currentUser) {
return response({ message: 'Invalid authorization token' }, STATUS.UNAUTHORIZED);
}
return response({ user: currentUser }, 200);
} catch (error) {
return handleError('[Auth] - Me', error);
}
}

View File

@@ -0,0 +1,45 @@
import type { NextRequest } from 'next/server';
import { sign } from 'src/utils/jwt';
import { STATUS, response, handleError } from 'src/utils/response';
import { _users, JWT_SECRET, JWT_EXPIRES_IN } from 'src/_mock/_auth';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/**
* This API is used for demo purpose only
* You should use a real database
* You should hash the password before saving to database
* You should not save the password in the database
* You should not expose the JWT_SECRET in the client side
*/
export async function POST(req: NextRequest) {
try {
const { email, password } = await req.json();
const currentUser = _users.find((user) => user.email === email);
if (!currentUser) {
return response(
{ message: 'There is no user corresponding to the email address.' },
STATUS.UNAUTHORIZED
);
}
if (currentUser?.password !== password) {
return response({ message: 'Wrong password' }, STATUS.UNAUTHORIZED);
}
const accessToken = await sign({ userId: currentUser?.id }, JWT_SECRET, {
expiresIn: JWT_EXPIRES_IN,
});
return response({ user: currentUser, accessToken }, 200);
} catch (error) {
return handleError('Auth - Sign in', error);
}
}

View File

@@ -0,0 +1,61 @@
import type { NextRequest } from 'next/server';
import { sign } from 'src/utils/jwt';
import { STATUS, response, handleError } from 'src/utils/response';
import { _users, JWT_SECRET, JWT_EXPIRES_IN } from 'src/_mock/_auth';
// ----------------------------------------------------------------------
/**
* This API is used for demo purpose only
* You should use a real database
* You should hash the password before saving to database
* You should not save the password in the database
* You should not expose the JWT_SECRET in the client side
*/
export const runtime = 'edge';
export async function POST(req: NextRequest) {
try {
const { email, password, firstName, lastName } = await req.json();
const userExists = _users.find((user) => user.email === email);
if (userExists) {
return response(
{ message: 'There already exists an account with the given email address.' },
STATUS.CONFLICT
);
}
const newUser = {
id: _users[0].id,
displayName: `${firstName} ${lastName}`,
email,
password,
photoURL: '',
phoneNumber: '',
country: '',
address: '',
state: '',
city: '',
zipCode: '',
about: '',
role: 'user',
isPublic: true,
};
const accessToken = await sign({ userId: newUser.id }, JWT_SECRET, {
expiresIn: JWT_EXPIRES_IN,
});
// Push new user to database
_users.push(newUser);
return response({ user: newUser, accessToken }, STATUS.OK);
} catch (error) {
return handleError('Auth - Sign up', error);
}
}

View File

@@ -0,0 +1,109 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _events } from 'src/_mock/_event';
// ----------------------------------------------------------------------
export const runtime = 'edge';
type EventType = ReturnType<typeof _events>[number];
let eventsData: Map<string, EventType> = new Map();
function loggerData(action?: string, value?: unknown) {
logger('[Event] total-events', eventsData.size);
if (value || action) {
logger(`[Event] ${action}`, value);
}
}
function initializeEvents() {
if (eventsData.size === 0) {
const events = _events();
eventsData = new Map(events.map((event) => [event.id, event]));
}
}
/** **************************************
* GET - All events
*************************************** */
export async function GET() {
try {
initializeEvents();
loggerData();
return response({ events: Array.from(eventsData.values()) }, STATUS.OK);
} catch (error) {
return handleError('Event - Get all', error);
}
}
/** **************************************
* POST - Create event
*************************************** */
export async function POST(req: NextRequest) {
try {
const { eventData } = await req.json();
eventsData.set(eventData.id, eventData);
loggerData('created', eventData);
return response({ event: eventData }, STATUS.OK);
} catch (error) {
return handleError('Event - Create', error);
}
}
/** **************************************
* PUT - Update event
*************************************** */
export async function PUT(req: NextRequest) {
try {
const { eventData } = await req.json();
if (!eventsData.has(eventData.id)) {
return response({ message: 'Event not found!' }, STATUS.NOT_FOUND);
}
const event = eventsData.get(eventData.id);
// Merge the existing event with the updated data
const updatedEvent = {
...event,
...eventData,
};
eventsData.set(eventData.id, updatedEvent);
loggerData('updated', updatedEvent);
return response({ event: updatedEvent }, STATUS.OK);
} catch (error) {
return handleError('Event - Update', error);
}
}
/** **************************************
* PATCH - Delete event
*************************************** */
export async function PATCH(req: NextRequest) {
try {
const { eventId } = await req.json();
if (!eventsData.has(eventId)) {
return response({ message: 'Event not found!' }, STATUS.NOT_FOUND);
}
eventsData.delete(eventId);
loggerData('deleted', eventId);
return response({ eventId }, STATUS.OK);
} catch (error) {
return handleError('Event - Delete', error);
}
}

View File

@@ -0,0 +1,178 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _contacts, _conversations } from 'src/_mock/_chat';
// ----------------------------------------------------------------------
export const runtime = 'edge';
type ConversationType = ReturnType<typeof _conversations>[number];
let conversationsData = new Map<string, ConversationType>();
const ENDPOINTS = {
CONVERSATIONS: 'conversations',
CONVERSATION: 'conversation',
MARK_AS_SEEN: 'mark-as-seen',
CONTACTS: 'contacts',
};
function loggerData(action?: string, value?: unknown) {
logger('[Chat] total-conversations', conversationsData.size);
if (value || action) {
logger(`[Chat] ${action}`, value);
}
}
function initializeConversations() {
if (conversationsData.size === 0) {
const conversations = _conversations();
conversationsData = new Map(conversations.map((conv) => [conv.id, conv]));
}
}
/** **************************************
* GET - Handle actions based on the endpoint
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const endpoint = searchParams.get('endpoint');
switch (endpoint) {
case ENDPOINTS.CONVERSATIONS:
return getConversations();
case ENDPOINTS.CONVERSATION:
return getConversation(req);
case ENDPOINTS.MARK_AS_SEEN:
return markAsSeen(req);
case ENDPOINTS.CONTACTS:
return getContacts();
default:
return response({ message: 'Endpoint not found!' }, STATUS.NOT_FOUND);
}
} catch (error) {
return handleError(`Chat - Get request`, error);
}
}
/** **************************************
* POST - Create conversation
*************************************** */
export async function POST(req: NextRequest) {
try {
const { conversationData } = await req.json();
conversationsData.set(conversationData.id, conversationData);
loggerData('created-conversation', conversationData.id);
return response({ conversation: conversationData }, STATUS.OK);
} catch (error) {
return handleError('Chat - Create conversation', error);
}
}
/** **************************************
* PUT - Update conversation
*************************************** */
export async function PUT(req: NextRequest) {
try {
const { conversationId, messageData } = await req.json();
const conversation = conversationsData.get(conversationId);
if (!conversation) {
return response({ message: 'Conversation not found!' }, STATUS.NOT_FOUND);
}
const updatedConversation = {
...conversation,
messages: [...conversation.messages, messageData],
};
conversationsData.set(conversationId, updatedConversation);
loggerData('updated-conversation', conversationId);
return response({ conversation: updatedConversation }, STATUS.OK);
} catch (error) {
return handleError('Chat - Update conversation', error);
}
}
/** **************************************
* GET - Contact list
*************************************** */
async function getContacts() {
return response({ contacts: _contacts() }, STATUS.OK);
}
/** **************************************
* GET - Conversation list
*************************************** */
async function getConversations() {
try {
initializeConversations();
loggerData();
return response({ conversations: Array.from(conversationsData.values()) }, STATUS.OK);
} catch (error) {
return handleError('Chat - Get conversations', error);
}
}
/** **************************************
* GET - Conversation
*************************************** */
async function getConversation(req: NextRequest) {
initializeConversations(); // Fix when the conversationsData is empty
const { searchParams } = req.nextUrl;
const conversationId = searchParams.get('conversationId');
if (!conversationId) {
return response({ message: 'Missing conversation id!' }, STATUS.BAD_REQUEST);
}
const conversation = conversationsData.get(conversationId);
if (!conversation) {
return response({ message: 'Conversation not found!' }, STATUS.NOT_FOUND);
}
loggerData('get-conversation', conversation.id);
return response({ conversation }, STATUS.OK);
}
/** **************************************
* PUT - Mark conversation as seen
*************************************** */
async function markAsSeen(req: NextRequest) {
const { searchParams } = req.nextUrl;
const conversationId = searchParams.get('conversationId');
if (!conversationId) {
return response({ message: 'Missing conversation id!' }, STATUS.BAD_REQUEST);
}
const conversation = conversationsData.get(conversationId);
if (!conversation) {
return response({ message: 'Conversation not found!' }, STATUS.NOT_FOUND);
}
const updatedConversation = {
...conversation,
unreadCount: 0,
};
conversationsData.set(conversationId, updatedConversation);
loggerData('conversation-marked-as-seen', conversation.id);
return response({ conversationId }, STATUS.OK);
}

View File

@@ -0,0 +1,16 @@
import type { NextRequest, NextResponse } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
export async function GET(req: NextRequest, res: NextResponse) {
try {
const products = await prisma.productItem.findMany();
console.log({ products });
return response({ products }, STATUS.OK);
} catch (error) {
return handleError('Post - Get latest', error);
}
}

View File

@@ -0,0 +1,16 @@
import type { NextRequest, NextResponse } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../lib/prisma';
export async function GET(req: NextRequest, res: NextResponse) {
try {
const users = await prisma.user.findMany();
console.log({ users });
return response({ users }, STATUS.OK);
} catch (error) {
return handleError('Post - Get latest', error);
}
}

View File

@@ -0,0 +1,271 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _board } from 'src/_mock/_kanban';
// ----------------------------------------------------------------------
export const runtime = 'edge';
type BoardType = ReturnType<typeof _board>;
let boardData: BoardType = _board();
const ENDPOINTS = {
CREATE_COLUMN: 'create-column',
UPDATE_COLUMN: 'update-column',
MOVE_COLUMN: 'move-column',
CLEAR_COLUMN: 'clear-column',
DELETE_COLUMN: 'delete-column',
CREATE_TASK: 'create-task',
UPDATE_TASK: 'update-task',
MOVE_TASK: 'move-task',
DELETE_TASK: 'delete-task',
};
function loggerData(action?: string, value?: unknown) {
const columnsWithTasks = boardData.columns.map(
(col) => `${col.name} (${boardData.tasks[col.id].length} tasks)`
);
logger(
'[Kanban] get-board',
`columns (${boardData.columns.length}): ${JSON.stringify(columnsWithTasks, null, 2)}`
);
if (value || action) {
logger(`[Kanban] ${action}`, value);
}
}
function updateBoardData(newData: Partial<BoardType>) {
boardData = { ...boardData, ...newData };
}
/** **************************************
* GET - Board
*************************************** */
export async function GET() {
try {
loggerData();
return response({ board: boardData }, STATUS.OK);
} catch (error) {
return handleError('Kanban - Get board', error);
}
}
/** **************************************
* POST - Handle actions based on the endpoint
*************************************** */
export async function POST(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const endpoint = searchParams.get('endpoint');
switch (endpoint) {
case ENDPOINTS.CREATE_COLUMN:
return createColumn(req);
case ENDPOINTS.UPDATE_COLUMN:
return updateColumn(req);
case ENDPOINTS.MOVE_COLUMN:
return moveColumn(req);
case ENDPOINTS.CLEAR_COLUMN:
return clearColumn(req);
case ENDPOINTS.DELETE_COLUMN:
return deleteColumn(req);
case ENDPOINTS.CREATE_TASK:
return createTask(req);
case ENDPOINTS.UPDATE_TASK:
return updateTask(req);
case ENDPOINTS.MOVE_TASK:
return moveTask(req);
case ENDPOINTS.DELETE_TASK:
return deleteTask(req);
default:
return response({ message: 'Endpoint not found!' }, STATUS.NOT_FOUND);
}
} catch (error) {
return handleError(`Kanban - Post request`, error);
}
}
/** **************************************
* COLUMN MANAGEMENT
*************************************** */
/**
* @Column Create
* Create a new column in the board.
*/
async function createColumn(req: NextRequest) {
const { columnData } = await req.json();
// Add the new column and initialize its task list
updateBoardData({
columns: [...boardData.columns, columnData],
tasks: { ...boardData.tasks, [columnData.id]: [] },
});
loggerData('created-column', columnData.name);
return response({ column: columnData }, STATUS.OK);
}
/**
* @Column Update
* Update the name of an existing column.
*/
async function updateColumn(req: NextRequest) {
const { columnId, columnName } = await req.json();
const column = boardData.columns.find((col) => col.id === columnId);
if (!column) {
return response({ message: 'Column not found!' }, STATUS.NOT_FOUND);
}
// Find and update the specified column.
updateBoardData({
columns: boardData.columns.map((col) =>
col.id === columnId ? { ...col, name: columnName } : col
),
});
loggerData('updated-column', columnName);
return response({ columnId, columnName }, STATUS.OK);
}
/**
* @Column Move
* Reorder columns in the board.
*/
async function moveColumn(req: NextRequest) {
const { updateColumns } = await req.json();
// Update the column order
updateBoardData({
columns: updateColumns,
});
loggerData('moved-column', 'success!');
return response({ columns: updateColumns }, STATUS.OK);
}
/**
* @Column Clear
* Remove all tasks from a specific column.
*/
async function clearColumn(req: NextRequest) {
const { columnId } = await req.json();
// Clear tasks for the specified column
updateBoardData({
tasks: { ...boardData.tasks, [columnId]: [] },
});
loggerData('cleared-column', 'success!');
return response({ columnId }, STATUS.OK);
}
/**
* @Column Delete
* Delete a column and its associated tasks.
*/
async function deleteColumn(req: NextRequest) {
const { columnId } = await req.json();
// Remove the column and its tasks
updateBoardData({
columns: boardData.columns.filter((col) => col.id !== columnId),
tasks: Object.fromEntries(Object.entries(boardData.tasks).filter(([id]) => id !== columnId)),
});
loggerData('deleted-column', columnId);
return response({ columnId }, STATUS.OK);
}
/** **************************************
* TASK MANAGEMENT
*************************************** */
/**
* @Task Create
* Add a new task to a specific column.
*/
async function createTask(req: NextRequest) {
const { columnId, taskData } = await req.json();
// Add the new task to the specified column
updateBoardData({
tasks: {
...boardData.tasks,
[columnId]: [taskData, ...boardData.tasks[columnId]],
},
});
loggerData('created-task', taskData.name);
return response({ columnId, taskData }, STATUS.OK);
}
/**
* @Task Update
* Update an existing task in a specific column.
*/
async function updateTask(req: NextRequest) {
const { columnId, taskData } = await req.json();
// Update the task in the specified column
updateBoardData({
tasks: {
...boardData.tasks,
[columnId]: boardData.tasks[columnId].map((task) =>
task.id === taskData.id ? { ...task, ...taskData } : task
),
},
});
loggerData('updated-task', taskData.name);
return response({ task: taskData }, STATUS.OK);
}
/**
* @Task Move
* Move a task between columns or reorder within the same column.
*/
async function moveTask(req: NextRequest) {
const { updateTasks } = await req.json();
// Update the task structure
updateBoardData({
tasks: updateTasks,
});
loggerData('moved-task', 'success!');
return response({ tasks: updateTasks }, STATUS.OK);
}
/**
* @Task Delete
* Remove a task from a specific column.
*/
async function deleteTask(req: NextRequest) {
const { columnId, taskId } = await req.json();
// Remove the task from the specified column
updateBoardData({
tasks: {
...boardData.tasks,
[columnId]: boardData.tasks[columnId].filter((task) => task.id !== taskId),
},
});
loggerData('deleted-task', taskId);
return response({ columnId, taskId }, STATUS.OK);
}

View File

@@ -0,0 +1,34 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _mails } from 'src/_mock/_mail';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Mail details
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const mailId = searchParams.get('mailId');
const mails = _mails();
const mail = mails.find((mailItem) => mailItem.id === mailId);
if (!mail) {
return response({ message: 'Mail not found!' }, STATUS.NOT_FOUND);
}
logger('[Mail] details', mail.id);
return response({ mail }, STATUS.OK);
} catch (error) {
return handleError('Mail - Get details', error);
}
}

View File

@@ -0,0 +1,23 @@
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _labels } from 'src/_mock/_mail';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Labels
*************************************** */
export async function GET() {
try {
const labels = _labels();
logger('[Mail] labels', labels.length);
return response({ labels }, STATUS.OK);
} catch (error) {
return handleError('Mail - Get labels', error);
}
}

View File

@@ -0,0 +1,57 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _mails, _labels } from 'src/_mock/_mail';
// ----------------------------------------------------------------------
export const runtime = 'edge';
type MailType = ReturnType<typeof _mails>[number];
/** **************************************
* GET - Mails by labelId
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const labelId = searchParams.get('labelId');
const labels = _labels();
const mails = _mails();
logger('[Mail] labelId', labelId);
const label = labels.find((labelItem) => labelItem.id === labelId);
if (!label) {
return response({ message: 'Label not found!' }, STATUS.NOT_FOUND);
}
// Get filtered mails
const filteredMails =
label.type === 'custom'
? mails.filter((mail) => mail.labelIds.includes(labelId!))
: filterMailsByLabelId(mails, labelId);
logger(`[Mail] label-[${labelId}]`, filteredMails.length);
return response({ mails: filteredMails }, STATUS.OK);
} catch (error) {
return handleError('Mail - Get list', error);
}
}
/** **************************************
* Actions & Utility
*************************************** */
function filterMailsByLabelId(mails: MailType[], labelId?: string | null) {
if (!labelId || labelId === 'inbox') return mails.filter((mail) => mail.folder === 'inbox');
if (labelId === 'all') return mails;
if (labelId === 'starred') return mails.filter((mail) => mail.isStarred);
if (labelId === 'important') return mails.filter((mail) => mail.isImportant);
return mails.filter((mail) => mail.folder === labelId);
}

View File

@@ -0,0 +1,21 @@
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _navItems } from 'src/_mock/_navbar';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Nav items
*************************************** */
export async function GET() {
try {
logger('[Nav] items', _navItems.length);
return response({ navItems: _navItems }, STATUS.OK);
} catch (error) {
return handleError('Nav - Get list', error);
}
}

View File

@@ -0,0 +1,80 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
// ----------------------------------------------------------------------
export const runtime = 'edge';
const DEFAULT_PAGE = 1;
const DEFAULT_PER_PAGE = 10;
const TOTAL_PRODUCTS = 50;
const _products = Array.from({ length: TOTAL_PRODUCTS }, (_, index) => ({
id: `id-${index + 1}`,
name: `product-${index + 1}`,
category: (index % 2 && 'Accessories') || (index % 3 && 'Shoes') || 'Clothing',
}));
type Products = typeof _products;
/** **************************************
* Products with pagination and filters
*************************************** */
export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl;
const pageParam = searchParams.get('page') ?? `${DEFAULT_PAGE}`;
const perPageParam = searchParams.get('perPage') ?? `${DEFAULT_PER_PAGE}`;
const page = parseInt(pageParam, 10);
const perPage = parseInt(perPageParam, 10);
const searchQuery = searchParams.get('search')?.trim().toLowerCase() ?? '';
const category = searchParams.get('category')?.trim() ?? '';
try {
const filteredProducts = filterProducts(_products, searchQuery, category);
const paginatedProducts = paginateProducts(filteredProducts, page, perPage);
const totalPages = Math.ceil(filteredProducts.length / perPage);
const totalItems = filteredProducts.length;
logger('[Product] filtered-products', filteredProducts.length);
return response(
{
products: paginatedProducts,
totalPages,
totalItems,
categoryOptions: Array.from(
new Set(_products.map(({ category: c_category }) => c_category))
), // Remove duplicate categories
},
STATUS.OK
);
} catch (error) {
return handleError('Pagination - Get list of products', error);
}
}
// ----------------------------------------------------------------------
function paginateProducts(products: Products, page: number, perPage: number) {
const startIndex = (page - 1) * perPage;
const endIndex = startIndex + perPage;
return products.slice(startIndex, endIndex);
}
function filterProducts(products: Products, searchQuery: string, category: string) {
return products.filter(({ id, name, category: prodCategory }) => {
// Accept search by id or name
const matchesSearch = searchQuery
? id.includes(searchQuery) || name.toLowerCase().includes(searchQuery)
: true;
const matchesCategory = category ? prodCategory === category : true;
return matchesSearch && matchesCategory;
});
}

View File

@@ -0,0 +1,36 @@
import type { NextRequest } from 'next/server';
import { kebabCase } from 'es-toolkit';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _posts } from 'src/_mock/_blog';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* Get post details
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const title = searchParams.get('title');
const posts = _posts();
const post = posts.find((postItem) => kebabCase(postItem.title) === title);
if (!post) {
return response({ message: 'Post not found!' }, STATUS.NOT_FOUND);
}
logger('[Post] details', post.id);
return response({ post }, STATUS.OK);
} catch (error) {
return handleError('Post - Get details', error);
}
}

View File

@@ -0,0 +1,32 @@
import type { NextRequest } from 'next/server';
import { kebabCase } from 'es-toolkit';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _posts } from 'src/_mock/_blog';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* Get latest posts
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const title = searchParams.get('title');
const posts = _posts();
const latestPosts = posts.filter((_post) => kebabCase(_post.title) !== title);
logger('[Post] latest-list', latestPosts.length);
return response({ latestPosts }, STATUS.OK);
} catch (error) {
return handleError('Post - Get latest', error);
}
}

View File

@@ -0,0 +1,23 @@
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _posts } from 'src/_mock/_blog';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Posts
*************************************** */
export async function GET() {
try {
const posts = _posts();
logger('[Post] list', posts.length);
return response({ posts }, STATUS.OK);
} catch (error) {
return handleError('Post - Get list', error);
}
}

View File

@@ -0,0 +1,38 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _posts } from 'src/_mock/_blog';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Search posts
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const query = searchParams.get('query')?.trim().toLowerCase();
if (!query) {
return response({ results: [] }, STATUS.OK);
}
const posts = _posts();
// Accept search by title or description
const results = posts.filter(
({ title, description }) =>
title.toLowerCase().includes(query) || description?.toLowerCase().includes(query)
);
logger('[Post] search-results', results.length);
return response({ results }, STATUS.OK);
} catch (error) {
return handleError('Post - Get search', error);
}
}

View File

@@ -0,0 +1,34 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _products } from 'src/_mock/_product';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* Get product details
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const productId = searchParams.get('productId');
const products = _products();
const product = products.find((productItem) => productItem.id === productId);
if (!product) {
return response({ message: 'Product not found!' }, STATUS.NOT_FOUND);
}
logger('[Product] details', product.id);
return response({ product }, STATUS.OK);
} catch (error) {
return handleError('Product - Get details', error);
}
}

View File

@@ -0,0 +1,21 @@
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* GET - Products
*************************************** */
export async function GET() {
try {
const products = await prisma.productItem.findMany();
logger('[Product] list', products.length);
return response({ products }, STATUS.OK);
} catch (error) {
return handleError('Product - Get list', error);
}
}

View File

@@ -0,0 +1,23 @@
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _products } from 'src/_mock/_product';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Products
*************************************** */
export async function GET() {
try {
const products = _products();
logger('[Product] list', products.length);
return response({ products }, STATUS.OK);
} catch (error) {
return handleError('Product - Get list', error);
}
}

View File

@@ -0,0 +1,37 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { _products } from 'src/_mock/_product';
// ----------------------------------------------------------------------
export const runtime = 'edge';
/** **************************************
* GET - Search products
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const query = searchParams.get('query')?.trim().toLowerCase();
if (!query) {
return response({ results: [] }, STATUS.OK);
}
const products = _products();
// Accept search by name or sku
const results = products.filter(
({ name, sku }) => name.toLowerCase().includes(query) || sku?.toLowerCase().includes(query)
);
logger('[Product] search-results', results.length);
return response({ results }, STATUS.OK);
} catch (error) {
return handleError('Product - Get search', error);
}
}