dropdown+scheduler
This commit is contained in:
		@@ -7,9 +7,8 @@ body {
 | 
			
		||||
  }
 | 
			
		||||
  .wraper{
 | 
			
		||||
    display: flex;
 | 
			
		||||
    &__rightbar{
 | 
			
		||||
      width: 80%;
 | 
			
		||||
    &__calendar{
 | 
			
		||||
      flex-grow: 3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,7 @@ import React, { useState } from "react";
 | 
			
		||||
import TopBar from "./components/TopBar/";
 | 
			
		||||
import Transfer from "./components/Transfer/";
 | 
			
		||||
import "./App.scss";
 | 
			
		||||
import Schedule from "./components/Calendar/";
 | 
			
		||||
import { appointments } from "./components/Calendar/appointments";
 | 
			
		||||
import {Scheduler} from "./components/Scheduler";
 | 
			
		||||
import RightBar from "./components/RightBar";
 | 
			
		||||
import { lectures } from "./lectures";
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +38,7 @@ function App() {
 | 
			
		||||
			/>
 | 
			
		||||
			<div className="wraper">
 | 
			
		||||
				<div className="wraper__calendar">
 | 
			
		||||
					<Schedule data={appointments} />
 | 
			
		||||
					<Scheduler />
 | 
			
		||||
				</div>
 | 
			
		||||
				<div className="wraper__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>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user