Skip to content

Instantly share code, notes, and snippets.

@naiplawan
Last active September 19, 2023 06:05
Show Gist options
  • Select an option

  • Save naiplawan/8d9de887e7b9fe2652a90715ce7dfd46 to your computer and use it in GitHub Desktop.

Select an option

Save naiplawan/8d9de887e7b9fe2652a90715ce7dfd46 to your computer and use it in GitHub Desktop.
AdminServiceList
import "../../styles/App.css";
import {useEffect} from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import { useUtils } from "../../hooks/utils.js";
import image from "../../assets/AdminPhoto/imageIndex";
const AdminServiceHeader = () => {
const navigate = useNavigate();
const { searchService, setSearchService, setService } = useUtils;
const searchServiceData = async () => {
const results = await axios.get(
`http://localhost:4000/service?keywords=${searchService}`
);
setService(results.data.data);
};
useEffect(() => {
let timerId;
timerId = setTimeout(searchServiceData, 1000);
return () => {
clearTimeout(timerId);
};
}, [searchService]);
return (
<header className="sticky top-0 bg-white">
<div className="pl-60 flex items-center h-20 pr-10 justify-between border-b border-grey300 ">
<h1 className="text-xl font-medium text-black pl-10">บริการ</h1>
<div className="flex">
<input
id="search-text"
name="search-text"
type="text"
placeholder="ค้นหาบริการ..."
value={searchService}
onChange={(event) => {
setSearchService(event.target.value);
}}
className="px-4 py-2 border-grey300 border bg-white rounded-lg focus:outline-none focus:ring focus:border-blue-300 w-[400px]"
/>
<button
className="btn-primary flex items-center ml-6"
onClick={() => navigate("/admin-create-service")}
>
<div className="text-base font-medium mr-3">เพิ่มบริการ</div>
<img src={image.plusSign} alt="Plus Symbol" />
</button>
</div>
</div>
</header>
);
};
export default AdminServiceHeader
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import dateFormat from "../../utils/dateFormat.js";
import AlertBoxDelete from "../AlertBox.jsx";
import image from "../../assets/AdminPhoto/imageIndex.js";
import { useUtils } from "../../hooks/utils.js";
import axios from "axios";
import drag from "../../assets/AdminPhoto/drag.svg";
import { Droppable, Draggable, DragDropContext } from "react-beautiful-dnd";
function AdminServiceList() {
const [service, setService] = useState([]);
const [service_Id, setService_Id] = useState();
const { setDeleteService, deleteService } = useUtils();
const navigate = useNavigate();
const hide = () => {
setDeleteService(false);
};
// Function to delete a service by ID
const deleteServiceId = async (serviceId) => {
await axios.delete(`http://localhost:4000/service/${serviceId}`);
getService();
document.getElementById("popUp").style.display = "none";
navigate("/service-dashboard");
};
const handleDelete = (serviceId) => {
deleteServiceId(serviceId);
setDeleteService(false);
};
const onDragEnd = (result) => {
if (!result.destination) return;
// Modified this section to correctly update the 'service' state
const reorderedServices = [...service.data];
const [movedService] = reorderedServices.splice(result.source.index, 1);
reorderedServices.splice(result.destination.index, 0, movedService);
setService({ data: reorderedServices });
// Save the order in localStorage
localStorage.setItem("serviceOrder", JSON.stringify(reorderedServices));
};
// Function to map category IDs to background colors
const getCategoryColor = (categoryId) => {
switch (categoryId % 5) {
case 0:
return "bg-blue100 text-blue800";
case 1:
return "bg-amber text-brown";
case 2:
return "bg-lime text-green900";
case 3:
return "bg-purple100 text-purple900";
default:
return "bg-pink text-red";
}
};
// Function to fetch services
const getService = async () => {
try {
const response = await axios.get("http://localhost:4000/service");
setService(response.data.data);
} catch (error) {
console.error("Error fetching services:", error);
}
};
// Function to set service delete alert
const serviceDeleteAlert = async (serviceId) => {
setService_Id(serviceId);
setDeleteService(true);
};
useEffect(() => {
getService();
}, []);
return (
<DragDropContext onDragEnd={onDragEnd}>
<div className="categories-data min-h-screen bg-bg p-[41px]">
<ul>
<li className="flex text-sm text-grey600 list-none p-[20px] rounded-t-lg bg-grey200 border-[1px] border-grey300">
<span className="text-grey700 mx-[1%] text-center">ลำดับ</span>
<span className="text-grey700 mx-[1%]">ชื่อบริการ</span>
<span className="p-3 font-normal">หมวดหมู่</span>
<span className="text-grey700 mx-[15%]">สร้างเมื่อ</span>
<span className="text-grey700 mx-[]">แก้ไขล่าสุด</span>
<span className="text-grey700 mx-[30%] mr-[2%]"> Action</span>
</li>
<Droppable droppableId="service-list">
{(provided) => (
<ul {...provided.droppableProps} ref={provided.innerRef}>
{service &&
service.data &&
service.data.map((serviceItem, index) => (
<Draggable
key={serviceItem.service_id.toString()}
draggableId={serviceItem.service_id.toString()}
index={index}
>
{(provided) => (
<li
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className="flex hover:bg-grey100 bg-white list-none p-[20px] border-[1px] border-grey200"
>
<div>
<img src={drag} className="w-[30px]" alt="Drag" />
</div>
<div className="service-detail cursor-pointer flex justify-between w-[100%] text-black h-[88px] items-center">
<div
className={`w-[100%] ml-2% rounded-lg justify-center flex ${
serviceItem.category?.category_name
? getCategoryColor(
serviceItem.category.category_id
)
: ""
}`}
onClick={() =>
navigate(
`/admin-service-detail/${serviceItem.service_id}`
)}
>
<div className="w-[20%]">{index + 1}</div>
<div className="w-[30%] ml-[2%] font-light">
{serviceItem.service_name}
</div>
<span>
{serviceItem.category?.category_name}
</span>
</div>
<span className="-[50%] ml-[12%]">
{dateFormat(serviceItem.service_created_date)}
</span>
<span className="w-[50%] mr-[10%]">
{dateFormat(serviceItem.service_edited_date)}
</span>
</div>
{/* Delete */}
{serviceItem.service_id !== deleteServiceId && (
<div className="pr-[5%] flex h-[88px] items-center justify-center">
<img
className="cursor-pointer w-[25px] h-[25px] mr-[50%]"
alt="Delete"
src={image.trashIcon}
onClick={() => {
serviceDeleteAlert(serviceItem.service_id);
}}
/>
<img
className="cursor-pointer w-[25px] h-[25px]"
alt="Edit"
src={image.editIcon}
onClick={() =>
navigate(
`/service/edit/${serviceItem.service_id}`
)}
/>
</div>
)}
</li>
)}
</Draggable>
))}
</ul>
)}
</Droppable>
</ul>
</div>
{deleteService && (
<AlertBoxDelete
deleteFunction={handleDelete}
hideFunction={hide}
textAlert="ยืนยันการลบรายการ"
alertQuestion={`คุณต้องการลบรายการ '${
service.data.find(
(serviceItem) => serviceItem.service_id === service_Id
)?.service_name
}' ใช่หรือไม่ ?`}
primary="ลบรายการ"
secondary="ยกเลิก"
/>
)}
</DragDropContext>
);
}
export default AdminServiceList;
import SideBar from "../components/ServicePage/AdminSidebar.jsx";
import "../styles/App.css";
import AdminServiceList from "../components/AdminServicePage/AdminServiceList.jsx";
import AdminServiceHeader from "../components/AdminServicePage/AdminServiceHeader.jsx";
import { useUtils } from "../hooks/utils.js";
function AdminServicePage() {
const {
searchService,
setSearchService,
service,
setService,
deleteServiceId,
serviceDeleteAlert,
deleteService,
service_Id,
setDeleteService,
} = useUtils;
return (
<div className="admin-service-page" >
<SideBar />
<AdminServiceHeader
setService={setService}
searchService={searchService}
setSearchService={setSearchService} />
<AdminServiceList
service={service}
deleteServiceId={deleteServiceId}
serviceDeleteAlert={serviceDeleteAlert}
deleteService={deleteService}
setDeleteService={setDeleteService}
service_Id={service_Id}/>
</div>
)
}
export default AdminServicePage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment