Status function change to auto update
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { Formik, Form } from "formik";
|
||||
import * as yup from "yup";
|
||||
import { Button, Radio } from "@nextui-org/react";
|
||||
import { NextUIFormikRadioGroup } from "../components/NextUIFormikRadioButton";
|
||||
import { Button } from "@nextui-org/react";
|
||||
import { NextUIFormikDatePicker } from "../components/NextUIFormikDatePicker";
|
||||
import NextUIFormikInput from "../components/NextUIFormikInput";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -18,14 +17,15 @@ const validationSchema = yup.object().shape({
|
||||
status: yup.string().trim().required()
|
||||
});
|
||||
|
||||
const initialValues: any = {
|
||||
const initialValues = {
|
||||
date: "",
|
||||
time: "",
|
||||
location: "",
|
||||
postalCode: "",
|
||||
status: ""
|
||||
status: "Up coming" // Set the default status
|
||||
};
|
||||
|
||||
|
||||
export default function CreateSchedulePage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -55,14 +55,9 @@ export default function CreateSchedulePage() {
|
||||
}
|
||||
|
||||
data.dateTime = dateTime.toISOString();
|
||||
|
||||
data.location = data.location.trim();
|
||||
|
||||
if (typeof data.postalCode === 'string') {
|
||||
data.postalCode = data.postalCode.trim();
|
||||
}
|
||||
|
||||
data.status = data.status.trim();
|
||||
data.postalCode = data.postalCode.trim();
|
||||
data.status = "Up coming"; // Set status to "Up coming" explicitly
|
||||
|
||||
console.log("Data to be sent:", data);
|
||||
|
||||
@@ -74,8 +69,8 @@ export default function CreateSchedulePage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full pb-12 pt-10">
|
||||
<div className="w-[400px] mx-auto p-6 bg-red-50 dark:bg-primary-950 border border-primary-100 rounded-2xl">
|
||||
<div className="w-full h-full pb-12 pt-20">
|
||||
<div className="w-[410px] mx-auto p-6 bg-red-50 dark:bg-primary-950 border border-primary-100 rounded-2xl">
|
||||
<div>
|
||||
<Button
|
||||
isIconOnly
|
||||
@@ -94,7 +89,7 @@ export default function CreateSchedulePage() {
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ isValid, dirty }) => (
|
||||
<Form className="flex flex-col gap-4 pt-5 items-center justify-center">
|
||||
<Form className="flex flex-col gap-4 pt-5 ">
|
||||
<div className="flex flex-col gap-5 w-[360px]">
|
||||
<NextUIFormikDatePicker
|
||||
label="Date"
|
||||
@@ -120,15 +115,6 @@ export default function CreateSchedulePage() {
|
||||
placeholder="123456"
|
||||
/>
|
||||
</div>
|
||||
<NextUIFormikRadioGroup
|
||||
label="Status"
|
||||
name="status"
|
||||
className="flex gap-2"
|
||||
>
|
||||
<Radio value="Up coming">Up coming</Radio>
|
||||
<Radio value="On going">On going</Radio>
|
||||
<Radio value="Ended">Ended</Radio>
|
||||
</NextUIFormikRadioGroup>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Formik, Form } from "formik";
|
||||
import * as yup from "yup";
|
||||
import { Button, Radio } from "@nextui-org/react";
|
||||
import { NextUIFormikRadioGroup } from "../components/NextUIFormikRadioButton";
|
||||
import { Button } from "@nextui-org/react";
|
||||
import { NextUIFormikDatePicker } from "../components/NextUIFormikDatePicker";
|
||||
import NextUIFormikInput from "../components/NextUIFormikInput";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
@@ -29,7 +28,6 @@ export default function EditSchedulePage() {
|
||||
time: "",
|
||||
location: "",
|
||||
postalCode: "",
|
||||
status: ""
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -78,10 +76,6 @@ export default function EditSchedulePage() {
|
||||
data.postalCode = data.postalCode.trim();
|
||||
}
|
||||
|
||||
data.status = data.status.trim();
|
||||
|
||||
console.log("Data to be sent:", data);
|
||||
|
||||
instance.put(`/schedule/${id}`, data)
|
||||
.then((res) => {
|
||||
console.log(res.data);
|
||||
@@ -93,8 +87,8 @@ export default function EditSchedulePage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full pb-12 pt-10">
|
||||
<div className="w-[400px] mx-auto p-6 bg-red-50 dark:bg-primary-950 border border-primary-100 rounded-2xl">
|
||||
<div className="w-full h-full pb-12 pt-20">
|
||||
<div className="w-[410px] mx-auto p-6 bg-red-50 dark:bg-primary-950 border border-primary-100 rounded-2xl">
|
||||
<div>
|
||||
<Button
|
||||
isIconOnly
|
||||
@@ -114,7 +108,7 @@ export default function EditSchedulePage() {
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ isValid, dirty }) => (
|
||||
<Form className="flex flex-col gap-4 pt-5 items-center justify-center">
|
||||
<Form className="flex flex-col gap-4 pt-4">
|
||||
<div className="flex flex-col gap-5 w-[360px]">
|
||||
<NextUIFormikDatePicker
|
||||
label="Date"
|
||||
@@ -140,17 +134,6 @@ export default function EditSchedulePage() {
|
||||
placeholder="123456"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<NextUIFormikRadioGroup
|
||||
label="Status"
|
||||
name="status"
|
||||
className="flex gap-2"
|
||||
>
|
||||
<Radio value="Up coming">Up coming</Radio>
|
||||
<Radio value="On going">On going</Radio>
|
||||
<Radio value="Ended">Ended</Radio>
|
||||
</NextUIFormikRadioGroup>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useEffect, useState } from 'react';
|
||||
import instance from "../security/http";
|
||||
import { PencilSquareIcon, PlusIcon, TrashDeleteIcon } from "../icons";
|
||||
import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Button, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, useDisclosure, SortDescriptor, Link as NextUILink } from "@nextui-org/react";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
interface Schedule {
|
||||
id: number;
|
||||
@@ -12,6 +13,12 @@ interface Schedule {
|
||||
status: string;
|
||||
}
|
||||
|
||||
const determineStatus = (dateTime: string): string => {
|
||||
const now = dayjs();
|
||||
const scheduleDateTime = dayjs(dateTime);
|
||||
return scheduleDateTime.isAfter(now) ? "Up coming" : "Ended";
|
||||
};
|
||||
|
||||
export default function ManageSchedulePage() {
|
||||
const navigate = useNavigate();
|
||||
const [scheduleList, setScheduleList] = useState<Schedule[]>([]);
|
||||
@@ -25,33 +32,63 @@ export default function ManageSchedulePage() {
|
||||
useEffect(() => {
|
||||
instance.get("/schedule")
|
||||
.then((res) => {
|
||||
const schedules = res.data.map((schedule: Schedule) => ({
|
||||
const schedules: Schedule[] = res.data.map((schedule: Schedule) => ({
|
||||
...schedule,
|
||||
dateTime: new Date(schedule.dateTime), // Convert to Date object
|
||||
dateTime: new Date(schedule.dateTime),
|
||||
status: determineStatus(schedule.dateTime),
|
||||
}));
|
||||
|
||||
setScheduleList(schedules);
|
||||
|
||||
// Update status in the database
|
||||
schedules.forEach((schedule: Schedule) => {
|
||||
instance.patch(`/schedule/${schedule.id}/status`)
|
||||
.catch((err) => {
|
||||
console.error(`Error updating status for schedule ${schedule.id}:`, err.response ? err.response.data : err.message);
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error fetching schedules:", err);
|
||||
console.error("Error fetching schedules:", err.response ? err.response.data : err.message);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setScheduleList(prevSchedules =>
|
||||
prevSchedules.map((schedule: Schedule) => ({
|
||||
...schedule,
|
||||
status: determineStatus(schedule.dateTime),
|
||||
}))
|
||||
);
|
||||
|
||||
// Optionally update status in the database
|
||||
scheduleList.forEach((schedule: Schedule) => {
|
||||
instance.patch(`/schedule/${schedule.id}/status`)
|
||||
.catch((err) => {
|
||||
console.error(`Error updating status for schedule ${schedule.id}:`, err.response ? err.response.data : err.message);
|
||||
});
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [scheduleList]);
|
||||
|
||||
const handleEdit = (id: number) => {
|
||||
navigate(`edit-schedule/${id}`);
|
||||
};
|
||||
|
||||
|
||||
const deleteSchedule = () => {
|
||||
if (scheduleIdToDelete !== null) {
|
||||
instance.delete(`/schedule/${scheduleIdToDelete}`)
|
||||
.then((res) => {
|
||||
console.log(res.data);
|
||||
setScheduleList((prev) => prev.filter(schedule => schedule.id !== scheduleIdToDelete));
|
||||
setScheduleList(prev => prev.filter((schedule: Schedule) => schedule.id !== scheduleIdToDelete));
|
||||
onOpenChange();
|
||||
setScheduleIdToDelete(null);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error deleting schedule:", err);
|
||||
console.error("Error deleting schedule:", err.response ? err.response.data : err.message);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -59,7 +96,7 @@ export default function ManageSchedulePage() {
|
||||
const sortScheduleList = (list: Schedule[], descriptor: SortDescriptor) => {
|
||||
const { column, direction } = descriptor;
|
||||
|
||||
const sortedList = [...list].sort((a, b) => {
|
||||
const sortedList = [...list].sort((a: Schedule, b: Schedule) => {
|
||||
switch (column) {
|
||||
case "dateTime":
|
||||
const dateA = new Date(a.dateTime);
|
||||
@@ -121,7 +158,7 @@ export default function ManageSchedulePage() {
|
||||
<TableColumn>Action</TableColumn>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{sortedScheduleList.map((schedule) => (
|
||||
{sortedScheduleList.map((schedule: Schedule) => (
|
||||
<TableRow key={schedule.id}>
|
||||
<TableCell>{((schedule.dateTime as unknown) as Date).toLocaleDateString()}</TableCell>
|
||||
<TableCell>{((schedule.dateTime as unknown) as Date).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</TableCell>
|
||||
@@ -171,6 +208,5 @@ export default function ManageSchedulePage() {
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const Schedule = sequelize.define("Schedule", {
|
||||
dateTime: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
const { DataTypes } = require("sequelize");
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
const Schedule = sequelize.define(
|
||||
"Schedule",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
allowNull: false,
|
||||
primaryKey: true,
|
||||
},
|
||||
dateTime: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
},
|
||||
location: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
postalCode: {
|
||||
type: DataTypes.INTEGER(6),
|
||||
allowNull: false
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
},
|
||||
location: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
postalCode: {
|
||||
type: DataTypes.INTEGER(6),
|
||||
allowNull: false
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "schedule"
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"axios": "^1.7.2",
|
||||
"bad-words": "^3.0.4",
|
||||
"cors": "^2.8.5",
|
||||
"dayjs": "^1.11.12",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
|
||||
8
server/pnpm-lock.yaml
generated
8
server/pnpm-lock.yaml
generated
@@ -20,6 +20,9 @@ importers:
|
||||
cors:
|
||||
specifier: ^2.8.5
|
||||
version: 2.8.5
|
||||
dayjs:
|
||||
specifier: ^1.11.12
|
||||
version: 1.11.12
|
||||
dotenv:
|
||||
specifier: ^16.4.5
|
||||
version: 16.4.5
|
||||
@@ -327,6 +330,9 @@ packages:
|
||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
dayjs@1.11.12:
|
||||
resolution: {integrity: sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==}
|
||||
|
||||
debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
@@ -1229,6 +1235,8 @@ snapshots:
|
||||
object-assign: 4.1.1
|
||||
vary: 1.1.2
|
||||
|
||||
dayjs@1.11.12: {}
|
||||
|
||||
debug@2.6.9:
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
|
||||
@@ -3,6 +3,7 @@ const router = express.Router();
|
||||
const { Schedule } = require('../models');
|
||||
const { Op } = require("sequelize");
|
||||
const yup = require("yup");
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
router.post("/", async (req, res) => {
|
||||
let data = req.body;
|
||||
@@ -104,5 +105,27 @@ router.delete("/:id", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.patch("/:id/status", async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const schedule = await Schedule.findByPk(id);
|
||||
|
||||
if (!schedule) {
|
||||
return res.status(404).json({ message: 'Schedule not found' });
|
||||
}
|
||||
|
||||
const now = dayjs();
|
||||
const scheduleDateTime = dayjs(schedule.dateTime);
|
||||
|
||||
const newStatus = scheduleDateTime.isAfter(now) ? "Up coming" : "Ended";
|
||||
schedule.status = newStatus;
|
||||
|
||||
await schedule.save();
|
||||
res.status(200).json(schedule);
|
||||
} catch (error) {
|
||||
console.error("Error updating status:", error); // Log the error
|
||||
res.status(500).json({ message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user