Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions client/src/components/ClassDetail.css
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
.class_detail_container {
/* position: absolute;
top: 30%;
left: 15%;
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888; */
background-color: #fefefe;
margin: auto;
background-color: #f6f7fc;
position: relative;
margin: 0 auto;
padding: 20px;
border: 1px solid #888;
width: 40%;
height: 20%;
}

.class_detail_close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
position: absolute;
top: 3%;
right: 5%;
cursor: pointer;
}

Expand All @@ -29,11 +26,18 @@
.class_calendar_icon {
display: inline-block;
width: 30px;
height: 30px;
height: 20px;
margin-bottom: 15px;
}

.class_description_icon {
display: inline-block;
width: 30px;
height: 30px;
height: 20px;
}

.class_time_icon {
display: inline-block;
width: 30px;
height: 20px;
}
35 changes: 9 additions & 26 deletions client/src/components/ClassDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,28 @@ import './ClassDetail.css';
import { BsFillPeopleFill } from 'react-icons/bs';
import {AiFillCalendar} from 'react-icons/ai';
import {FaStickyNote} from 'react-icons/fa';
import {DAYS, MONTHS} from '../CONSTANT.js';
import {BiTimeFive} from "react-icons/bi";
import moment from 'moment'

const ClassDetail = (props) => {
const navigate = useNavigate();

const [day, setDay] = useState('');
const [month, setMonth] = useState('');
const [startTime, setStartTime] = useState('');
const [endTime, setEndTime] = useState('');

useEffect(() => {
changeFormat();
})

const changeFormat = () => {
const formattedDate = new Date(props.currentDetailClass.startDate).toString();
const formattedDay = DAYS[formattedDate.slice(0, 3)];
const formatteMonth = MONTHS[formattedDate.slice(4, 7)];
const formatteStartTime = props.currentDetailClass.startTime.slice(0, -6);
const formattedEndTime = props.currentDetailClass.endTime.slice(0, -6);

setDay(formattedDay);
setMonth(formatteMonth);
setStartTime(formatteStartTime);
setEndTime(formattedEndTime);
}

return (
<div className="class_detail_container">
<span className="class_detail_close" onClick={props.closeClassDetail}>&times;</span>
<h2>
<span className="class_student_icon"><BsFillPeopleFill /></span>
{props.currentDetailClass.name}
{props.name}
</h2>
<div><span className="class_calendar_icon"><AiFillCalendar /></span>
{day}, {month} {props.currentDetailClass.day.date} ・ {startTime} - {endTime}
{moment(props.startDate).format('MMMM Do YYYY')}
</div>
<div>
<span className="class_time_icon"><BiTimeFive /></span>
{`${moment(props.startDate).format('LT')} - ${moment(props.endDate).format('LT')}`}
</div>
<p><span className="class_description_icon"><FaStickyNote /></span>
{props.currentDetailClass.description}
{props.description}
</p>
</div>
)
Expand Down
1 change: 0 additions & 1 deletion client/src/components/PopUp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const PopUp = (props) => {
const res = await axios.put("/student", formData, {
headers: { "Content-Type": "multipart/form-data" },
});
console.log(res);

if (res.status === 204) {
props.getStudents();
Expand Down
41 changes: 26 additions & 15 deletions client/src/components/PopUpEvent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@ const PopUpEvent = (props) => {

const scheduleClass = async (e) => {
e.preventDefault();
const name = e.target[0].value.slice(0, e.target[0].value.indexOf('(') - 1);
const email = e.target[0].value.slice(e.target[0].value.indexOf('(') + 1, e.target[0].value.length - 1);
const startTime = e.target[1].value;
const endTime = e.target[2].value;

const date = `${props.currentShownSchedule.year}:${props.currentShownSchedule.month}:${props.currentShownSchedule.date}`;
const startTime = e.target[0].value;
const endTime = e.target[1].value;
const name = e.target[2].value;
const description = e.target[3].value;

const year = props.currentShownSchedule.year;
const month = (props.currentShownSchedule.month < 10) ? '0' + props.currentShownSchedule.month : props.currentShownSchedule.month;
const date = (props.currentShownSchedule.date < 10) ? '0' + props.currentShownSchedule.date : props.currentShownSchedule.date;

const startDateInTimeStamp = `${year}-${month}-${date} ${startTime}:00`;
const endDateInTimeStamp = `${year}-${month}-${date} ${endTime}:00`;

const startDateTime = moment().format(`${date} ${startTime}:00`);
const endDateTime = moment().format(`${date} ${endTime}:00`);

if (startTime > endTime) {
setScheduleError("Time Error");
if (checkDateError(startDateInTimeStamp, endDateInTimeStamp)) {
setScheduleError('Error in date');
return;
}

axios
.post("/schedule", {
start: startDateTime,
end: endDateTime,
name: name,
description: description,
email: email,
startDate: startDateInTimeStamp,
endDate: endDateInTimeStamp,
description: e.target[3].value
})
.then((res) => {
if (res.status === 200) {
Expand All @@ -42,6 +46,11 @@ const PopUpEvent = (props) => {
});
};

const checkDateError = (start, end) => {
let currentTime = moment().format('YYYY-MM-DD hh:mm:ss');
return start > end || start < currentTime || end < currentTime;
}

return (
<div className="popup_event_container">
<h2 className="popup_event_title">Schedule a class</h2>
Expand All @@ -56,8 +65,10 @@ const PopUpEvent = (props) => {
<section className="popup_event_section">
<label htmlFor="name">Student name</label>
<select name="name" id="name">
{props.students.map((student) => (
<option key={student.name} value={student.name}>{student.name}</option>
<option>select</option>
{props.students.map((student, index) => (
// <option key={index}>{student.firstName} {student.lastName} {`(${student.email})`}</option>
<option key={index}>{`${student.firstName} ${student.lastName} (${student.email})`}</option>
))}
</select>
</section>
Expand Down
10 changes: 10 additions & 0 deletions client/src/components/Schedule.css
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,14 @@

.schedule_go_back_button:hover {
background-color: #04AA6D;
}

.class_detail {
cursor: pointer;
transition-duration: 0.4s;
}

.class_detail:hover {
color: #fff;
background-color: #3096CC;
}
133 changes: 57 additions & 76 deletions client/src/components/Schedule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ let month = today.getMonth();

const Schedule = (props) => {
const [calendar, setCalendar] = useState([]);
const [testData, setTestData] = useState([]);
const [classes, setClasses] = useState([]);
const [scheduleClassShown, setScheduleClassShown] = useState(false);
const [noClassScheduled, setNoClassScheduled] = useState(false);
const [classDetailShown, setClassDetailShown] = useState(false);
const [currentDetailClass, setCurrentDetailClass] = useState({});
const [currentShownSchedule, setCurrentShownSchedule] = useState({});
const duringPopUp = scheduleClassShown ? "during-popup" : "";
const duringPopUp2 = classDetailShown ? "during-popup_2" : "";
const [className, setClassName] = useState("");
const [classDate, setClassDate] = useState();

const navigate = useNavigate();

Expand Down Expand Up @@ -113,7 +114,8 @@ const Schedule = (props) => {
showCalendar();
};

const setEvent = (year, month, date) => {
const setEvent = (e, year, month, date) => {
setClassName(e.target.className);
const event = {
year: year,
month: month + 1,
Expand All @@ -127,48 +129,24 @@ const Schedule = (props) => {
setScheduleClassShown(false);
};

const closeClassDetail = (e) => {
e.stopPropagation();
setClassDetailShown(false);
const showClassDetail = (date) => {
setClassDetailShown(true);
setClassDate(date);
};

const getSchedule = async () => {
const response = await axios.get("/schedule");
const data = response.data; // UTC

let array = [];
data.forEach((x) => {
let subObj = {};
subObj["name"] = x.name;
subObj["start_time"] = new Date(x.start_time).toLocaleString();
subObj["end_time"] = new Date(x.end_time).toLocaleString();
subObj["description"] = x.description;
array.push(subObj);
const data = response.data;
data.map((d) => {
d["start_date"] = new Date(d["start_date"]).toString();
d["end_date"] = new Date(d["end_date"]).toString();
});

setTestData(array);
setClasses(data);
};

const showClassDetail = (
e,
name,
day,
startDate,
startTime,
endTime,
description
) => {
e.stopPropagation(); // prevent parent function's execution
const format = {
name: name,
day: day,
startDate: startDate,
startTime: startTime,
endTime: endTime,
description: description,
};
setCurrentDetailClass(format);
setClassDetailShown(true);
const closeClassDetail = () => {
setClassDetailShown(false);
};

return (
Expand Down Expand Up @@ -198,50 +176,53 @@ const Schedule = (props) => {
{days.map((day) => (
<th className="schedule_day" key={day}>
{day}
</th> /** Map Mon - Sun */
</th>
))}
</tr>
</thead>
<tbody>
{calendar.map((week) => {
// console.log("week: ", week);
return (
<tr className="schedule_week">
{week.map((day) => (
<td
className="schedule_date"
onClick={() => setEvent(year, day["month"], day["date"])}
onClick={(e) =>
setEvent(e, year, day["month"], day["date"])
}
>
<span className="schedule_date_text">{day.date}</span>
{testData.map((t, idx) => {
// console.log("t: ", t);
const startDate = t["start_time"].split(",")[0]; // 12/19/2022
if (startDate.split("/")[1] === day.date.toString()) {
const name = t["name"];
const year = startDate.split("/")[2];
const month = startDate.split("/")[0];
const startTime = t["start_time"].split(",")[1];
const endTime = t["end_time"].split(",")[1];
const description = t["description"];

{classes.map((t, idx) => {
const startDate = new Date(t["start_date"]);
const endDate = new Date(t["end_date"]);

if (
day.year === startDate.getFullYear() &&
day.month + 1 === startDate.getMonth() + 1 &&
day.date === startDate.getDate()
) {
return (
<div>
{day.year.toString() === year && (day.month + 1).toString() === month &&
<div className="schedule_class">
{`${startTime.slice(0, -6)} - ${name}`}
{classDetailShown &&
currentDetailClass.day === day && (
<div className={duringPopUp2}>
<ClassDetail
currentDetailClass={currentDetailClass}
closeClassDetail={closeClassDetail}
/>
</div>
)}
</div>
}
<div
className="class_detail"
onClick={() => showClassDetail(day.date)}
>
{`${t["student_name"]} ${startDate.getHours()}:${startDate.getMinutes()} - ${endDate.getHours()}:${endDate.getMinutes()}`}
{classDetailShown &&
className === "class_detail" &&
classDate === day.date && (
<div className={duringPopUp2}>
<ClassDetail
closeClassDetail={closeClassDetail}
name={t['student_name']}
date={day.date}
description={t['description']}
startDate={startDate}
endDate={endDate}
/>
</div>
)}
</div>
)
);
}
})}
</td>
Expand All @@ -251,17 +232,17 @@ const Schedule = (props) => {
})}
</tbody>
</table>
<div className={duringPopUp}>
{scheduleClassShown && (
<PopUpEvent
currentShownSchedule={currentShownSchedule}
closeEvent={closeEvent}
getSchedule={getSchedule}
students={props.students}
/>
{scheduleClassShown && className === "schedule_date" && (
<div className={duringPopUp}>
<PopUpEvent
currentShownSchedule={currentShownSchedule}
closeEvent={closeEvent}
getSchedule={getSchedule}
students={props.students}
/>
</div>
)}
</div>
</div>
);
};

Expand Down
Loading