dropdown+scheduler

This commit is contained in:
wrzesinski-hubert 2020-07-20 17:53:50 +02:00
parent 5b24b5fd59
commit f95c8d450d
12 changed files with 204 additions and 123 deletions

View File

@ -7,9 +7,8 @@ body {
} }
.wraper{ .wraper{
display: flex; display: flex;
&__rightbar{ &__calendar{
width: 80%; flex-grow: 3;
} }
} }

View File

@ -2,8 +2,7 @@ import React, { useState } from "react";
import TopBar from "./components/TopBar/"; import TopBar from "./components/TopBar/";
import Transfer from "./components/Transfer/"; import Transfer from "./components/Transfer/";
import "./App.scss"; import "./App.scss";
import Schedule from "./components/Calendar/"; import {Scheduler} from "./components/Scheduler";
import { appointments } from "./components/Calendar/appointments";
import RightBar from "./components/RightBar"; import RightBar from "./components/RightBar";
import { lectures } from "./lectures"; import { lectures } from "./lectures";
@ -39,7 +38,7 @@ function App() {
/> />
<div className="wraper"> <div className="wraper">
<div className="wraper__calendar"> <div className="wraper__calendar">
<Schedule data={appointments} /> <Scheduler />
</div> </div>
<div className="wraper__rightbar"> <div className="wraper__rightbar">
<RightBar <RightBar

View File

@ -1,30 +0,0 @@
export const appointments = [
{
title: 'E-gospodarka - narzędzia i bezpieczeństwo',
startDate: new Date(2020, 5, 3, 9, 45),
endDate: new Date(2020, 5, 3, 11, 30),
id: 0,
location: 'Room 1',
},
{
title: 'Algorytmy grafowe',
startDate: new Date(2020, 5, 1, 9, 45),
endDate: new Date(2020, 5, 1, 11, 30),
id: 0,
location: 'Room 1',
},
{
title: 'Podstawy programowania deklaratywnego',
startDate: new Date(2020, 5, 1, 9, 45),
endDate: new Date(2020, 5, 1, 11, 30),
id: 0,
location: 'Room 1',
},
{
title: 'Statystyka',
startDate: new Date(2020, 5, 1, 18, 45),
endDate: new Date(2020, 5, 1, 20, 0),
id: 0,
location: 'Room 1',
},
];

View File

@ -1,87 +0,0 @@
import * as React from "react";
import { ViewState } from "@devexpress/dx-react-scheduler";
import { AppointmentModel } from "@devexpress/dx-react-scheduler";
import { Scheduler, WeekView, Appointments, AppointmentTooltip } from "@devexpress/dx-react-scheduler-material-ui";
import moment from "moment";
import "moment/locale/pl";
import "./index.scss";
import { makeStyles, createStyles } from "@material-ui/core/styles";
interface CalendarProps {
data: Array<AppointmentModel>;
}
interface CalendarState {
currentDate: Date;
}
const formatDayScaleDate = (date: moment.MomentInput, nextOptions: Intl.DateTimeFormatOptions): string => {
const momentDate = moment(date).locale("pl");
return momentDate.format(nextOptions.weekday ? "dddd" : " ").toUpperCase();
};
const useStyles = makeStyles(() =>
createStyles({
dayScaleCell: {
paddingTop: 10,
paddingBottom: 10,
},
timeTableLayout: {
border: "1px solid rgba(224, 224, 224, 1);",
borderCollapse: "separate",
},
appointmentLayer: {
borderRadius: 15,
marginLeft: 5,
textAlign: "center",
},
})
);
const DayScaleCell = ({ formatDate, ...restProps }: WeekView.DayScaleCellProps) => {
const classes = useStyles();
return (
<WeekView.DayScaleCell {...restProps} formatDate={formatDayScaleDate} today={false} className={classes.dayScaleCell} />
);
};
const TimeTableLayout = ({ ...restProps }: WeekView.TimeTableLayoutProps) => {
const classes = useStyles();
return <WeekView.TimeTableLayout {...restProps} className={classes.timeTableLayout} />;
};
const Appointment = ({ ...restProps }: Appointments.AppointmentProps) => {
const classes = useStyles();
return <Appointments.Appointment {...restProps} className={classes.appointmentLayer} />;
};
export default class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
constructor(props: CalendarProps) {
super(props);
this.state = {
currentDate: new Date("2020-06-01"),
};
}
render() {
const { data } = this.props;
const { currentDate } = this.state;
return (
<Scheduler data={data} locale={"PL-PL"} firstDayOfWeek={1}>
<ViewState defaultCurrentDate={currentDate} />
<WeekView
startDayHour={8}
endDayHour={20}
excludedDays={[0, 6]}
cellDuration={60}
dayScaleCellComponent={DayScaleCell}
timeTableLayoutComponent={TimeTableLayout}
/>
<Appointments appointmentComponent={Appointment} />
<AppointmentTooltip />
</Scheduler>
);
}
}

View File

@ -0,0 +1,23 @@
import React from "react";
interface CellProps {
colIndex: number;
index: number;
term?: string;
handleClick?: (e: React.MouseEvent) => void;
isEventable?: boolean;
}
export const Cell = ({
colIndex,
index,
term,
handleClick,
isEventable,
}: CellProps) => {
return (
<div id={`${colIndex} ${index}`} className="td" onClick={handleClick}>
{isEventable || term}
</div>
);
};

View File

@ -0,0 +1,33 @@
import React from "react";
import { Cell } from "../Cell";
interface ColumnProps {
hours: Array<string>;
handleClick?: (e: React.MouseEvent) => void;
children?: React.ReactNode;
colIndex?: number;
isEventable?: boolean;
}
export const Column = ({
hours,
colIndex,
isEventable,
children,
...rest
}: ColumnProps) => {
return (
<div className="tbody__column">
{hours.map((hour, index) => (
<Cell
{...rest}
index={index}
term={hour}
colIndex={colIndex || 0}
isEventable={isEventable}
/>
))}
{children}
</div>
);
};

View File

@ -0,0 +1,38 @@
import React from "react";
interface SchedulerEventProps {
events: Array<number>;
colIndex: number;
}
export const SchedulerEvent = ({ events, colIndex }: SchedulerEventProps) => {
const handleEventClick = (e: React.MouseEvent) => {
const eventDiv = e.target as HTMLDivElement;
eventDiv.style.backgroundColor = "#1547C5";
};
return (
<>
{events.map((event, index) => (
<div
id={`eventCol${colIndex}eventRow${index}`}
style={{
position: "absolute",
top: 80 * index + 5,
left:5,
backgroundColor: "#839FE6",
color: "white",
borderRadius: 5,
padding:5,
width: "80%",
height: 60,
display: "none",
}}
onClick={handleEventClick}
>
:)
</div>
))}
</>
);
};

View File

@ -0,0 +1,30 @@
.scheduler {
margin-top: 20px;
border-collapse: collapse;
.thead {
display: flex;
width: 100%;
}
.tbody {
display: flex;
&__column {
display: flex;
flex-direction: column;
position: relative;
flex: 1;
}
}
.td,
.th {
border: 1px solid #ddd;
padding: 10px;
text-align: center;
flex: 1;
}
.td:hover {
background-color: #ddd;
}
}

View File

@ -0,0 +1,76 @@
import React, { useEffect } from "react";
import { useState } from "react";
import "./index.scss";
import { SchedulerEvent } from "./SchedulerEvent";
import { Column } from "./Column";
const days = ["", "poniedziałek", "wtorek", "środa", "czwartek", "piątek"];
const hours = [
"8:00",
"9:00",
"10:00",
"11:00",
"12:00",
"13:00",
"14:00",
"15:00",
"16:00",
"17:00",
"18:00",
"19:00",
"20:00",
"21:00",
];
let events: Array<number> = [];
for (let i = 0; i < hours.length / 2; i++) {
events.push(i);
}
let terms = ["Zawsze", "jest pora", "na kurde", "lody", "koral"];
export const Scheduler = () => {
const [currentEventsIds, setCurrentEventsIds] = useState<Array<string>>([]);
useEffect(() => {
const displayEvents = () => {
currentEventsIds.map((eventId: string) => {
const event = document.getElementById(eventId);
event!.style.display = "block";
});
};
displayEvents();
}, [currentEventsIds]);
const handleClick = (e: React.MouseEvent) => {
const cellId = e.currentTarget.id;
const column = cellId.slice(0, 1);
const row = cellId.slice(1);
const eventId = `eventCol${column}eventRow${Math.floor(parseInt(row) / 2)}`;
setCurrentEventsIds((currentEventsIds) => [...currentEventsIds, eventId]);
};
return (
<>
<div className="scheduler">
<div className="thead">
{days.map((day, index) => (
<div className="th" key={index}>
{day}
</div>
))}
</div>
<div className="tbody">
<Column hours={hours} isEventable={false}/>
{terms.map((_, colIndex) => (
<Column hours={hours} handleClick={handleClick} colIndex={colIndex} isEventable={true} >
<SchedulerEvent events={events} colIndex={colIndex} />
</Column>
))}
</div>
</div>
</>
);
};