Status function change to auto update

This commit is contained in:
ZacTohZY
2024-08-12 19:06:26 +08:00
parent d89a58f809
commit 80a9e9edd3
7 changed files with 119 additions and 72 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>
)
);
}

View File

@@ -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"
});

View File

@@ -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
View File

@@ -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

View File

@@ -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;