dropdown+scheduler
This commit is contained in:
parent
5b24b5fd59
commit
f95c8d450d
@ -7,9 +7,8 @@ body {
|
|||||||
}
|
}
|
||||||
.wraper{
|
.wraper{
|
||||||
display: flex;
|
display: flex;
|
||||||
&__rightbar{
|
&__calendar{
|
||||||
width: 80%;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
|
||||||
},
|
|
||||||
];
|
|
@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
23
src/components/Scheduler/Cell/index.tsx
Normal file
23
src/components/Scheduler/Cell/index.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
0
src/components/Scheduler/Column/index.scss
Normal file
0
src/components/Scheduler/Column/index.scss
Normal file
33
src/components/Scheduler/Column/index.tsx
Normal file
33
src/components/Scheduler/Column/index.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
0
src/components/Scheduler/SchedulerEvent/index.scss
Normal file
0
src/components/Scheduler/SchedulerEvent/index.scss
Normal file
38
src/components/Scheduler/SchedulerEvent/index.tsx
Normal file
38
src/components/Scheduler/SchedulerEvent/index.tsx
Normal 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>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
30
src/components/Scheduler/index.scss
Normal file
30
src/components/Scheduler/index.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
76
src/components/Scheduler/index.tsx
Normal file
76
src/components/Scheduler/index.tsx
Normal 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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user