This commit is contained in:
Maciek Głowacki
2020-08-24 23:40:30 +02:00
parent bce990e1f0
commit 193427a412
37 changed files with 0 additions and 16002 deletions

View File

@ -1,14 +0,0 @@
body {
margin: 0px;
padding: 0px;
}
body::-webkit-scrollbar {
display: none;
}
.wraper{
display: flex;
&__calendar{
width: 85%;
}
}

View File

@ -1,60 +0,0 @@
import React, { useState, useContext } 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 RightBar from "./components/RightBar";
import { lectures } from "./lectures";
import { BusinessLogicContext } from "./businesslogic/BusinessLogicProvider";
function App() {
const [isOpenTransfer, setOpenTransfer] = useState(false);
const [text, setText] = useState("");
const { logout } = useContext(BusinessLogicContext).actions;
return (
<div className="App">
<TopBar
textChangeHandler={(e) => {
setText(e.target.value);
}}
handleTransfer={(e) => {
setOpenTransfer(!isOpenTransfer);
}}
onLangChange={(e) => {
console.log(e);
}}
handleLogout={() => {
logout();
}}
/>
<Transfer
isOpen={isOpenTransfer}
handleClose={(e) => {
setOpenTransfer(!isOpenTransfer);
}}
/>
<div className="wraper">
<div className="wraper__calendar">
<Schedule data={appointments} />
</div>
<div className="wraper__rightbar">
<RightBar
lectures={lectures}
onGroupMouseOver={(id, name) => {
console.log("XD");
}}
onGroupClick={(id, name) => {}}
/>
</div>
</div>
<h1>{text}</h1>
</div>
);
}
export default App;

View File

@ -1,54 +0,0 @@
import React, { useState, useEffect } from "react";
import { User } from "./models/user";
import { redirectToCASLoginService, redirectToCASLogoutService } from "./utilites";
export interface IBusinessLogicContext {
user: User | null;
actions: {
logout: () => void;
};
}
export const BusinessLogicContext = React.createContext<IBusinessLogicContext>({
user: null,
actions: { logout: () => {} },
});
interface Props {}
export const BusinessLogicProvider: React.FC<Props> = (props) => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
login();
}, []);
const login = () => {
const urlParams = new URLSearchParams(window.location.search);
const ticket = urlParams.get("ticket");
if (!ticket) {
redirectToCASLoginService();
}
if (ticket) {
setUser({ ticket });
}
};
const logout = () => {
redirectToCASLogoutService();
};
return (
<BusinessLogicContext.Provider
value={{
user: user,
actions: {
logout: logout,
},
}}
>
{props.children}
</BusinessLogicContext.Provider>
);
};

View File

@ -1,5 +0,0 @@
export type User = {
name?: string;
surname?: string;
ticket: string | null;
};

View File

@ -1,7 +0,0 @@
export const redirectToCASLogoutService = () => {
window.location.replace(`https://cas.amu.edu.pl/cas/logout?service=${window.origin}`);
};
export const redirectToCASLoginService = () => {
window.location.replace(`https://cas.amu.edu.pl/cas/login?service=${window.origin}&locale=pl`);
};

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>
);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

View File

@ -1,38 +0,0 @@
.class {
display: flex;
min-height: 50px;
background-color: rgb(100, 181, 246) !important;
align-items: center;
justify-content: center;
flex-direction: column;
margin-top: 10px;
padding-top:10px;
padding-bottom:10px;
border-radius: 10px;
cursor: pointer;
align-items: stretch;
&__group{
padding-top: 1px;
padding-bottom: 1px;
&:hover{
cursor: pointer;
transition: 1s;
background-color: #8BC8FB;
}
}
&__name{
padding-top: 10px;
padding-bottom: 10px;
}
&__expandIcon{
margin-top: 5px;
width: 20px;
transition: 0.2s;
}
&__expandIconRotate{
margin-top: 5px;
width: 20px;
transition: 0.5s;
transform: scaleY(-1);
}
}

View File

@ -1,39 +0,0 @@
import React from "react";
import "./index.scss";
import Collapse from "@material-ui/core/Collapse";
import ExpandIcon from "./expand.png";
import { Lecture } from "../../../lectures";
interface LectureCardProps {
onGroupMouseOver: (id: string, name: string) => void;
onGroupClick: (id: string, name: string) => void;
onCardClick: (e: React.MouseEvent) => void;
lecture: Lecture;
id: string;
isSelected: boolean;
}
export default function LectureCard({ onGroupMouseOver, onGroupClick, onCardClick, lecture, id, isSelected }: LectureCardProps) {
return (
<div className="class" onClick={onCardClick} id={id}>
<div className="class__name">{lecture.name}</div>
<Collapse in={isSelected} timeout="auto" unmountOnExit>
{lecture.groups.map((group, index) => (
<div
className="class__group"
key={index}
onMouseOver={() => onGroupMouseOver(group.id, lecture.name)}
onClick={() => onGroupClick(group.id, lecture.name)}
>
<p>
{group.id} {group.day} {group.time} {group.room} <br></br> {group.lecturer}
</p>{" "}
</div>
))}
</Collapse>
<div onClick={onCardClick} id={id}>
<img alt="expand" src={ExpandIcon} className={`class__expandIcon${isSelected ? "Rotate" : ""}`} />
</div>
</div>
);
}

View File

@ -1,13 +0,0 @@
.right-bar {
padding-top: 10px;
padding-left: 15px;
padding-right: 15px;
text-align: center;
font-family: Lato;
&__text {
border-bottom: 1px solid;
}
height:85vh;
overflow-y: scroll;
}

View File

@ -1,43 +0,0 @@
import React, { useState, useContext } from "react";
import "./index.scss";
import { Lecture } from "../../lectures";
import LectureCard from "./LectureCard";
import { BusinessLogicContext } from "../../businesslogic/BusinessLogicProvider";
interface RightBarProps {
onGroupMouseOver: (id: string, name: string) => void;
onGroupClick: (id: string, name: string) => void;
lectures: Array<Lecture>;
}
export default function RightBar({ lectures, onGroupMouseOver, onGroupClick }: RightBarProps) {
const [selectedCardId, setSelectedCardId] = useState<string | null>(null);
const ticket = useContext(BusinessLogicContext).user?.ticket;
const onCardClick = (e: React.MouseEvent) => {
const target = e.currentTarget as HTMLElement;
selectedCardId === target.id ? setSelectedCardId(null) : setSelectedCardId(target.id);
};
return (
<div className="right-bar">
<p>{ticket}</p>
<div className="right-bar__text">
Hubert Wrzesiński<br></br>
Semestr zimowy 2020/2021
</div>
{lectures.map((lecture, index) => (
<LectureCard
lecture={lecture}
key={index}
id={index.toString()}
onGroupMouseOver={onGroupMouseOver}
onGroupClick={onGroupClick}
onCardClick={onCardClick}
isSelected={selectedCardId === index.toString()}
/>
))}
</div>
);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,36 +0,0 @@
import { Menu, MenuItem } from "@material-ui/core";
import React, { FC } from "react";
interface ProfileProps {
anchorEl: HTMLElement | null;
handleClose: () => void;
handleLogout: () => void;
}
export const Profile: FC<ProfileProps> = ({
anchorEl,
handleClose,
handleLogout,
...restProps
}) => {
return (
<Menu
className="top-bar__menu"
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem>Profile</MenuItem>
<MenuItem>My account</MenuItem>
<MenuItem
onClick={() => {
handleLogout();
}}
>
Logout
</MenuItem>
</Menu>
);
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" ?><svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"><path d="M38 12.83l-2.83-2.83-11.17 11.17-11.17-11.17-2.83 2.83 11.17 11.17-11.17 11.17 2.83 2.83 11.17-11.17 11.17 11.17 2.83-2.83-11.17-11.17z"/><path d="M0 0h48v48h-48z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 297 B

View File

@ -1,71 +0,0 @@
.top-bar {
background-color: #ffdc61;
height: 80px;
padding: 5px;
font-family: comic sans MS;
font-size: 24px;
font-weight: bold;
display: flex;
justify-content: space-between;
&__logo {
display: flex;
align-items: center;
flex-grow: 0.5;
justify-content: flex-start;
&-image {
width: 80px;
height: 80px;
}
}
&__input {
&-div {
width: 70%;
display: flex;
align-items: center;
flex-grow: 3;
}
&-field {
width: 96%;
}
&-icon {
width: 35px;
}
}
&__icon {
width: 50px;
cursor: pointer;
&-box {
display: flex;
align-items: center;
justify-content: space-around;
flex-grow: 1.5;
}
}
&__menu{
margin-top: 25px;
}
}
@media only screen and (max-width: 670px) {
.top-bar {
&__tekst {
display: none;
}
&__icon {
width: 35px;
}
&__logo-image {
width: 60px;
height: 60px;
}
&__input-icon {
width: 25px;
}
}
}

View File

@ -1,123 +0,0 @@
import React, { ChangeEvent } from "react";
import "./index.scss";
import Input from "@material-ui/core/Input";
import Transfer from "./transfer.png";
import Search from "./search.svg";
import UK from "./UK.png";
import PL from "./PL.png";
import User from "./user.png";
import CloseIcon from "./close.svg";
import { Profile } from "./Profile";
interface TopBarProps {
handleTransfer: (e: React.MouseEvent) => void;
onLangChange: (lang: boolean) => void;
handleLogout: () => void;
textChangeHandler: (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => void;
}
interface TopBarState {
isPolish: boolean;
anchorEl: HTMLElement | null;
}
export default class TopBar extends React.Component<TopBarProps, TopBarState> {
constructor(props: TopBarProps) {
super(props);
this.handleProfile = this.handleProfile.bind(this);
this.handleClose = this.handleClose.bind(this);
this.onLangChange = this.onLangChange.bind(this);
this.handleTransfer = this.handleTransfer.bind(this);
this.state = {
isPolish: true,
anchorEl: null,
};
}
handleChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
this.props.textChangeHandler(e);
}
handleTransfer(e: React.MouseEvent) {
this.props.handleTransfer(e);
}
onLangChange(e: React.MouseEvent) {
this.setState({
isPolish: !this.state.isPolish,
});
this.props.onLangChange(this.state.isPolish);
}
handleProfile(event: React.MouseEvent<HTMLImageElement>) {
this.setState({
anchorEl: event.currentTarget,
});
}
handleClose() {
this.setState({
anchorEl: null,
});
}
render() {
return (
<div className="top-bar">
<div className="top-bar__logo">
<img
className="top-bar__logo-image"
alt="logo"
src="https://plannaplan.pl/img/logo.svg"
/>
<div className="top-bar__tekst"> plan na plan </div>
</div>
<div className="top-bar__input-div">
<img
className="top-bar__input-icon"
alt="search"
src={Search}
/>
<Input
placeholder="Wyszukaj..."
inputProps={{ "aria-label": "description" }}
className="top-bar__input-field"
onChange={(e) => this.handleChange(e)}
/>
<img
className="top-bar__input-icon"
alt="close"
src={CloseIcon}
/>
</div>
<div className="top-bar__icon-box">
<img
className="top-bar__icon"
alt="transfer"
src={Transfer}
onClick={this.handleTransfer}
/>
<img
className="top-bar__icon"
alt="change_language"
src={this.state.isPolish ? UK : PL}
onClick={this.onLangChange}
/>
<img
className="top-bar__icon"
alt="profile"
src={User}
onClick={this.handleProfile}
/>
<Profile
anchorEl={this.state.anchorEl}
handleClose={this.handleClose}
handleLogout={this.props.handleLogout}
/>
</div>
</div>
);
}
}

View File

@ -1 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="512px" id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M344.5,298c15-23.6,23.8-51.6,23.8-81.7c0-84.1-68.1-152.3-152.1-152.3C132.1,64,64,132.2,64,216.3 c0,84.1,68.1,152.3,152.1,152.3c30.5,0,58.9-9,82.7-24.4l6.9-4.8L414.3,448l33.7-34.3L339.5,305.1L344.5,298z M301.4,131.2 c22.7,22.7,35.2,52.9,35.2,85c0,32.1-12.5,62.3-35.2,85c-22.7,22.7-52.9,35.2-85,35.2c-32.1,0-62.3-12.5-85-35.2 c-22.7-22.7-35.2-52.9-35.2-85c0-32.1,12.5-62.3,35.2-85c22.7-22.7,52.9-35.2,85-35.2C248.5,96,278.7,108.5,301.4,131.2z"/></svg>

Before

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,53 +0,0 @@
.wrapper {
display: flex;
justify-content: center;
text-align: center;
align-items: center;
}
.transfer {
display: flex;
outline:none;
width: 80%;
height: 70%;
padding-top: 40px;
background: rgba(255, 220, 97, 0.6);
border: 3px solid #000000;
border-radius: 15px;
text-transform: uppercase;
letter-spacing: 0.3ch;
&__left {
display: flex;
justify-content: space-around;
flex-grow: 1;
}
&__right {
flex-grow: 4;
}
&__text {
font-family: Lato;
font-size: 50px;
margin-bottom: 10px;
}
&__input {
width: 300px;
height: 45px;
background: #ffc400;
outline:none;
border: 1px solid;
border-radius: 22px ;
padding: 10px;
font-size: 24px;
transition-duration: 0.3s;
}
input:focus {
-webkit-box-shadow: 0px 0px 18px 8px #ffae00;
-moz-box-shadow: 0px 0px 18px 8px #ffae00;
box-shadow: 0px 0px 18px 8px #ffae00;
}
}

View File

@ -1,60 +0,0 @@
import React from "react";
import Modal from "@material-ui/core/Modal";
import "./index.scss";
import Fade from '@material-ui/core/Fade';
interface TransferProps {
handleClose: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
isOpen: boolean;
}
interface TransferState {}
export default class Transfer extends React.Component<
TransferProps,
TransferState
> {
constructor(props: TransferProps) {
super(props);
this.handleClose = this.handleClose.bind(this);
}
handleClose(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
this.props.handleClose(e);
}
render() {
return (
<div>
<Modal
className="wrapper"
open={this.props.isOpen}
onClose={this.handleClose}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<Fade in={this.props.isOpen}>
<div className="transfer">
<div className="transfer__left">
{/* <button className="transfer__add">chuj</button> */}
<div className="transfer__give">
<div className="transfer__text">Oddam</div>
<input className="transfer__input"></input>
</div>
<div className="transfer__receive">
<div className="transfer__text">Przyjmę</div>
<input className="transfer__input"></input>
</div>
</div>
<div className="transfer__right">
<div className="transfer__proposition"></div>
</div>
</div>
</Fade>
</Modal>
</div>
);
}
}

View File

@ -1,13 +0,0 @@
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BusinessLogicProvider } from "./businesslogic/BusinessLogicProvider";
ReactDOM.render(
<>
<BusinessLogicProvider>
<App />
</BusinessLogicProvider>
</>,
document.getElementById("root")
);

View File

@ -1,53 +0,0 @@
export interface Lecture {
name: string;
groups: Array<Group>;
}
interface Group {
id: string;
day: string;
time: string;
lecturer: string;
room: string;
}
export const lectures: Array<Lecture> = [
{
name: "E-gospodarka - narzędzia i bezpieczeństwo",
groups: [
{
id: "1CB",
day: "Pn",
time: "10:00",
lecturer: "dr inż. Michał Ren",
room: "A2-01",
},
{
id: "1XD",
day: "Wt",
time: "12:00",
lecturer: "dr inż. Michał Ren",
room: "A3-01",
},
],
},
{
name: "Statystyka",
groups: [
{
id: "2CB",
day: "Pn",
time: "10:00",
lecturer: "dr inż. Michał Ren",
room: "A2-01",
},
{
id: "2XD",
day: "Wt",
time: "12:00",
lecturer: "dr inż. Michał Ren",
room: "A3-01",
},
],
},
];

View File

@ -1 +0,0 @@
/// <reference types="react-scripts" />

View File

@ -1,27 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
};
function HigherOrderComponent(props: { classes: any; }) {
const { classes } = props;
return <Button className={classes.root}>Higher-order component</Button>;
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(HigherOrderComponent);