Fixed Function of Admin KG Schedule
This commit is contained in:
@@ -10,8 +10,10 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@internationalized/date": "^3.5.5",
|
||||||
"@nextui-org/react": "^2.4.2",
|
"@nextui-org/react": "^2.4.2",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
"dayjs": "^1.11.12",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"framer-motion": "^11.2.10",
|
"framer-motion": "^11.2.10",
|
||||||
"openai": "^4.53.2",
|
"openai": "^4.53.2",
|
||||||
|
|||||||
6292
client/pnpm-lock.yaml
generated
6292
client/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,8 @@ import ForgotPasswordPage from "./pages/ForgotPasswordPage";
|
|||||||
import RestrictedLayout from "./layouts/restricted";
|
import RestrictedLayout from "./layouts/restricted";
|
||||||
import Ranking from "./pages/Ranking";
|
import Ranking from "./pages/Ranking";
|
||||||
import ManageSchedulePage from "./pages/ManageSchedulePage";
|
import ManageSchedulePage from "./pages/ManageSchedulePage";
|
||||||
|
import EditSchedulePage from "./pages/EditSchedulePage";
|
||||||
|
import CreateSchedulePage from "./pages/CreateSchedulePage";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
@@ -98,6 +100,8 @@ function App() {
|
|||||||
|
|
||||||
<Route path="schedules">
|
<Route path="schedules">
|
||||||
<Route index element={<ManageSchedulePage />} />
|
<Route index element={<ManageSchedulePage />} />
|
||||||
|
<Route path="create-schedule" element={<CreateSchedulePage />} />
|
||||||
|
<Route path="edit-schedule/:id" element={<EditSchedulePage />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
42
client/src/components/NextUIFormikDatePicker.tsx
Normal file
42
client/src/components/NextUIFormikDatePicker.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { DatePicker } from "@nextui-org/react";
|
||||||
|
import { useField } from "formik";
|
||||||
|
import { CalendarDate, getLocalTimeZone, today } from "@internationalized/date";
|
||||||
|
|
||||||
|
interface NextUIFormikDatePickerProps {
|
||||||
|
label: string;
|
||||||
|
name: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateToCalendarDate = (date: Date): CalendarDate => {
|
||||||
|
return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
||||||
|
};
|
||||||
|
|
||||||
|
// NextUIFormikDatePicker component
|
||||||
|
export const NextUIFormikDatePicker = ({
|
||||||
|
label,
|
||||||
|
...props
|
||||||
|
}: NextUIFormikDatePickerProps) => {
|
||||||
|
const [field, meta, helpers] = useField(props.name);
|
||||||
|
|
||||||
|
const handleChange = (date: CalendarDate | null) => {
|
||||||
|
if (date) {
|
||||||
|
helpers.setValue(date.toDate('UTC')); // Ensure date is converted to a proper Date object with a timezone
|
||||||
|
} else {
|
||||||
|
helpers.setValue(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DatePicker
|
||||||
|
{...props}
|
||||||
|
label={label}
|
||||||
|
value={field.value ? dateToCalendarDate(new Date(field.value)) : null} // Convert field value to CalendarDate
|
||||||
|
onChange={handleChange}
|
||||||
|
isInvalid={meta.touched && !!meta.error}
|
||||||
|
errorMessage={meta.touched && meta.error ? meta.error : ""}
|
||||||
|
minValue={today(getLocalTimeZone())}
|
||||||
|
defaultValue={today(getLocalTimeZone()).subtract({ days: 1 })}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
34
client/src/components/NextUIFormikRadioButton.tsx
Normal file
34
client/src/components/NextUIFormikRadioButton.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { RadioGroup } from "@nextui-org/react";
|
||||||
|
import { useField } from "formik";
|
||||||
|
|
||||||
|
interface NextUIFormikRadioGroupProps {
|
||||||
|
label: string;
|
||||||
|
name: string;
|
||||||
|
className?: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextUIFormikRadioGroup component
|
||||||
|
export const NextUIFormikRadioGroup = ({
|
||||||
|
label,
|
||||||
|
...props
|
||||||
|
}: NextUIFormikRadioGroupProps) => {
|
||||||
|
const [field, meta, helpers] = useField(props.name);
|
||||||
|
|
||||||
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
helpers.setValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RadioGroup
|
||||||
|
{...props}
|
||||||
|
label={label}
|
||||||
|
value={field.value}
|
||||||
|
onChange={handleChange}
|
||||||
|
isInvalid={meta.touched && !!meta.error}
|
||||||
|
errorMessage={meta.touched && meta.error ? meta.error : ""}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</RadioGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
140
client/src/pages/CreateSchedulePage.tsx
Normal file
140
client/src/pages/CreateSchedulePage.tsx
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import { Formik, Form } from "formik";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { Button, Radio } from "@nextui-org/react";
|
||||||
|
import { NextUIFormikRadioGroup } from "../components/NextUIFormikRadioButton";
|
||||||
|
import { NextUIFormikDatePicker } from "../components/NextUIFormikDatePicker";
|
||||||
|
import NextUIFormikInput from "../components/NextUIFormikInput";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import instance from "../security/http";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
// Validation schema
|
||||||
|
const validationSchema = yup.object().shape({
|
||||||
|
date: yup.date().required(),
|
||||||
|
time: yup.string().trim().required(),
|
||||||
|
location: yup.string().trim().min(15).max(50).required(),
|
||||||
|
postalCode: yup.string().matches(/^\d{6}$/, "Postal code must be exactly 6 digits").required(),
|
||||||
|
status: yup.string().trim().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialValues: any = {
|
||||||
|
date: "",
|
||||||
|
time: "",
|
||||||
|
location: "",
|
||||||
|
postalCode: "",
|
||||||
|
status: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CreateSchedulePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleSubmit = (values: any) => {
|
||||||
|
let data = { ...values };
|
||||||
|
|
||||||
|
// Ensure the date is in the correct format
|
||||||
|
const formattedDate = dayjs(data.date).format('YYYY-MM-DD');
|
||||||
|
console.log("Formatted Date:", formattedDate);
|
||||||
|
|
||||||
|
// Ensure the time is in the correct format
|
||||||
|
const formattedTime = data.time.length === 5 ? `${data.time}:00` : data.time;
|
||||||
|
console.log("Formatted Time:", formattedTime);
|
||||||
|
|
||||||
|
// Combine the formatted date and time
|
||||||
|
const dateTimeString = `${formattedDate} ${formattedTime}`;
|
||||||
|
console.log("Combined dateTime string:", dateTimeString);
|
||||||
|
|
||||||
|
// Parse the combined string with dayjs
|
||||||
|
const dateTime = dayjs(dateTimeString, 'YYYY-MM-DD HH:mm:ss');
|
||||||
|
console.log("Parsed dateTime:", dateTime);
|
||||||
|
|
||||||
|
// Check if the parsed dateTime is valid
|
||||||
|
if (!dateTime.isValid()) {
|
||||||
|
console.error("Invalid dateTime format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.dateTime = dateTime.toISOString();
|
||||||
|
|
||||||
|
data.location = data.location.trim();
|
||||||
|
|
||||||
|
if (typeof data.postalCode === 'string') {
|
||||||
|
data.postalCode = data.postalCode.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
data.status = data.status.trim();
|
||||||
|
|
||||||
|
console.log("Data to be sent:", data);
|
||||||
|
|
||||||
|
instance.post("/schedule", data)
|
||||||
|
.then((res) => {
|
||||||
|
console.log(res.data);
|
||||||
|
navigate(-1);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="flex flex-col items-center justify-center gap-20 py-8 md:py-10">
|
||||||
|
<div className="w-full flex items-start">
|
||||||
|
<Button
|
||||||
|
variant="light"
|
||||||
|
onPress={() => navigate(-1)}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<div className="flex-grow text-center">
|
||||||
|
<p className="text-3xl font-bold">Add New Schedule</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{({ isValid, dirty }) => (
|
||||||
|
<Form className="flex flex-col gap-4">
|
||||||
|
<div className="flex gap-8">
|
||||||
|
<NextUIFormikDatePicker
|
||||||
|
label="Date"
|
||||||
|
name="date"
|
||||||
|
className="max-w-[280px]"
|
||||||
|
/>
|
||||||
|
<NextUIFormikInput
|
||||||
|
type='time'
|
||||||
|
label="Time"
|
||||||
|
name="time"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-8">
|
||||||
|
<NextUIFormikInput
|
||||||
|
type="text"
|
||||||
|
label="Location"
|
||||||
|
name="location"
|
||||||
|
placeholder="Enter the location"
|
||||||
|
/>
|
||||||
|
<NextUIFormikInput
|
||||||
|
type="text"
|
||||||
|
label="Postal Code"
|
||||||
|
name="postalCode"
|
||||||
|
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" className="w-[100px]">Create</Button>
|
||||||
|
{/* Example of using isValid and dirty */}
|
||||||
|
<p>Form is {isValid ? 'valid' : 'invalid'}</p>
|
||||||
|
<p>Form has been {dirty ? 'touched' : 'not touched'}</p>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
164
client/src/pages/EditSchedulePage.tsx
Normal file
164
client/src/pages/EditSchedulePage.tsx
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
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 { NextUIFormikDatePicker } from "../components/NextUIFormikDatePicker";
|
||||||
|
import NextUIFormikInput from "../components/NextUIFormikInput";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import instance from "../security/http";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
|
||||||
|
// Validation schema
|
||||||
|
const validationSchema = yup.object().shape({
|
||||||
|
date: yup.date().required(),
|
||||||
|
time: yup.string().trim().required(),
|
||||||
|
location: yup.string().trim().min(15).max(50).required(),
|
||||||
|
postalCode: yup.string().matches(/^\d{6}$/, "Postal code must be exactly 6 digits").required(),
|
||||||
|
status: yup.string().trim().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function EditSchedulePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { id } = useParams();
|
||||||
|
|
||||||
|
const [schedule, setSchedule] = useState<any>({
|
||||||
|
date: "",
|
||||||
|
time: "",
|
||||||
|
location: "",
|
||||||
|
postalCode: "",
|
||||||
|
status: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
instance.get(`/schedule/${id}`).then((res) => {
|
||||||
|
const scheduleData = res.data;
|
||||||
|
|
||||||
|
scheduleData.date = dayjs(scheduleData.dateTime).format("YYYY-MM-DD");
|
||||||
|
scheduleData.time = dayjs(scheduleData.dateTime).format("HH:mm");
|
||||||
|
|
||||||
|
console.log("Fetched schedule data:", scheduleData);
|
||||||
|
setSchedule(scheduleData);
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error("Error fetching schedule:", err);
|
||||||
|
});
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handleSubmit = (values: any) => {
|
||||||
|
let data = { ...values };
|
||||||
|
|
||||||
|
// Ensure the date is in the correct format
|
||||||
|
const formattedDate = dayjs(data.date).format("YYYY-MM-DD");
|
||||||
|
console.log("Formatted Date:", formattedDate);
|
||||||
|
|
||||||
|
// Ensure the time is in the correct format
|
||||||
|
const formattedTime = data.time.length === 5 ? `${data.time}:00` : data.time;
|
||||||
|
console.log("Formatted Time:", formattedTime);
|
||||||
|
|
||||||
|
// Combine the formatted date and time
|
||||||
|
const dateTimeString = `${formattedDate} ${formattedTime}`;
|
||||||
|
console.log("Combined dateTime string:", dateTimeString);
|
||||||
|
|
||||||
|
// Parse the combined string with dayjs
|
||||||
|
const dateTime = dayjs(dateTimeString, "YYYY-MM-DD HH:mm:ss");
|
||||||
|
console.log("Parsed dateTime:", dateTime);
|
||||||
|
|
||||||
|
// Check if the parsed dateTime is valid
|
||||||
|
if (!dateTime.isValid()) {
|
||||||
|
console.error("Invalid dateTime format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.dateTime = dateTime.toISOString();
|
||||||
|
data.location = data.location.trim();
|
||||||
|
|
||||||
|
if (typeof data.postalCode === "string") {
|
||||||
|
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);
|
||||||
|
navigate(-1);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error updating schedule:", error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="flex flex-col items-center justify-center gap-20 py-8 md:py-10">
|
||||||
|
<div className="w-full flex items-start">
|
||||||
|
<Button
|
||||||
|
variant="light"
|
||||||
|
onPress={() => navigate(-1)}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<div className="flex-grow text-center">
|
||||||
|
<p className="text-3xl font-bold">Add New Schedule</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Formik
|
||||||
|
enableReinitialize
|
||||||
|
initialValues={schedule}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{({ isValid, dirty }) => (
|
||||||
|
<Form className="flex flex-col gap-4">
|
||||||
|
<div className="flex gap-8">
|
||||||
|
<NextUIFormikDatePicker
|
||||||
|
label="Date"
|
||||||
|
name="date"
|
||||||
|
className="max-w-[284px]"
|
||||||
|
/>
|
||||||
|
<NextUIFormikInput
|
||||||
|
type='time'
|
||||||
|
label="Time"
|
||||||
|
name="time"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-8">
|
||||||
|
<NextUIFormikInput
|
||||||
|
type="text"
|
||||||
|
label="Location"
|
||||||
|
name="location"
|
||||||
|
placeholder="Enter the location"
|
||||||
|
/>
|
||||||
|
<NextUIFormikInput
|
||||||
|
type="text"
|
||||||
|
label="Postal Code"
|
||||||
|
name="postalCode"
|
||||||
|
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>
|
||||||
|
<div className="flex gap-5">
|
||||||
|
<Button type="submit" color="secondary" className="max-w-[100px]">Update</Button>
|
||||||
|
</div>
|
||||||
|
{/* Example of using isValid and dirty */}
|
||||||
|
<p>Form is {isValid ? 'valid' : 'invalid'}</p>
|
||||||
|
<p>Form has been {dirty ? 'touched' : 'not touched'}</p>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import instance from "../security/http";
|
import instance from "../security/http";
|
||||||
import { PencilSquareIcon, PlusIcon, TrashDeleteIcon } from "../icons";
|
import { PencilSquareIcon, PlusIcon, TrashDeleteIcon } from "../icons";
|
||||||
@@ -13,7 +13,7 @@ interface Schedule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ManageSchedulePage() {
|
export default function ManageSchedulePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
const [scheduleList, setScheduleList] = useState<Schedule[]>([]);
|
const [scheduleList, setScheduleList] = useState<Schedule[]>([]);
|
||||||
const [scheduleIdToDelete, setScheduleIdToDelete] = useState<number | null>(null);
|
const [scheduleIdToDelete, setScheduleIdToDelete] = useState<number | null>(null);
|
||||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||||
@@ -36,6 +36,11 @@ export default function ManageSchedulePage() {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleEdit = (id: number) => {
|
||||||
|
navigate(`edit-schedule/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const deleteSchedule = () => {
|
const deleteSchedule = () => {
|
||||||
if (scheduleIdToDelete !== null) {
|
if (scheduleIdToDelete !== null) {
|
||||||
instance.delete(`/schedule/${scheduleIdToDelete}`)
|
instance.delete(`/schedule/${scheduleIdToDelete}`)
|
||||||
@@ -96,7 +101,11 @@ export default function ManageSchedulePage() {
|
|||||||
<div className="inline-block text-center justify-center flex flex-row gap-10">
|
<div className="inline-block text-center justify-center flex flex-row gap-10">
|
||||||
<p className="text-3xl font-bold">Admin Karang Guni Schedule</p>
|
<p className="text-3xl font-bold">Admin Karang Guni Schedule</p>
|
||||||
<Link to="/Addschedules">
|
<Link to="/Addschedules">
|
||||||
<Button isIconOnly color="primary">
|
<Button
|
||||||
|
isIconOnly
|
||||||
|
color="primary"
|
||||||
|
onPress={() => navigate("create-schedule")}
|
||||||
|
>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -122,8 +131,21 @@ export default function ManageSchedulePage() {
|
|||||||
<TableCell>{schedule.postalCode}</TableCell>
|
<TableCell>{schedule.postalCode}</TableCell>
|
||||||
<TableCell>{schedule.status}</TableCell>
|
<TableCell>{schedule.status}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Link to={`/Editschedules/${schedule.id}`}><Button isIconOnly color="success" variant="light"><PencilSquareIcon /></Button></Link>
|
<Button
|
||||||
<Button isIconOnly color="danger" variant="light" onPress={() => { setScheduleIdToDelete(schedule.id); onOpen(); }}><TrashDeleteIcon /></Button>
|
isIconOnly
|
||||||
|
variant="light"
|
||||||
|
color="success"
|
||||||
|
onPress={() => handleEdit(schedule.id)}
|
||||||
|
>
|
||||||
|
<PencilSquareIcon />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
isIconOnly
|
||||||
|
color="danger"
|
||||||
|
variant="light"
|
||||||
|
onPress={() => { setScheduleIdToDelete(schedule.id); onOpen(); }}>
|
||||||
|
<TrashDeleteIcon />
|
||||||
|
</Button>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -98,26 +98,29 @@ export default function SchedulePage() {
|
|||||||
return (
|
return (
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full">
|
||||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||||
<h1>Karang Guni Schedule</h1>
|
<div className="flex flex-row gap-10">
|
||||||
<div className="flex gap-4">
|
<p className="text-2xl font-bold">Karang Guni Schedule</p>
|
||||||
{/* Search Input */}
|
|
||||||
<Input
|
<div className="flex gap-4">
|
||||||
value={search}
|
{/* Search Input */}
|
||||||
className="w-[400px]"
|
<Input
|
||||||
placeholder="Search Address/Postal"
|
value={search}
|
||||||
onChange={onSearchChange}
|
className="w-[400px]"
|
||||||
onKeyDown={onSearchKeyDown}
|
placeholder="Search"
|
||||||
endContent={
|
onChange={onSearchChange}
|
||||||
<div className="flex flex-row -mr-3">
|
onKeyDown={onSearchKeyDown}
|
||||||
<Button isIconOnly variant="light" onPress={onClickSearch}>
|
endContent={
|
||||||
<MagnifyingGlassIcon />
|
<div className="flex flex-row -mr-3">
|
||||||
</Button>
|
<Button isIconOnly variant="light" onPress={onClickSearch}>
|
||||||
<Button isIconOnly variant="light" onPress={onClickClear}>
|
<MagnifyingGlassIcon />
|
||||||
<XMarkIcon />
|
</Button>
|
||||||
</Button>
|
<Button isIconOnly variant="light" onPress={onClickClear}>
|
||||||
</div>
|
<XMarkIcon />
|
||||||
}
|
</Button>
|
||||||
/>
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-8">
|
<div className="flex flex-col gap-8">
|
||||||
<Table aria-label="Schedule Table">
|
<Table aria-label="Schedule Table">
|
||||||
@@ -145,7 +148,7 @@ export default function SchedulePage() {
|
|||||||
<TableCell>{schedule.location}</TableCell>
|
<TableCell>{schedule.location}</TableCell>
|
||||||
<TableCell>{schedule.postalCode}</TableCell>
|
<TableCell>{schedule.postalCode}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Chip color={getStatusColor(schedule.status)}>
|
<Chip variant="flat" color={getStatusColor(schedule.status)}>
|
||||||
{schedule.status}
|
{schedule.status}
|
||||||
</Chip>
|
</Chip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
Reference in New Issue
Block a user