Skip to content

Commit

Permalink
Fix bugs.
Browse files Browse the repository at this point in the history
  • Loading branch information
am9zZWY committed Jun 28, 2024
1 parent 3f7e7ac commit 82d8f15
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 76 deletions.
37 changes: 36 additions & 1 deletion src/app/admin/manage/order/[[...orderId]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,33 @@ const Page = ({ params }: { params: { orderId: string } }) => {
.catch(error => setError(error.message));
}

const setOrderAsPaid = (_id: string, isPaid: boolean) => {
fetch(`/api/order/${_id}/pay`, {
method: 'PUT',
headers: headers,
body: JSON.stringify({ isPaid: isPaid })
})
.then(async response => {
const data = await response.json();
if (!response.ok) {
const error = (data && data.message) || response.statusText;
throw new Error(error);
}
return data;
})
.then(() => {
// Update the order by id
const newOrders = orders.map((order: OrderDocument) => {
if (order._id === _id) {
order.isPaid = isPaid;
}
return order;
});
setOrders(newOrders);
})
.catch(error => setError(error.message));
}

/**
* Function to convert barcode to order
* @param barcode
Expand Down Expand Up @@ -217,7 +244,7 @@ const Page = ({ params }: { params: { orderId: string } }) => {
<span className="text-sm font-medium text-gray-800">{food.name}</span>
<div className="flex gap-1 mt-1">
{food.dietary && <span
className="px-2 py-0.5 text-xs font-semibold text-white bg-blue-500 rounded-full">{food.dietary}</span>}
className="px-2 py-0.5 text-xs font-semibold text-white bg-blue-500 rounded-full">{food.dietary}</span>}
<span
className="px-2 py-0.5 text-xs font-semibold text-white bg-green-500 rounded-full">{food.type}</span>
</div>
Expand All @@ -238,6 +265,14 @@ const Page = ({ params }: { params: { orderId: string } }) => {
{state}
</button>
))}
<button
className={`rounded-full px-4 py-2 text-sm font-medium transition duration-200
${order.isPaid ? 'bg-green-300 text-green-700 hover:bg-green-400' : 'bg-red-300 text-red-700 hover:bg-red-400'}
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed`}
onClick={() => setOrderAsPaid(order._id, !order.isPaid)}
>
{order.isPaid ? 'Paid' : 'Not Paid'}
</button>
</div>
</div>
))}
Expand Down
18 changes: 12 additions & 6 deletions src/app/admin/prepare/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import {useEffect, useState} from "react";
import {getFromLocalStorage} from "@/lib/localStorage";
import ErrorMessage from "@/app/components/ErrorMessage.jsx";
import {getDateFromTimeSlot} from "@/lib/time";
import {formatDateTime} from "@/lib/time";
import {formatDateTime, getDateFromTimeSlot} from "@/lib/time";
import WithAuth from "../WithAuth.jsx";

const getHeaders = () => {
Expand Down Expand Up @@ -98,6 +97,9 @@ const Page = () => {
newOrders[orderIndex] = newOrder;
setOrders(newOrders);
},
undone: (_id) => {
updateOrderStatus(_id, 'pending')
},
done: (_id) => {
updateOrderStatus(_id, 'baking')
},
Expand Down Expand Up @@ -127,17 +129,17 @@ const Page = () => {
<div key={activeOrderId + index} className="bg-white rounded-lg shadow-sm p-2">
<div className="mb-2">
<div className="flex justify-between items-center">
<div className="flex space-x-2">
<div className="flex space-x-2 flex-wrap">
<span
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800">
className="inline-flex items-center px-2.5 py-0.5 m-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800">
{order._id}
</span>
<span
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800">
className="inline-flex items-center px-2.5 py-0.5 m-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800">
{order.name}
</span>
<span
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-sm font-medium text-gray-800
className={`inline-flex items-center px-2.5 py-0.5 m-0.5 rounded-full text-sm font-medium text-gray-800
${order.status === 'pending' ? 'bg-yellow-100' : ''}
${order.status === 'paid' ? 'bg-orange-100' : ''}
${order.status === 'baking' ? 'bg-green-100' : ''}`}>
Expand Down Expand Up @@ -182,6 +184,10 @@ const Page = () => {
<button onClick={() => actions.cancel(order._id)}
className="px-2 py-1 text-xs rounded border border-gray-300 hover:bg-gray-100">Cancel
</button>
<button onClick={() => actions.undone(order._id)}
disabled={order.status === 'pending'}
className="px-2 py-1 text-xs rounded border border-gray-300 hover:bg-gray-100 disabled:opacity-50">Undone
</button>
<button onClick={() => actions.done(order._id)}
disabled={order.items.some(item => item.status !== 'done')}
className="px-2 py-1 text-xs rounded border border-gray-300 hover:bg-gray-100 disabled:opacity-50">Done
Expand Down
30 changes: 15 additions & 15 deletions src/app/api/manage/db/prepare/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,25 @@ export async function POST() {

// Add pizzas
const pizzas = [
{ name: 'Salami half', price: 4, type: 'pizza', ingredients: pizza_by_name('Salami'), },
{ name: 'Salami full', price: 8, type: 'pizza', ingredients: pizza_by_name('Salami'), },
{ name: 'Ham and mushrooms half', price: 4, type: 'pizza', ingredients: pizza_by_name('Ham and mushrooms'), },
{ name: 'Ham and mushrooms full', price: 8, type: 'pizza', ingredients: pizza_by_name('Ham and mushrooms'), },
{ name: 'Capriccosa half', price: 4, type: 'pizza', ingredients: pizza_by_name('Capriccosa'), },
{ name: 'Capriccosa full', price: 8, type: 'pizza', ingredients: pizza_by_name('Capriccosa'), },
{ name: 'Margherita half', price: 3, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Margherita'), },
{ name: 'Margherita full', price: 6, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Margherita'), },
{ name: 'Veggies half', price: 3, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Veggies'), },
{ name: 'Veggies full', price: 6, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Veggies'), },
{ name: 'Margherita vegan half', price: 3, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Margherita vegan'), },
{ name: 'Margherita vegan full', price: 6, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Margherita vegan'), },
{ name: 'Capriccosa vegan half', price: 3, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Capriccosa vegan'), },
{ name: 'Capriccosa vegan full', price: 6, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Capriccosa vegan'), },
{ name: 'Salami half', price: 4, type: 'pizza', ingredients: pizza_by_name('Salami'), size: 0.5 },
{ name: 'Salami full', price: 8, type: 'pizza', ingredients: pizza_by_name('Salami'), size: 1 },
{ name: 'Ham and mushrooms half', price: 4, type: 'pizza', ingredients: pizza_by_name('Ham and mushrooms'), size: 0.5 },
{ name: 'Ham and mushrooms full', price: 8, type: 'pizza', ingredients: pizza_by_name('Ham and mushrooms'), size: 1 },
{ name: 'Capriccosa half', price: 4, type: 'pizza', ingredients: pizza_by_name('Capriccosa'), size: 0.5 },
{ name: 'Capriccosa full', price: 8, type: 'pizza', ingredients: pizza_by_name('Capriccosa'), size: 1 },
{ name: 'Margherita half', price: 3, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Margherita'), size: 0.5 },
{ name: 'Margherita full', price: 6, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Margherita'), size: 1 },
{ name: 'Veggies half', price: 3, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Veggies'), size: 0.5 },
{ name: 'Veggies full', price: 6, dietary: 'vegetarian', type: 'pizza', ingredients: pizza_by_name('Veggies'), size: 1 },
{ name: 'Margherita vegan half', price: 3, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Margherita vegan'), size: 0.5 },
{ name: 'Margherita vegan full', price: 6, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Margherita vegan'), size: 1 },
{ name: 'Capriccosa vegan half', price: 3, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Capriccosa vegan'), size: 0.5 },
{ name: 'Capriccosa vegan full', price: 6, dietary: 'vegan', type: 'pizza', ingredients: pizza_by_name('Capriccosa vegan'), size: 1 },
];
for (const pizza of pizzas) {
await new Food(pizza).save();
}

// Add the system
const system = new System({ name: constants.SYSTEM_NAME, status: 'active' })
await system.save()
Expand Down
5 changes: 3 additions & 2 deletions src/app/api/order/[id]/cancel/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export async function PUT(req: Request, { params }: { params: { id: string } })

// Check if the order is already delivered or ready
if (['delivered', 'ready'].includes(foundOrder.status)) {
console.log('Order was already cancelled:', foundOrder.status)
return new Response(`Order was already ${foundOrder.status}. Cannot cancel!`, { status: 400 });
}

Expand All @@ -47,7 +48,7 @@ export async function PUT(req: Request, { params }: { params: { id: string } })
// console.log('Order updated:', foundOrder)
return Response.json(foundOrder);
} catch (error) {
console.error('Error setting order as paid:', error);
return new Response('Error setting order as paid', { status: 500 });
console.error('Error cancel order:', error);
return new Response('Error cancel order', { status: 500 });
}
}
89 changes: 89 additions & 0 deletions src/app/api/order/[id]/pay/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import mongoose from "mongoose";
import dbConnect from "@/lib/dbConnect";
import { headers } from "next/headers";
import { extractBearerFromHeaders, validateToken } from "@/lib/auth";
import { Order } from "@/model/order";
import { NextResponse } from "next/server";

/**
* Retrieve whether order is paid or not
* @param req
* @param params
* @constructor
*/
export async function GET(req: Request, { params }: { params: { id: string } }) {
await dbConnect();

// Get the ID from the URL
const id = params.id

// Check if the ID is valid and ObjectId
if (!id || !mongoose.isValidObjectId(id)) {
return NextResponse.json({
message: 'The ID is not valid.'
}, { status: 400 })
}

// Find the order by ID
const order = await Order.findById(id);
if (!order) {
return NextResponse.json({
message: 'The Order was not found.'
}, { status: 404 })
}

return Response.json({
isPaid: order.isPaid
})
}

/**
* Set order as paid
* @param req
* @param params
* @constructor
*/
export async function PUT(req: Request, { params }: { params: { id: string } }) {
await dbConnect();

// Authenticate the user
const headersList = headers()
if (!await validateToken(extractBearerFromHeaders(headersList))) {
return new Response('Unauthorized', { status: 401 });
}

// Get the order details from the request body
const id = params.id
const { isPaid } = await req.json()

// Check if the ID is valid and ObjectId
if (!id || !mongoose.isValidObjectId(id)) {
return NextResponse.json({
message: 'The ID is not valid.'
}, { status: 400 })
}


try {
// Find the order by ID
const foundOrder = await Order.findById(id);

if (!foundOrder) {
return NextResponse.json({
message: 'The Order was not found.'
}, { status: 404 })
}

// Update the order status
foundOrder.isPaid = isPaid

// Save the updated order
await foundOrder.save();

// console.log('Order updated:', foundOrder)
return Response.json(foundOrder);
} catch (error) {
console.error(`Error setting order as paid`)
return new Response(`Error setting order as paid`, { status: 500 });
}
}
4 changes: 2 additions & 2 deletions src/app/api/order/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import dbConnect from "@/lib/dbConnect";

import moment from 'moment-timezone';
import mongoose from "mongoose";
import { Order } from "@/model/order";
import { Food, FoodDocument } from "@/model/food";
import { constants } from "@/config";
import moment from "moment-timezone";


export async function GET(req: Request, { params }: { params: { id: string } }) {
Expand Down Expand Up @@ -68,6 +67,7 @@ export async function GET(req: Request, { params }: { params: { id: string } })
totalPrice: order.totalPrice,
finishedAt: moment(order.finishedAt).tz(constants.TIMEZONE_ORDERS).format(),
status: order.status,
isPaid: order.isPaid
}

// Send the order
Expand Down
3 changes: 2 additions & 1 deletion src/app/api/order/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export async function GET(req: Request) {
timeslot: order.timeslot, // new Date(order.orderDate.getTime() + totalTime),
totalPrice: order.totalPrice,
finishedAt: order.finishedAt,
status: order.status
status: order.status,
isPaid: order.isPaid
}
}))

Expand Down
2 changes: 1 addition & 1 deletion src/app/components/layout/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Header = () => {
}, []);

const adminLinks = [
{to: "/admin/preparing", text: "Prepare Foods"}, //does not work yet
{to: "/admin/prepare", text: "Prepare Foods"}, //does not work yet
{to: "/admin/manage", text: "Manage DB"},
{to: "/admin/manage/order", text: "Manage Orders"},
{to: "/admin/manage/pizza", text: "Manage Foods"},
Expand Down
Loading

0 comments on commit 82d8f15

Please sign in to comment.