| display: flex; | display: flex; | ||||
| flex-direction: column; | flex-direction: column; | ||||
| height: 143px; | height: 143px; | ||||
| width: 177px; | |||||
| width: 178px; | |||||
| border: 1px solid #f4f4f4; | border: 1px solid #f4f4f4; | ||||
| padding: 17px; | padding: 17px; | ||||
| transition: 0.5s; | transition: 0.5s; | ||||
| .day-component-container:hover{ | .day-component-container:hover{ | ||||
| cursor: pointer; | cursor: pointer; | ||||
| scale: 1.03; | |||||
| scale: 1.02; | |||||
| animation-timing-function: ease-in-out; | animation-timing-function: ease-in-out; | ||||
| animation-duration: 300ms; | animation-duration: 300ms; | ||||
| } | } |
| cursor: pointer; | cursor: pointer; | ||||
| } | } | ||||
| .day-datails-arrow-container-p { | |||||
| display: flex; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 7px; | |||||
| width: 36px; | |||||
| height: 36px; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| cursor: pointer; | |||||
| transform: rotate(-180deg); | |||||
| } | |||||
| @media only screen and (max-width: 361px) { | @media only screen and (max-width: 361px) { | ||||
| .day-details-applicant { | .day-details-applicant { | ||||
| margin-left: 10px; | margin-left: 10px; | ||||
| } | } | ||||
| .day-details-sub-container { | .day-details-sub-container { | ||||
| //padding-top: 36px; | |||||
| padding: 32px; | padding: 32px; | ||||
| } | } | ||||
| .day-details-link { | .day-details-link { | ||||
| } | } | ||||
| .day-details-name { | .day-details-name { | ||||
| width: 66px; | width: 66px; | ||||
| //width: 86px; | |||||
| } | } | ||||
| .day-details-applicant { | .day-details-applicant { | ||||
| width: 97px; | width: 97px; | ||||
| //width: 117px; | |||||
| } | } | ||||
| .day-details-close-btn { | .day-details-close-btn { | ||||
| margin-left: 12px; | margin-left: 12px; |
| .schedule-page-container{ | |||||
| display: flex; | |||||
| } | |||||
| .schedule-page-container { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| padding-bottom: 46px; | |||||
| overflow-x: auto; | |||||
| } | |||||
| .schedule-page-main-header { | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 36px; | |||||
| font-weight: 600; | |||||
| line-height: 36px; | |||||
| letter-spacing: 0.02em; | |||||
| text-align: left; | |||||
| } | |||||
| .schedule-page-header { | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 24px; | |||||
| font-weight: 600; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| text-align: left; | |||||
| color: #226cb0; | |||||
| align-self: flex-end; | |||||
| margin-left: 5px; | |||||
| } | |||||
| .schedule-page-arrows-container { | |||||
| display: flex; | |||||
| gap: 18px; | |||||
| margin-top: 32px; | |||||
| } | |||||
| .schedule-page-arrow-container { | |||||
| display: flex; | |||||
| height: 45px; | |||||
| width: 45px; | |||||
| border-radius: 9px; | |||||
| border: 1px solid #e4e4e4; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| cursor: pointer; | |||||
| } | |||||
| .schedule-page-content-container { | |||||
| display: grid; | |||||
| grid-template-columns: auto auto auto auto auto auto auto; | |||||
| padding-top: 18px; | |||||
| padding-right: 59px; | |||||
| padding-bottom: 10px; | |||||
| grid-gap: 0px; | |||||
| width: 1305px; | |||||
| } | |||||
| @media only screen and (max-width: 361px) { | |||||
| .schedule-page-main-header { | |||||
| font-size: 18px; | |||||
| } | |||||
| .schedule-page-header{ | |||||
| font-size: 14px; | |||||
| } | |||||
| .schedule-page-arrow-container{ | |||||
| width: 36px; | |||||
| height: 36px; | |||||
| } | |||||
| .schedule-page-content-container{ | |||||
| padding-right: 36px; | |||||
| width: 1250px; | |||||
| } | |||||
| } |
| import React from "react"; | |||||
| import React, { useEffect, useState } from "react"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import { | |||||
| Dialog, | |||||
| DialogContent, | |||||
| DialogTitle, | |||||
| // useMediaQuery, | |||||
| // useTheme, | |||||
| } from "@mui/material"; | |||||
| import { Dialog, DialogContent, DialogTitle } from "@mui/material"; | |||||
| import calendar from "../../../src/assets/images/calendar2.png"; | import calendar from "../../../src/assets/images/calendar2.png"; | ||||
| import arrowLeft from "../../../src/assets/images/arrow_left.png"; | |||||
| import arrowLeftDisabled from "../../../src/assets/images/arrow_left.png"; | |||||
| import arrowLeft from "../../../src/assets/images/arrow_left2.png"; | |||||
| import arrowRight from "../../../src/assets/images/arrow_right.png"; | import arrowRight from "../../../src/assets/images/arrow_right.png"; | ||||
| import x from "../../../src/assets/images/x.png"; | import x from "../../../src/assets/images/x.png"; | ||||
| import meet from "../../../src/assets/images/meet.png"; | import meet from "../../../src/assets/images/meet.png"; | ||||
| selectionProcesses, | selectionProcesses, | ||||
| open, | open, | ||||
| onClose, | onClose, | ||||
| setCurrentlySelected, | |||||
| setCurrentlySelectedDay, | |||||
| currentlySelectedDay, | |||||
| numberOfDaysInMonth, | |||||
| }) => { | }) => { | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matches = useMediaQuery(theme.breakpoints.down("361")); | const matches = useMediaQuery(theme.breakpoints.down("361")); | ||||
| const [isLeftArrowDisabled, setIsLeftArrowDisabled] = useState( | |||||
| currentlySelectedDay === 1 ? true : false | |||||
| ); | |||||
| const [isRightArrowDisabled, setIsRightArrowDisabled] = useState( | |||||
| currentlySelectedDay === 1 ? true : false | |||||
| ); | |||||
| const handleClose = () => { | const handleClose = () => { | ||||
| onClose(); | onClose(); | ||||
| }; | }; | ||||
| useEffect(() => { | |||||
| console.log(numberOfDaysInMonth); | |||||
| setIsLeftArrowDisabled(currentlySelectedDay === 1 ? true : false); | |||||
| setIsRightArrowDisabled( | |||||
| currentlySelectedDay === numberOfDaysInMonth ? true : false | |||||
| ); | |||||
| }, [currentlySelectedDay, isLeftArrowDisabled, isRightArrowDisabled]); | |||||
| const goForwardOneDay = () => { | |||||
| const date = selectedDate.split("."); | |||||
| const day = date[0]; | |||||
| const month = date[1]; | |||||
| const year = date[2]; | |||||
| const newDay = parseInt(day) + 1; | |||||
| if (day === numberOfDaysInMonth) { | |||||
| setIsRightArrowDisabled(true); | |||||
| return; | |||||
| } | |||||
| setCurrentlySelected(newDay + "." + month + "." + year); | |||||
| setCurrentlySelectedDay(newDay); | |||||
| setIsLeftArrowDisabled(true); | |||||
| }; | |||||
| const goBackOneDay = () => { | |||||
| const date = selectedDate.split("."); | |||||
| const day = date[0]; | |||||
| const month = date[1]; | |||||
| const year = date[2]; | |||||
| if (day === 1) { | |||||
| setIsLeftArrowDisabled(true); | |||||
| return; | |||||
| } | |||||
| const newDay = parseInt(day) - 1; | |||||
| setCurrentlySelected(newDay + "." + month + "." + year); | |||||
| setCurrentlySelectedDay(newDay); | |||||
| }; | |||||
| return ( | return ( | ||||
| <Dialog | <Dialog | ||||
| onClose={handleClose} | onClose={handleClose} | ||||
| open={open} | open={open} | ||||
| maxWidth={!matches ? 549 : 339} | |||||
| maxWidth={!matches ? "549" : "339"} | |||||
| > | > | ||||
| <div className="day-details-sub-container"> | <div className="day-details-sub-container"> | ||||
| <DialogTitle className="day-datails-title-container"> | <DialogTitle className="day-datails-title-container"> | ||||
| <p className="day-details-time"> | <p className="day-details-time"> | ||||
| {formatTimeSrb(selectionProcess.date)}h | {formatTimeSrb(selectionProcess.date)}h | ||||
| </p> | </p> | ||||
| <div style={{display:'flex',alignItems:!matches ? 'center' : 'flex-start',flexDirection:!matches ? 'row' : 'column'}}> | |||||
| <div | |||||
| style={{ | |||||
| display: "flex", | |||||
| alignItems: !matches ? "center" : "flex-start", | |||||
| flexDirection: !matches ? "row" : "column", | |||||
| }} | |||||
| > | |||||
| <p className="day-details-name"> | <p className="day-details-name"> | ||||
| {selectionProcess.selectionLevel.name} | {selectionProcess.selectionLevel.name} | ||||
| </p> | </p> | ||||
| <Link | <Link | ||||
| className="day-details-applicant" | className="day-details-applicant" | ||||
| to={CANDIDATES_PAGE + "/" + selectionProcess.applicant.applicantId} | |||||
| to={ | |||||
| CANDIDATES_PAGE + | |||||
| "/" + | |||||
| selectionProcess.applicant.applicantId | |||||
| } | |||||
| > | > | ||||
| {selectionProcess.applicant.firstName}{" "} | {selectionProcess.applicant.firstName}{" "} | ||||
| {selectionProcess.applicant.lastName} | {selectionProcess.applicant.lastName} | ||||
| </div> | </div> | ||||
| ))} | ))} | ||||
| </div> | </div> | ||||
| <div style={{ display: "flex", gap: "18px" }}> | |||||
| <div className="day-datails-arrow-container"> | |||||
| <img src={arrowLeft} /> | |||||
| </div> | |||||
| <div className="day-datails-arrow-container"> | |||||
| <img src={arrowRight} /> | |||||
| </div> | |||||
| <div | |||||
| style={{ | |||||
| display: "flex", | |||||
| gap: "18px", | |||||
| marginTop: selectionProcesses.length === 0 ? "18px" : "0px", | |||||
| }} | |||||
| > | |||||
| {isLeftArrowDisabled === true ? ( | |||||
| <div className="day-datails-arrow-container"> | |||||
| <img src={arrowLeftDisabled} /> | |||||
| </div> | |||||
| ) : ( | |||||
| <div | |||||
| className="day-datails-arrow-container" | |||||
| onClick={goBackOneDay} | |||||
| > | |||||
| <img src={arrowLeft} /> | |||||
| </div> | |||||
| )} | |||||
| {isRightArrowDisabled === true ? ( | |||||
| <div className="day-datails-arrow-container-p"> | |||||
| <img src={arrowLeftDisabled} /> | |||||
| </div> | |||||
| ) : ( | |||||
| <div | |||||
| className="day-datails-arrow-container" | |||||
| onClick={goForwardOneDay} | |||||
| > | |||||
| <img src={arrowRight} /> | |||||
| </div> | |||||
| )} | |||||
| </div> | </div> | ||||
| </DialogContent> | </DialogContent> | ||||
| </div> | </div> | ||||
| selectionProcesses: PropTypes.array, | selectionProcesses: PropTypes.array, | ||||
| open: PropTypes.bool, | open: PropTypes.bool, | ||||
| onClose: PropTypes.func, | onClose: PropTypes.func, | ||||
| setCurrentlySelected: PropTypes.func, | |||||
| setCurrentlySelectedDay: PropTypes.func, | |||||
| currentlySelectedDay: PropTypes.number, | |||||
| numberOfDaysInMonth: PropTypes.number, | |||||
| }; | }; | ||||
| export default DayDetailsComponent; | export default DayDetailsComponent; |
| @import './assets/styles/components/rules'; | @import './assets/styles/components/rules'; | ||||
| @import './assets/styles/components/nav'; | @import './assets/styles/components/nav'; | ||||
| @import './assets/styles/components/ads'; | @import './assets/styles/components/ads'; | ||||
| @import './assets/styles/components/schedulePage'; | |||||
| @import './assets/styles/components/day-component'; | @import './assets/styles/components/day-component'; | ||||
| @import './assets/styles/components/day-details-component'; | @import './assets/styles/components/day-details-component'; | ||||
| @import './assets/styles/layout'; | @import './assets/styles/layout'; |
| import React, { useState } from "react"; | import React, { useState } from "react"; | ||||
| import DayComponent from "../../components/Schedules/DayComponent"; | import DayComponent from "../../components/Schedules/DayComponent"; | ||||
| import arrowRight from "../../assets/images/arrow_right.png"; | |||||
| import arrowLeft from "../../assets/images/arrow_left2.png"; | |||||
| import DayDetailsComponent from "../../components/Schedules/DayDetailsComponent"; | import DayDetailsComponent from "../../components/Schedules/DayDetailsComponent"; | ||||
| import { | |||||
| getMonthString, | |||||
| getDayString, | |||||
| getFormatedDayOrMonth, | |||||
| } from "../../util/helpers/dateHelpers"; | |||||
| const SchedulePage = () => { | const SchedulePage = () => { | ||||
| const [detailDialogShown, setDetailsDialogShown] = useState(false); | const [detailDialogShown, setDetailsDialogShown] = useState(false); | ||||
| const [currentMonth, setCurrentMonth] = useState(new Date().getMonth()); | |||||
| const [currentYear, setCurrentYear] = useState(new Date().getFullYear()); | |||||
| const [numberOfDaysInMonth, setNumberOfDaysInMonth] = useState( | |||||
| new Date(currentYear, currentMonth + 1, 0).getDate() | |||||
| ); | |||||
| const [currentlySelectedDate, setCurrentlySelectedDate] = useState(""); | |||||
| const [currentlySelectedDay, setCurrentlySelectedDay] = useState(0); | |||||
| // array will contain number of days of current month | |||||
| const makeArray = () => { | |||||
| let count = 0; | |||||
| let arr = []; | |||||
| while (count !== numberOfDaysInMonth) { | |||||
| arr.push(count); | |||||
| count += 1; | |||||
| } | |||||
| return arr; | |||||
| }; | |||||
| const handleCloseDialog = () => { | const handleCloseDialog = () => { | ||||
| setDetailsDialogShown(false); | setDetailsDialogShown(false); | ||||
| }; | }; | ||||
| const handleOpenDialog = () => { | |||||
| setDetailsDialogShown(true) | |||||
| } | |||||
| const handleOpenDialog = (numberOfDay) => { | |||||
| setCurrentlySelectedDay(numberOfDay); | |||||
| setCurrentlySelectedDate( | |||||
| getFormatedDayOrMonth(numberOfDay) + | |||||
| "." + | |||||
| getFormatedDayOrMonth(currentMonth + 1) + | |||||
| "." + | |||||
| currentYear | |||||
| ); | |||||
| setDetailsDialogShown(true); | |||||
| }; | |||||
| const getSelectionProcessesForSpecificDay = (day) => { | |||||
| return selectionProcesses.filter( | |||||
| (k) => | |||||
| new Date(k.date).getDate() === day && | |||||
| new Date(k.date).getFullYear() === currentYear && | |||||
| new Date(k.date).getMonth() === currentMonth | |||||
| ); | |||||
| }; | |||||
| const goBackOneMonth = () => { | |||||
| setNumberOfDaysInMonth( | |||||
| new Date( | |||||
| currentMonth - 1 === -1 ? currentYear - 1 : currentYear, | |||||
| currentMonth - 1 === -1 ? 12 : currentMonth, | |||||
| 0 | |||||
| ).getDate() | |||||
| ); | |||||
| if (currentMonth - 1 === -1) { | |||||
| setCurrentMonth(11); | |||||
| setCurrentYear(currentYear - 1); | |||||
| } else { | |||||
| setCurrentMonth(currentMonth - 1); | |||||
| } | |||||
| }; | |||||
| const goForwardOneMonth = () => { | |||||
| setNumberOfDaysInMonth( | |||||
| new Date( | |||||
| currentMonth + 1 === 12 ? currentYear + 1 : currentYear, | |||||
| currentMonth + 1 === 12 ? 1 : currentMonth + 2, | |||||
| 0 | |||||
| ).getDate() | |||||
| ); | |||||
| if (currentMonth + 1 === 12) { | |||||
| setCurrentMonth(0); | |||||
| setCurrentYear(currentYear + 1); | |||||
| } else { | |||||
| setCurrentMonth(currentMonth + 1); | |||||
| } | |||||
| }; | |||||
| const selectionProcesses = [ | const selectionProcesses = [ | ||||
| { | { | ||||
| date: "2022-11-05T14:30:00", | |||||
| date: "2022-12-05T14:30:00", | |||||
| link: "some link", | link: "some link", | ||||
| selectionLevel: { | selectionLevel: { | ||||
| id: 3, | id: 3, | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| date: "2022-11-27T15:30:00", | |||||
| date: "2022-12-27T15:30:00", | |||||
| link: "some link", | link: "some link", | ||||
| selectionLevel: { | selectionLevel: { | ||||
| id: 4, | id: 4, | ||||
| }, | }, | ||||
| ]; | ]; | ||||
| return ( | return ( | ||||
| <div className="schedule-page-container"> | |||||
| <DayDetailsComponent | |||||
| onClose={handleCloseDialog} | |||||
| open={detailDialogShown} | |||||
| selectedDate="12.03.2022" | |||||
| selectionProcesses={selectionProcesses} | |||||
| /> | |||||
| <DayComponent numberOfDay={1} nameOfDay="sre" interviews={selectionProcesses} onClick={handleOpenDialog}/> | |||||
| <div className="schedule-page-container pl-144 pt-36px"> | |||||
| <DayDetailsComponent | |||||
| onClose={handleCloseDialog} | |||||
| open={detailDialogShown} | |||||
| selectedDate={currentlySelectedDate} | |||||
| selectionProcesses={getSelectionProcessesForSpecificDay( | |||||
| currentlySelectedDay | |||||
| )} | |||||
| numberOfDaysInMonth={numberOfDaysInMonth} | |||||
| setCurrentlySelected={setCurrentlySelectedDate} | |||||
| setCurrentlySelectedDay={setCurrentlySelectedDay} | |||||
| currentlySelectedDay={currentlySelectedDay} | |||||
| /> | |||||
| <div> | |||||
| <p className="schedule-page-main-header">Planer aktivnosti</p> | |||||
| <p className="schedule-page-header"> | |||||
| | {getMonthString(currentMonth)} {currentYear} | |||||
| </p> | |||||
| </div> | |||||
| <div className="schedule-page-arrows-container"> | |||||
| <div className="schedule-page-arrow-container" onClick={goBackOneMonth}> | |||||
| <img src={arrowLeft} /> | |||||
| </div> | |||||
| <div | |||||
| className="schedule-page-arrow-container" | |||||
| onClick={goForwardOneMonth} | |||||
| > | |||||
| <img src={arrowRight} /> | |||||
| </div> | |||||
| </div> | |||||
| <div className="schedule-page-content-container"> | |||||
| {makeArray().map((numberOfDay, index) => ( | |||||
| <DayComponent | |||||
| key={index} | |||||
| numberOfDay={numberOfDay + 1} | |||||
| nameOfDay={getDayString(numberOfDay % 7) | |||||
| .toLowerCase() | |||||
| .slice(0, 3)} | |||||
| interviews={getSelectionProcessesForSpecificDay(numberOfDay + 1)} | |||||
| onClick={() => handleOpenDialog(numberOfDay + 1)} | |||||
| /> | |||||
| ))} | |||||
| </div> | </div> | ||||
| </div> | |||||
| ); | ); | ||||
| }; | }; | ||||
| export function formatTimeSrb(date) { | export function formatTimeSrb(date) { | ||||
| const dt = new Date(date); | const dt = new Date(date); | ||||
| return format(dt, 'HH:mm'); | return format(dt, 'HH:mm'); | ||||
| } | |||||
| export function getMonthString(numberOfMonth) { | |||||
| let month = ""; | |||||
| switch (numberOfMonth) { | |||||
| case 0: | |||||
| month = "Januar"; | |||||
| break; | |||||
| case 1: | |||||
| month = "Februar"; | |||||
| break; | |||||
| case 2: | |||||
| month = "Mart"; | |||||
| break; | |||||
| case 3: | |||||
| month = "April"; | |||||
| break; | |||||
| case 4: | |||||
| month = "Maj"; | |||||
| break; | |||||
| case 5: | |||||
| month = "Jun"; | |||||
| break; | |||||
| case 6: | |||||
| month = "Jul"; | |||||
| break; | |||||
| case 7: | |||||
| month = "Avgust"; | |||||
| break; | |||||
| case 8: | |||||
| month = "Septembar"; | |||||
| break; | |||||
| case 9: | |||||
| month = "Oktobar"; | |||||
| break; | |||||
| case 10: | |||||
| month = "Novembar"; | |||||
| break; | |||||
| case 11: | |||||
| month = "Decembar"; | |||||
| break; | |||||
| default: | |||||
| month = "Neispravan mesec"; | |||||
| break; | |||||
| } | |||||
| return month; | |||||
| } | |||||
| export function getDayString(dayOfWeek) { | |||||
| let day = ""; | |||||
| switch (dayOfWeek) { | |||||
| case 0: | |||||
| day = "Ponedeljak"; | |||||
| break; | |||||
| case 1: | |||||
| day = "Utorak"; | |||||
| break; | |||||
| case 2: | |||||
| day = "Sreda"; | |||||
| break; | |||||
| case 3: | |||||
| day = "Cetvrtak"; | |||||
| break; | |||||
| case 4: | |||||
| day = "Petak"; | |||||
| break; | |||||
| case 5: | |||||
| day = "Subota"; | |||||
| break; | |||||
| case 6: | |||||
| day = "Nedelja"; | |||||
| break; | |||||
| } | |||||
| return day; | |||||
| } | |||||
| export function getFormatedDayOrMonth(dayNumber) { | |||||
| return dayNumber <= 9 ? "0" + dayNumber : dayNumber; | |||||
| } | } |