aboutsummaryrefslogtreecommitdiff
path: root/src/client/react/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/react/components')
-rw-r--r--src/client/react/components/container/HelpBox.js4
-rw-r--r--src/client/react/components/container/HelpBox.scss23
-rw-r--r--src/client/react/components/container/Menu.js30
-rw-r--r--src/client/react/components/container/Menu.scss25
-rw-r--r--src/client/react/components/container/Results.js6
-rw-r--r--src/client/react/components/container/Results.scss5
-rw-r--r--src/client/react/components/container/RoomFinder.js12
-rw-r--r--src/client/react/components/container/RoomFinder.scss23
-rw-r--r--src/client/react/components/container/Search.js12
-rw-r--r--src/client/react/components/container/Search.scss42
-rw-r--r--src/client/react/components/container/WeekSelector.js4
-rw-r--r--src/client/react/components/container/WeekSelector.scss40
-rw-r--r--src/client/react/components/page/Index.js4
-rw-r--r--src/client/react/components/page/Index.scss33
-rw-r--r--src/client/react/components/page/User.js12
-rw-r--r--src/client/react/components/page/User.scss24
-rw-r--r--src/client/react/components/presentational/Loading.js2
-rw-r--r--src/client/react/components/presentational/Loading.scss5
-rw-r--r--src/client/react/components/presentational/Result.js15
-rw-r--r--src/client/react/components/presentational/Result.scss30
20 files changed, 308 insertions, 43 deletions
diff --git a/src/client/react/components/container/HelpBox.js b/src/client/react/components/container/HelpBox.js
index 31624db..8b53382 100644
--- a/src/client/react/components/container/HelpBox.js
+++ b/src/client/react/components/container/HelpBox.js
@@ -22,6 +22,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
+import './HelpBox.scss';
+
class HelpBox extends React.Component {
static propTypes = {
// redux
@@ -35,7 +37,7 @@ class HelpBox extends React.Component {
}
return (
- <div className="help-box">
+ <div className="HelpBox">
<div className="arrow" />
<div className="bubble">
Voer hier een docentafkorting, klas, leerlingnummer of lokaalnummer in.
diff --git a/src/client/react/components/container/HelpBox.scss b/src/client/react/components/container/HelpBox.scss
new file mode 100644
index 0000000..f91eb77
--- /dev/null
+++ b/src/client/react/components/container/HelpBox.scss
@@ -0,0 +1,23 @@
+.HelpBox {
+ position: relative;
+ margin-top: 32px;
+
+ .arrow {
+ position: absolute;
+ background-color: white;
+ width: 32px;
+ height: 32px;
+ top: -16px;
+ left: 48px;
+ transform: rotate(45deg);
+ }
+
+ .bubble {
+ position: relative;
+ background-color: white;
+ font-weight: bold;
+ margin: 16px;
+ padding: 16px;
+ border-radius: 4px;
+ }
+}
diff --git a/src/client/react/components/container/Menu.js b/src/client/react/components/container/Menu.js
index 920973b..0b5c4dc 100644
--- a/src/client/react/components/container/Menu.js
+++ b/src/client/react/components/container/Menu.js
@@ -28,6 +28,8 @@ import { Icon } from 'rmwc/Icon';
import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
+import './Menu.scss';
+
class Menu extends React.Component {
static propTypes = {
// redux
@@ -59,19 +61,21 @@ class Menu extends React.Component {
render() {
return (
- <SimpleMenu
- handle={<Button><ButtonIcon use="more_vert" /></Button>}
- onSelected={(event) => {
- // Send the `data-type` of the selected <MenuItem />
- this.onItemSelected(event.detail.item.dataset.type);
- }}
- >
- <MenuItem data-type="add_label"><Icon use="bookmark_border" />Voeg label toe</MenuItem>
- <MenuItem data-type="make_favorite"><Icon use="star_border" />Maak favoriet</MenuItem>
- <div className="mdc-list-divider" role="separator" />
- <MenuItem data-type="room_finder"><Icon use="location_searching" />Lokaal zoeken</MenuItem>
- <MenuItem data-type="use_legacy_schedule"><Icon use="launch" />Oud rooster gebruiken</MenuItem>
- </SimpleMenu>
+ <div className="Menu">
+ <SimpleMenu
+ handle={<Button><ButtonIcon use="more_vert" /></Button>}
+ onSelected={(event) => {
+ // Send the `data-type` of the selected <MenuItem />
+ this.onItemSelected(event.detail.item.dataset.type);
+ }}
+ >
+ <MenuItem data-type="add_label"><Icon use="bookmark_border" />Voeg label toe</MenuItem>
+ <MenuItem data-type="make_favorite"><Icon use="star_border" />Maak favoriet</MenuItem>
+ <div className="mdc-list-divider" role="separator" />
+ <MenuItem data-type="room_finder"><Icon use="location_searching" />Lokaal zoeken</MenuItem>
+ <MenuItem data-type="use_legacy_schedule"><Icon use="launch" />Oud rooster gebruiken</MenuItem>
+ </SimpleMenu>
+ </div>
);
}
}
diff --git a/src/client/react/components/container/Menu.scss b/src/client/react/components/container/Menu.scss
new file mode 100644
index 0000000..3d84507
--- /dev/null
+++ b/src/client/react/components/container/Menu.scss
@@ -0,0 +1,25 @@
+.Menu {
+ .mdc-menu-anchor {
+ height: 100%;
+ }
+
+ .mdc-button {
+ height: 100%;
+ min-width: unset;
+ color: black;
+
+ &::before, &::after {
+ background-color: black;
+ }
+
+ i {
+ font-size: 24px;
+ }
+ }
+
+ .mdc-list-item {
+ i {
+ padding-right: 8px;
+ }
+ }
+}
diff --git a/src/client/react/components/container/Results.js b/src/client/react/components/container/Results.js
index 4fc9987..82e37cb 100644
--- a/src/client/react/components/container/Results.js
+++ b/src/client/react/components/container/Results.js
@@ -28,6 +28,8 @@ import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
import Result from '../presentational/Result';
+import './Results.scss';
+
class Results extends React.Component {
static propTypes = {
results: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -56,8 +58,8 @@ class Results extends React.Component {
return (
<div
- className={classnames('search__results', {
- 'search__results--has-results': !isExactMatch && this.props.results.length > 0,
+ className={classnames('Results', {
+ hasResults: !isExactMatch && this.props.results.length > 0,
})}
style={{
minHeight: isExactMatch ? 0 : this.props.results.length * 54,
diff --git a/src/client/react/components/container/Results.scss b/src/client/react/components/container/Results.scss
new file mode 100644
index 0000000..60379cf
--- /dev/null
+++ b/src/client/react/components/container/Results.scss
@@ -0,0 +1,5 @@
+.Results {
+ &.hasResults {
+ border-top: 1px #BDBDBD solid;
+ }
+}
diff --git a/src/client/react/components/container/RoomFinder.js b/src/client/react/components/container/RoomFinder.js
index 97ed175..b729ee3 100644
--- a/src/client/react/components/container/RoomFinder.js
+++ b/src/client/react/components/container/RoomFinder.js
@@ -26,6 +26,8 @@ import { Button, ButtonIcon } from 'rmwc/Button';
import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
+import './RoomFinder.scss';
+
class RoomFinder extends React.Component {
static propTypes = {
// redux
@@ -38,12 +40,6 @@ class RoomFinder extends React.Component {
history: PropTypes.object.isRequired,
}
- constructor(props) {
- super(props);
-
- this.changeRoom = this.changeRoom.bind(this);
- }
-
componentWillMount() {
const user = userFromMatch(this.props.match);
if (this.props.isVisible && users.byId[user].type !== 'r') {
@@ -81,12 +77,12 @@ class RoomFinder extends React.Component {
}
return (
- <div className="room-finder">
+ <div className="RoomFinder">
<Button onClick={() => this.changeRoom(-1)}>Vorige</Button>
<Button onClick={() => this.changeRoom(+1)}>Volgende</Button>
<div className="grow" />
<Button
- className="close-button"
+ className="closeButton"
onClick={() => this.props.dispatch({ type: 'ROOM_FINDER/HIDE' })}
>
<ButtonIcon use="close" />
diff --git a/src/client/react/components/container/RoomFinder.scss b/src/client/react/components/container/RoomFinder.scss
new file mode 100644
index 0000000..d4b16d9
--- /dev/null
+++ b/src/client/react/components/container/RoomFinder.scss
@@ -0,0 +1,23 @@
+.RoomFinder {
+ display: flex;
+ margin: 8px;
+ padding: 8px;
+ border-radius: 2px;
+ background-color: #D32F2F;
+
+ .mdc-button {
+ color: white;
+
+ &::before, &::after {
+ background-color: white;
+ }
+ }
+
+ .closeButton {
+ min-width: 48px;
+
+ .mdc-button__icon {
+ margin-right: 0;
+ }
+ }
+}
diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js
index c968957..a124b21 100644
--- a/src/client/react/components/container/Search.js
+++ b/src/client/react/components/container/Search.js
@@ -33,6 +33,8 @@ import Menu from './Menu';
import Results from './Results';
import IconFromUserType from '../presentational/IconFromUserType';
+import './Search.scss';
+
class Search extends React.Component {
static propTypes = {
results: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -143,17 +145,17 @@ class Search extends React.Component {
searchText === users.byId[urlUser].value;
return (
- <div className="search">
- <div className={classnames('search-overflow', { 'search--has-focus': hasFocus })}>
- <div className="search__input-wrapper">
- <div className="search__icon-wrapper">
+ <div className="Search">
+ <div className={classnames('overflow', { hasFocus })}>
+ <div className="inputWrapper">
+ <div className="iconWrapper">
<IconFromUserType
userType={isExactMatch ? users.byId[urlUser].type : null}
defaultIcon={<SearchIcon />}
/>
</div>
<input
- id="search__input"
+ id="searchInput"
onChange={event => dispatch({ type: 'SEARCH/INPUT_CHANGE', searchText: event.target.value })}
onKeyDown={this.onKeyDown}
value={searchText}
diff --git a/src/client/react/components/container/Search.scss b/src/client/react/components/container/Search.scss
new file mode 100644
index 0000000..ef629c2
--- /dev/null
+++ b/src/client/react/components/container/Search.scss
@@ -0,0 +1,42 @@
+.Search {
+ height: 54px;
+ position: relative;
+
+ .overflow {
+ border-radius: 2px;
+ background-color: white;
+ position: absolute;
+ width: 100%;
+ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.16), 0 0 0 1px rgba(0,0,0,0.08);
+
+ &.hasFocus {
+ box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.08);
+ }
+
+ .inputWrapper {
+ display: flex;
+ height: 54px;
+
+ .iconWrapper {
+ height: 54px;
+ padding: 15px;
+
+ svg {
+ height: 24px;
+ width: 24px;
+ }
+ }
+
+ input {
+ border: 0;
+ background-color: transparent;
+ flex-grow: 1;
+ height: inherit;
+ padding: 16px;
+ padding-left: 0px;
+ font-size: 16px;
+ outline: none;
+ }
+ }
+ }
+}
diff --git a/src/client/react/components/container/WeekSelector.js b/src/client/react/components/container/WeekSelector.js
index 9a88af6..a8f5936 100644
--- a/src/client/react/components/container/WeekSelector.js
+++ b/src/client/react/components/container/WeekSelector.js
@@ -29,6 +29,8 @@ import ArrowForwardIcon from 'react-icons/lib/md/arrow-forward';
import purifyWeek from '../../lib/purifyWeek';
import { setWeek, weekFromLocation } from '../../lib/url';
+import './WeekSelector.scss';
+
class WeekSelector extends React.Component {
static propTypes = {
// react-router
@@ -67,7 +69,7 @@ class WeekSelector extends React.Component {
render() {
return (
- <div className="week-selector">
+ <div className="WeekSelector">
<button onClick={() => this.updateWeek(-1)}><ArrowBackIcon /></button>
<div className="text">{this.getWeekText()}</div>
<button onClick={() => this.updateWeek(+1)}><ArrowForwardIcon /></button>
diff --git a/src/client/react/components/container/WeekSelector.scss b/src/client/react/components/container/WeekSelector.scss
new file mode 100644
index 0000000..dd71fea
--- /dev/null
+++ b/src/client/react/components/container/WeekSelector.scss
@@ -0,0 +1,40 @@
+.WeekSelector {
+ display: flex;
+ padding: 8px;
+ padding-bottom: 0;
+ background-color: #F44336;
+ color: white;
+ align-items: center;
+
+ .text {
+ flex-grow: 1;
+ text-align: center;
+ }
+
+ button {
+ background-color: initial;
+ border: initial;
+ color: inherit;
+ padding: 8px;
+ border-radius: 4px;
+
+ svg {
+ font-size: 2em;
+ }
+
+ &:focus {
+ background-color: #D32F2F;
+ outline: none;
+ }
+
+ &:active {
+ background-color: #B81111;
+ outline: none;
+ }
+
+ &::-moz-focus-inner {
+ /* Remove the dotted line outline from Firefox */
+ border: 0;
+ }
+ }
+}
diff --git a/src/client/react/components/page/Index.js b/src/client/react/components/page/Index.js
index ac6c4f6..b2ebbcb 100644
--- a/src/client/react/components/page/Index.js
+++ b/src/client/react/components/page/Index.js
@@ -22,10 +22,12 @@ import React from 'react';
import Search from '../container/Search';
import HelpBox from '../container/HelpBox';
+import './Index.scss';
+
class IndexPage extends React.Component {
render() {
return (
- <div className="page-index">
+ <div className="IndexPage">
<div className="container">
<img src="/icons/mml-logo.png" alt="Metis" />
<Search />
diff --git a/src/client/react/components/page/Index.scss b/src/client/react/components/page/Index.scss
new file mode 100644
index 0000000..f47b36d
--- /dev/null
+++ b/src/client/react/components/page/Index.scss
@@ -0,0 +1,33 @@
+.IndexPage {
+ background-color: #ececec;
+ padding-top: calc(50vh - 310px);
+ height: 100vh;
+
+ .container {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+
+ img {
+ display: block;
+ margin: 64px auto;
+ }
+
+ .Search {
+ z-index: 1; // Position search above help-box
+ }
+ }
+}
+
+
+@media (max-height: 510px) {
+ .IndexPage {
+ padding-top: 0px;
+
+ .container {
+ img {
+ display: none;
+ }
+ }
+ }
+}
diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js
index 00fde7e..6f9373f 100644
--- a/src/client/react/components/page/User.js
+++ b/src/client/react/components/page/User.js
@@ -28,6 +28,8 @@ import { userFromMatch } from '../../lib/url';
import WeekSelector from '../container/WeekSelector';
import RoomFinder from '../container/RoomFinder';
+import './User.scss';
+
class UserPage extends React.Component {
static propTypes = {
// react-router
@@ -43,15 +45,15 @@ class UserPage extends React.Component {
}
return (
- <div className="page-user">
- <div className="search-wrapper">
- <div className="search-container">
+ <div className="UserPage">
+ <div className="searchWrapper">
+ <div className="searchContainer">
<Search />
</div>
</div>
<Elevation z={2}>
- <div className="menu">
- <div className="menu-container">
+ <div className="headerWrapper">
+ <div className="header">
<RoomFinder />
<WeekSelector />
</div>
diff --git a/src/client/react/components/page/User.scss b/src/client/react/components/page/User.scss
new file mode 100644
index 0000000..f56a593
--- /dev/null
+++ b/src/client/react/components/page/User.scss
@@ -0,0 +1,24 @@
+.UserPage {
+ .searchWrapper {
+ position: fixed;
+ z-index: 1; // Position the search bar abore the schedule
+ width: 100%;
+
+ .searchContainer {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+ }
+ }
+
+ .headerWrapper {
+ background-color: #F44336;
+ padding-top: 54px;
+
+ .header {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+ }
+ }
+}
diff --git a/src/client/react/components/presentational/Loading.js b/src/client/react/components/presentational/Loading.js
index e33720b..ce8f49a 100644
--- a/src/client/react/components/presentational/Loading.js
+++ b/src/client/react/components/presentational/Loading.js
@@ -24,7 +24,7 @@ import { LinearProgress } from 'rmwc/LinearProgress';
class Loading extends React.Component {
render() {
return (
- <div className="loading">
+ <div className="Loading">
<LinearProgress determinate={false} />
</div>
);
diff --git a/src/client/react/components/presentational/Loading.scss b/src/client/react/components/presentational/Loading.scss
new file mode 100644
index 0000000..5748899
--- /dev/null
+++ b/src/client/react/components/presentational/Loading.scss
@@ -0,0 +1,5 @@
+.Loading {
+ .mdc-linear-progress .mdc-linear-progress__bar-inner {
+ background-color: #9C27B0;
+ }
+}
diff --git a/src/client/react/components/presentational/Result.js b/src/client/react/components/presentational/Result.js
index 18e4eb9..900d3ac 100644
--- a/src/client/react/components/presentational/Result.js
+++ b/src/client/react/components/presentational/Result.js
@@ -25,6 +25,8 @@ import users from '../../users';
import IconFromUserType from './IconFromUserType';
+import './Result.scss';
+
class Result extends React.Component {
static propTypes = {
userId: PropTypes.string.isRequired,
@@ -34,20 +36,21 @@ class Result extends React.Component {
render() {
return (
- // eslint-disable-next-line
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
<div
- className={classnames('search__result', {
- 'search__result--selected': this.props.isSelected,
+ className={classnames('Result', {
+ isSelected: this.props.isSelected,
})}
onClick={this.props.onClick}
>
- <div className="search__icon-wrapper">
+ <div className="iconWrapper">
<IconFromUserType userType={users.byId[this.props.userId].type} />
</div>
- <div className="search__result__text">
+ <div className="text">
{users.byId[this.props.userId].value}
{users.byId[this.props.userId].alt &&
- <span className="search__result__text__alt">
+ <span className="alt">
{` ${users.byId[this.props.userId].alt}`}
</span>
}
diff --git a/src/client/react/components/presentational/Result.scss b/src/client/react/components/presentational/Result.scss
new file mode 100644
index 0000000..1ca0dd8
--- /dev/null
+++ b/src/client/react/components/presentational/Result.scss
@@ -0,0 +1,30 @@
+.Result {
+ display: flex;
+ cursor: pointer;
+
+ &:hover, &.isSelected {
+ background-color: lightgray;
+ }
+
+ .iconWrapper {
+ height: 54px;
+ padding: 15px;
+
+ svg {
+ height: 24px;
+ width: 24px;
+ }
+ }
+
+ .text {
+ padding: 15px;
+ padding-left: 0px;
+ font-size: 16px;
+ transform: translate(0, 3px);
+
+ .alt {
+ font-style: italic;
+ color: gray;
+ }
+ }
+}