updated edit category functionality and created menu item page for admin panel

This commit is contained in:
Juthatip McDevitt 2024-05-16 16:40:49 -05:00
parent cc709d5bd5
commit ee1869b0b8
6 changed files with 149 additions and 7 deletions

View file

@ -0,0 +1,21 @@
import { Category } from "../models/Category";
export async function POST(req){
const {name} = await req.json();
const categoryDoc = await Category.create({name})
return Response.json(categoryDoc);
}
export async function PUT(req){
const {_id, name} = await req.json();
await Category.updateOne({_id}, {name});
return Response.json(true);
}
export async function GET(req){
return Response.json(
await Category.find()
)
}

View file

@ -0,0 +1,11 @@
import { Schema, model, models } from "mongoose";
const CategorySchema = new Schema({
name: {
type: String,
required: true
},
}, {timestamps: true})
export const Category = models?.Category || model('Category', CategorySchema);

View file

@ -1,24 +1,96 @@
"use client"
import React from 'react'
import React, { useEffect, useState } from 'react'
import UserTab from '../../components/layout/UserTab'
import useProfile from '../../components/UseProfile'
import toast from 'react-hot-toast'
const CategoriesPage = () => {
const {loading:profileLoading, data:profileData} = useProfile();
const [categoryName, setCategoryName] = useState('');
const [categories, setCategories] = useState([]);
const [editCategory, setEditCategory] = useState(null);
//create new category && toast promis functionlity
useEffect(() => {
fetchCategories();
}, []);
function fetchCategories(){
fetch('api/categories').then(res => {
res.json().then(categories => {
setCategories(categories)
})
})
}
async function handleCategorySubmit(ev){
ev.preventDefault();
const creatCategoryPromise = new Promise(async (resolve, reject) => {
const data = {name:categoryName}; //edit category functionality
if(editCategory){
data._id = editCategory._id
}
const response = await fetch('api/categories', {
method: editCategory ? 'PUT' : 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data),
});
setCategoryName('');
fetchCategories();
setEditCategory(null)
if(response.ok)
resolve();
else
reject();
});
await toast.promise(creatCategoryPromise, {
loading: editCategory ? 'Updating...' : 'Creating...',
success: editCategory ? 'A category is updated' : 'A new category is created',
error: editCategory ? 'Fail to update category' : 'Fail to create a new category',
})
}
//loading & admin
if(profileLoading){
return <p className='flex justify-center items-center'>Loading...</p>
}
if(!profileData.admin){
return <p className='flex justify-center items-center'>Please login as an admin</p>
}
return (
<div className='px-5 mb-10 max-w-lg mx-auto'>
<div className='px-5 mb-10 max-w-md mx-auto'>
<UserTab isAdmin={true}/>
This is a category page
<form className='mt-10' onSubmit={handleCategorySubmit}>
<div className='flex flex-col'>
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>
{editCategory ? 'Update category' : 'New category name'}
{editCategory && (
<div className='font-notmal'>: {editCategory.name}</div>
)}
</label>
<div className='flex gap-2 items-center'>
<div className='grow'>
<input type='text' value={categoryName} onChange={ev => setCategoryName(ev.target.value)} placeholder='Enter category name'/>
</div>
<div>
<button type='submit' className='bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300'>{editCategory ? 'Update' : 'Create'}</button>
</div>
</div>
</div>
</form>
<div className='mt-5'>
<label className='-mb-1 text-gray-700 font-semibold text-sm'>Edit category</label>
{categories?.length > 0 && categories.map(c => (
<button onClick={() => {setEditCategory(c); setCategoryName(c.name)}} className='w-full flex gap-2 bg-slate-100 px-4 py-2 cursor-pointer rounded-md mb-2'>
<p>{c.name}</p>
</button>
))}
</div>
</div>
)
}

View file

@ -34,7 +34,7 @@ input[type="email"], input[type="password"], input[type="text"], input[type="tel
}
/*===== profile =====*/
div.tabs > *{
@apply py-2 px-4 bg-gray-200 text-gray-700 rounded-md
@apply py-1 px-2 sm:py-2 sm:px-4 bg-gray-200 text-gray-700 rounded-md
}
div.tabs > *.active{
@apply bg-pink-500 text-white font-semibold

View file

@ -0,0 +1,39 @@
"use client"
import React from 'react'
import UserTab from '../../components/layout/UserTab'
import useProfile from '../../components/UseProfile'
const MenuItemsPage = () => {
const {loading, data} = useProfile();
if(loading){
return <p className='flex justify-center items-center'>Loading...</p>
}
if(!data.admin){
return <p className='flex justify-center items-center'>Please login as an admin</p>
}
return (
<div className='px-5 mb-10 max-w-md mx-auto'>
<UserTab isAdmin={true}/>
<form className='mt-10'>
<div className='flex flex-col'>
<label className='-mb-1 text-gray-700 font-semibold text-sm flex'>Items name</label>
<div className='flex gap-2 items-center'>
<div className='grow'>
<input type='text' placeholder='Enter items name'/>
</div>
<div>
<button type='submit' className='bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300'>Create</button>
</div>
</div>
</div>
</form>
</div>
)
}
export default MenuItemsPage

View file

@ -88,7 +88,6 @@ const ProfilePage = () => {
success: 'An image is uploaded',
error: 'Fail to upload image!',
})
}
}