summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.css48
-rw-r--r--src/App.js40
-rw-r--r--src/RuzCard.js94
-rw-r--r--src/RuzDialog.js138
-rw-r--r--src/RuzList.js159
-rw-r--r--src/index.html1
-rw-r--r--src/signin.js117
7 files changed, 542 insertions, 55 deletions
diff --git a/src/App.css b/src/App.css
index 3837551..e69de29 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,48 +0,0 @@
-.App {
- height: 100%;
- min-height: 400px;
- text-align: center;
- display: flex;
- flex-direction: column;
- justify-content: stretch;
-}
-
-.App-flex {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.App-heading {
- background-color: #222;
- color: #f8f8f8;
- font-size: 6vh;
- box-shadow: 0px 4px 4vh 4px rgba(34,34,34,0.9);
- z-index: 2;
-}
-
-.App-react {
- color: #00d8ff;
- text-decoration: overline underline;
-}
-
-.App-logo {
- max-height: 30vh;
- max-width: 30vh;
-}
-
-.App-instructions {
- background-color: #f8f8f8;
- color: #222;
- font-size: 3vh;
- line-height: 1.5;
- padding: 0 1em;
-}
-
-.App-instructions code {
- background-color: #222;
- color: #00d8ff;
- padding: .2em .3em;
- border-radius: .2em;
-}
diff --git a/src/App.js b/src/App.js
index b890840..21e9763 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,16 +1,42 @@
-import './App.css'
+import SignIn from './signin.js';
+import Container from '@material-ui/core/Container';
+import Grid from '@material-ui/core/Grid';
+import RuzList from './RuzList.js';
+//import RuzSearch from './RuzSearch.js';
+import { makeStyles, ThemeProvider, useTheme, createMuiTheme } from '@material-ui/core/styles';
import React, {Component} from 'react'
+const theme = createMuiTheme({
+ palette: {
+ type: 'dark',
+ background: {
+ paper: '#121212',
+ default: '#121212',
+ },
+ primary: {
+ main: '#BB86FC',
+ },
+ secondary: {
+ main: '#03DAC6',
+ },
+ }
+});
+
class App extends Component {
render() {
- return <div className="App">
- <div className="App-heading App-flex">
- <h2>Welcome to <span className="App-react">React</span></h2>
- </div>
+ return <div className="">
+ <ThemeProvider theme={theme}>
+ <Grid container spacing={0}>
+ <Grid item xs={12} md={6} lg={6}>
+ <RuzList />
+ </Grid>
+ <Grid item xs={12} md={6} lg={6}>
+ {/* <SignIn /> */}
+ </Grid>
+ </Grid>
+ </ThemeProvider>
<div className="App-instructions App-flex">
- <img className="App-logo" src={require('./react.svg')}/>
- <p>Edit <code>src/App.js</code> and save to hot reload your changes.</p>
</div>
</div>
}
diff --git a/src/RuzCard.js b/src/RuzCard.js
new file mode 100644
index 0000000..4b0a39a
--- /dev/null
+++ b/src/RuzCard.js
@@ -0,0 +1,94 @@
+import React, { useState } from 'react';
+import { makeStyles, useTheme } from '@material-ui/core/styles';
+import Card from '@material-ui/core/Card';
+import CardContent from '@material-ui/core/CardContent';
+import CardMedia from '@material-ui/core/CardMedia';
+import Typography from '@material-ui/core/Typography';
+import ListItem from '@material-ui/core/ListItem';
+import ListItemAvatar from '@material-ui/core/ListItemAvatar';
+import ListItemText from '@material-ui/core/ListItemText';
+import { Button, useMediaQuery, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@material-ui/core';
+
+
+const useStyles = makeStyles(theme => ({
+ card: {
+ display: 'flex',
+ },
+ details: {
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ content: {
+ flex: '1 0 auto',
+ },
+ inline: {
+ display: 'inline',
+ },
+ seminarCard: {
+ color: 'limegreen',
+ },
+ examCard: {
+ color: 'red',
+ },
+}));
+
+
+function class_by_type (type, classes) {
+ let classname = null;
+ switch (type) {
+ case 'Семинар':
+ classname = classes.seminarCard;
+ break;
+ case 'Экзамен':
+ classname = classes.examCard;
+ break;
+ default:
+ return;
+ }
+
+ return classname;
+}
+
+
+export default function RuzCard(props) {
+ const classes = useStyles();
+ const theme = useTheme();
+ const dialogFullScreen = useMediaQuery(theme.breakpoints.down('sm'));
+ const [open, setOpen] = useState(false);
+
+ const handleClickOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+
+
+ return (
+ <ListItem alignItems="flex-start" button onClick={props.onClick}>
+ <ListItemAvatar>
+ <div>
+ <Typography variant="body2">{props.item.beginLesson}</Typography><br />
+ <Typography variant="body2" color="secondary">{props.item.endLesson}</Typography>
+ </div>
+ </ListItemAvatar>
+ <ListItemText
+ primary={props.item.discipline}
+ secondary={
+ <React.Fragment>
+ {props.item.auditorium}<br />
+ <Typography
+ component="span"
+ variant="body2"
+ className={class_by_type(props.item.kindOfWork, classes)}
+ color="textPrimary"
+ >
+ {props.item.kindOfWork}
+ </Typography>
+ </React.Fragment>
+ }
+ />
+ </ListItem>
+ )
+} \ No newline at end of file
diff --git a/src/RuzDialog.js b/src/RuzDialog.js
new file mode 100644
index 0000000..5a8e8ea
--- /dev/null
+++ b/src/RuzDialog.js
@@ -0,0 +1,138 @@
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import { Dialog, DialogContent, DialogContentText, DialogTitle, DialogActions, Button, List } from '@material-ui/core';
+import { useMediaQuery, useTheme } from '@material-ui/core';
+import { Divider, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core';
+import { AppBar, Toolbar, IconButton, Typography } from '@material-ui/core';
+import CloseIcon from '@material-ui/icons/Close';
+
+
+const useStyles = makeStyles(theme => ({
+ paper: {
+ marginTop: theme.spacing(3),
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ width: '100%',
+ },
+ schedule: {
+ width: '100%',
+ backgroundColor: theme.palette.background.paper,
+ },
+ avatar: {
+ margin: theme.spacing(1),
+ backgroundColor: theme.palette.secondary.main,
+ },
+ stickyHeader: {
+ background: 'inherit',
+ },
+ fixUl: {
+ padding: 0,
+ background: 'inherit',
+ },
+ centerProgress: {
+ position: 'absolute',
+ top: '50%',
+ verticalAlign: 'middle',
+ },
+ dateHeader: {
+ textTransform: 'capitalize',
+ color: 'teal',
+ },
+ mobileBar: {
+ position: 'relative',
+ },
+ mobileTitle: {
+ marginLeft: theme.spacing(2),
+ flex: 1,
+ },
+}));
+
+function RuzDialogCard(props) {
+
+ return (
+ <ListItem alignItems="flex-start">
+ <ListItemText
+ primary={props.entry.description}
+ />
+ </ListItem>
+ )
+}
+
+function RuzDialogList(props) {
+ const item = props.item;
+ const classes = useStyles();
+
+ const entries = [
+ { description: `${item.building}` },
+ { description: `${item.lecturer}` },
+ ];
+
+ return (
+ <List className={classes.schedule}>
+ {entries.map(entry => {
+ return (
+ <React.Fragment>
+ <RuzDialogCard entry={entry} />
+ <Divider />
+ </React.Fragment>
+ );}
+ )}
+ </List>
+ )
+}
+
+function MobileNavBar(props) {
+
+ const classes = useStyles();
+ const closeAction = props.closeAction;
+ const title = props.title;
+
+ return (
+ <AppBar className={classes.mobileBar}>
+ <Toolbar>
+ <IconButton edge="start" color="inherit" onClick={closeAction} aria-label="close">
+ <CloseIcon />
+ </IconButton>
+ <Typography variant="h6" className={classes.mobileTitle}>
+ {title}
+ </Typography>
+ </Toolbar>
+ </AppBar>
+ );
+}
+
+export default function RuzDialog(props) {
+ if (!props.open)
+ return <React.Fragment />
+
+ const theme = useTheme();
+ const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
+ const closeAction = props.dialogCloseAction;
+
+ return (
+ <Dialog
+ fullScreen={isMobile}
+ fullWidth={true}
+ maxWidth="xs"
+ open={true}
+ onClose={closeAction}
+ aria-labelledby="ruz-dialog-title"
+ >
+ {
+ isMobile ?
+ <MobileNavBar closeAction={closeAction} title={props.dialog.discipline} />
+ :
+ <DialogTitle id="responsive-dialog-title">{props.dialog.discipline}</DialogTitle>
+ }
+ <DialogContent>
+ <RuzDialogList item={props.dialog} />
+ </DialogContent>
+ <DialogActions>
+ <Button onClick={closeAction} color="primary" autoFocus>
+ close
+ </Button>
+ </DialogActions>
+ </Dialog>
+ );
+}
diff --git a/src/RuzList.js b/src/RuzList.js
new file mode 100644
index 0000000..c31c4aa
--- /dev/null
+++ b/src/RuzList.js
@@ -0,0 +1,159 @@
+import React, { useState } from 'react';
+import Avatar from '@material-ui/core/Avatar';
+import Button from '@material-ui/core/Button';
+import CssBaseline from '@material-ui/core/CssBaseline';
+import TextField from '@material-ui/core/TextField';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Checkbox from '@material-ui/core/Checkbox';
+import Link from '@material-ui/core/Link';
+import Grid from '@material-ui/core/Grid';
+import Box from '@material-ui/core/Box';
+import ScheduleIcon from '@material-ui/icons/Schedule';
+import Typography from '@material-ui/core/Typography';
+import { makeStyles } from '@material-ui/core/styles';
+import Container from '@material-ui/core/Container';
+import Divider from '@material-ui/core/Divider';
+import List from '@material-ui/core/List';
+import ListSubheader from '@material-ui/core/ListSubheader';
+import { CircularProgress } from '@material-ui/core';
+import { useTheme } from '@material-ui/core/styles';
+import { useMediaQuery, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@material-ui/core';
+
+import axios from 'axios';
+
+import RuzCard from './RuzCard.js';
+import RuzDialog from './RuzDialog.js';
+
+
+const useStyles = makeStyles(theme => ({
+ paper: {
+ marginTop: theme.spacing(3),
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ width: '100%',
+ },
+ schedule: {
+ width: '100%',
+ backgroundColor: theme.palette.background.paper,
+ },
+ avatar: {
+ margin: theme.spacing(1),
+ backgroundColor: theme.palette.secondary.main,
+ },
+ stickyHeader: {
+ background: 'inherit',
+ },
+ fixUl: {
+ padding: 0,
+ background: 'inherit',
+ },
+ centerProgress: {
+ position: 'absolute',
+ top: '50%',
+ verticalAlign: 'middle',
+ },
+ dateHeader: {
+ textTransform: 'capitalize',
+ color: 'teal',
+ },
+}));
+
+
+function RuzListDate(props) {
+ const items = props.items;
+ const date = new Date(props.date);
+ const datestring = date.toLocaleDateString('ru-RU', {weekday: 'short', day: 'numeric', month: 'long'})
+ const classes = useStyles();
+
+ return (
+ <React.Fragment key={`ruzdate-inner-${props.date}`}>
+ <ListSubheader className={classes.dateHeader}>
+ {datestring}
+ </ListSubheader>
+ {
+ items.map(item => {
+ return (
+ <React.Fragment>
+ <RuzCard onClick={() => props.onClickForward(item)} item={item} />
+ <Divider variant="inset" />
+ </React.Fragment>
+ );
+ })
+ }
+ </React.Fragment>
+ );
+}
+
+
+export default function RuzList(props) {
+ const classes = useStyles();
+
+ const [ items, setItems ] = useState([]);
+ const [ needUpdate, setNeedUpdate ] = useState(true);
+ const [ openDialog, setOpenDialog ] = useState(null);
+
+ if (needUpdate) {
+ axios({
+ method: 'GET',
+ url: 'http://cors.hell.fcked.net/api/schedule/group/11235',
+ params: {
+ start: '2019.12.16',
+ finish: '2019.12.23',
+ lng: '1',
+ },
+ }).then(resp => {
+ setNeedUpdate(false);
+
+ const data = {};
+ for (let [id, item] of resp.data.entries()) {
+ if (!item) continue;
+ item.id = id;
+ item.date in data
+ ?
+ data[item.date].push(item)
+ :
+ data[item.date] = [item];
+ }
+ setItems(data);
+ });
+ }
+
+ console.log(openDialog);
+ const dialogCloseAction = () => {
+ setOpenDialog(null);
+ }
+
+ let progressBar = (<React.Fragment />);
+ if (needUpdate) {
+ progressBar = (<CircularProgress className={classes.centerProgress} />);
+ }
+
+ const dates = [...Object.keys(items)].sort();
+
+ return (
+ <Container component="main" maxWidth="xs">
+ <CssBaseline />
+ <RuzDialog dialog={openDialog} open={openDialog !== null} dialogCloseAction={dialogCloseAction} />
+ <div className={classes.paper}>
+ <Avatar className={classes.avatar}>
+ <ScheduleIcon />
+ </Avatar>
+ {progressBar}
+ <List className={classes.schedule} hidden={items.needUpdate}>
+ {
+ dates.map(date => {
+ return (
+ <li key={`ruzdate-${date}`} className={classes.stickyHeader}>
+ <ul className={classes.fixUl}>
+ <RuzListDate onClickForward={setOpenDialog} items={items[date]} date={date} />
+ </ul>
+ </li>
+ )
+ })
+ }
+ </List>
+ </div>
+ </Container>
+ );
+}
diff --git a/src/index.html b/src/index.html
index d0bdd15..4c8a34e 100644
--- a/src/index.html
+++ b/src/index.html
@@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<title>fcked-rt</title>
<meta name="description" content="">
</head>
diff --git a/src/signin.js b/src/signin.js
new file mode 100644
index 0000000..4d7ed4f
--- /dev/null
+++ b/src/signin.js
@@ -0,0 +1,117 @@
+import React from 'react';
+import Avatar from '@material-ui/core/Avatar';
+import Button from '@material-ui/core/Button';
+import CssBaseline from '@material-ui/core/CssBaseline';
+import TextField from '@material-ui/core/TextField';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Checkbox from '@material-ui/core/Checkbox';
+import Link from '@material-ui/core/Link';
+import Grid from '@material-ui/core/Grid';
+import Box from '@material-ui/core/Box';
+import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
+import Typography from '@material-ui/core/Typography';
+import { makeStyles } from '@material-ui/core/styles';
+import Container from '@material-ui/core/Container';
+
+function Copyright() {
+ return (
+ <Typography variant="body2" color="textSecondary" align="center">
+ {'Copyright © '}
+ <Link color="inherit" href="https://material-ui.com/">
+ Your Website
+ </Link>{' '}
+ {new Date().getFullYear()}
+ {'.'}
+ </Typography>
+ );
+}
+
+const useStyles = makeStyles(theme => ({
+ paper: {
+ marginTop: theme.spacing(8),
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ },
+ avatar: {
+ margin: theme.spacing(1),
+ backgroundColor: theme.palette.secondary.main,
+ },
+ form: {
+ width: '100%', // Fix IE 11 issue.
+ marginTop: theme.spacing(1),
+ },
+ submit: {
+ margin: theme.spacing(3, 0, 2),
+ },
+}));
+
+export default function SignIn() {
+ const classes = useStyles();
+
+ return (
+ <Container component="main" maxWidth="xs">
+ <CssBaseline />
+ <div className={classes.paper}>
+ <Avatar className={classes.avatar}>
+ <LockOutlinedIcon />
+ </Avatar>
+ <Typography component="h1" variant="h5">
+ Sign in
+ </Typography>
+ <form className={classes.form} noValidate>
+ <TextField
+ variant="outlined"
+ margin="normal"
+ required
+ fullWidth
+ id="email"
+ label="Email Address"
+ name="email"
+ autoComplete="email"
+ autoFocus
+ />
+ <TextField
+ variant="outlined"
+ margin="normal"
+ required
+ fullWidth
+ name="password"
+ label="Password"
+ type="password"
+ id="password"
+ autoComplete="current-password"
+ />
+ <FormControlLabel
+ control={<Checkbox value="remember" color="primary" />}
+ label="Remember me"
+ />
+ <Button
+ type="submit"
+ fullWidth
+ variant="contained"
+ color="primary"
+ className={classes.submit}
+ >
+ Sign In
+ </Button>
+ <Grid container>
+ <Grid item xs>
+ <Link href="#" variant="body2">
+ Forgot password?
+ </Link>
+ </Grid>
+ <Grid item>
+ <Link href="#" variant="body2">
+ {"Don't have an account? Sign Up"}
+ </Link>
+ </Grid>
+ </Grid>
+ </form>
+ </div>
+ <Box mt={8}>
+ <Copyright />
+ </Box>
+ </Container>
+ );
+}