diff --git a/assets/img/logo.svg b/assets/img/logo.svg
new file mode 100644
index 0000000..210f7ee
--- /dev/null
+++ b/assets/img/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/img/logo_webgem.svg b/assets/img/logo_webgem.svg
new file mode 100644
index 0000000..eea1d0f
--- /dev/null
+++ b/assets/img/logo_webgem.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/img/none-assigned.png b/assets/img/none-assigned.png
new file mode 100644
index 0000000..fc1a31f
Binary files /dev/null and b/assets/img/none-assigned.png differ
diff --git a/assets/img/plus-circle.svg b/assets/img/plus-circle.svg
new file mode 100644
index 0000000..f7a138c
--- /dev/null
+++ b/assets/img/plus-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/img/trash-alt.svg b/assets/img/trash-alt.svg
new file mode 100644
index 0000000..6f2df79
--- /dev/null
+++ b/assets/img/trash-alt.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/components/Redirect/index.js b/components/Redirect/index.js
new file mode 100644
index 0000000..24c332b
--- /dev/null
+++ b/components/Redirect/index.js
@@ -0,0 +1,12 @@
+import { Component } from 'preact';
+import { route } from 'preact-router';
+
+export default class Redirect extends Component {
+ componentWillMount() {
+ route(this.props.to, true);
+ }
+
+ render() {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/components/addItem/index.js b/components/addItem/index.js
new file mode 100644
index 0000000..6dd5a9c
--- /dev/null
+++ b/components/addItem/index.js
@@ -0,0 +1,32 @@
+import { h, Component } from 'preact';
+import style from './style';
+
+export default class AddItem extends Component{
+ addItem(event) {
+ event.preventDefault();
+ const timestamp = Date.now();
+ const item = {
+ desc: this.name.value,
+ p1: `none`,
+ p2: `none`,
+ p3: `none`,
+ p4: `none`,
+ status: `To do`
+ };
+ this.props.addItem(item);
+ this.addItemForm.reset();
+ }
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+AddItem.propTypes = {
+ addItem: Component.PropTypes.func.isRequired
+};
\ No newline at end of file
diff --git a/components/addItem/style.css b/components/addItem/style.css
new file mode 100644
index 0000000..047224d
--- /dev/null
+++ b/components/addItem/style.css
@@ -0,0 +1,68 @@
+.newItem{
+ display: flex;
+ align-items: center;
+ padding: 0;
+ margin: 0;
+ /* border-left: 7.5px solid #eee */
+}
+
+.newItem img{
+ height: 18px;
+ margin: 5px
+}
+
+.newItemForm{
+ width: calc(100% - 1px);
+ min-width: 308px;
+ display: flex;
+ padding: 0;
+ margin: 0;
+ height: 35px;
+}
+
+.newItemForm input{
+ width: 100%;
+ background: none;
+ box-shadow: none;
+ outline: none;
+ border: none;
+ border-left: 7.5px solid #eee;
+ border-top: 1px solid #eee;
+ border-right: 1px solid #eee;
+ border-bottom: 1px solid #eee;
+ /* border-left: 7px solid ##c2c2c2; */
+ font-size: 14px;
+ padding: 10px;
+ margin: 0;
+ color: #333;
+ transition: all .2s ease-in-out;
+ height: 35px;
+}
+
+.newItemForm input::placeholder{
+ color: #A09C9C;
+}
+
+.newItemForm input:focus{
+ border-color: #f44336;
+ color: #333;
+}
+
+.newItemForm button{
+ background: none;
+ outline: none;
+ border: none;
+ box-shadow: none;
+ border: 2px solid #d81b60;
+ font-size: 20px;
+ color: #d81b60;
+ padding: 0 10px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.newItemForm button:hover{
+ background: #d81b60;
+ color: #ffffff;
+}
\ No newline at end of file
diff --git a/components/app.js b/components/app.js
new file mode 100644
index 0000000..991f49e
--- /dev/null
+++ b/components/app.js
@@ -0,0 +1,131 @@
+import { h, Component } from 'preact';
+import { Router } from 'preact-router';
+
+import Header from './header';
+import Home from '../routes/home';
+import Profile from '../routes/profile';
+import Team from '../routes/team';
+import Login from '../routes/login';
+import Teams from '../routes/Teams';
+
+import firebase from 'firebase/app';
+require('firebase/auth');
+import fireApp from '../base2';
+
+const github = new firebase.auth.GithubAuthProvider();
+github.addScope('user:email');
+
+const facebook = new firebase.auth.FacebookAuthProvider();
+facebook.addScope('user_email');
+
+const twitter = new firebase.auth.TwitterAuthProvider();
+
+export default class App extends Component {
+ constructor() {
+ super();
+ // this.renderInventory = this.renderInventory.bind(this);
+ // this.renderLogin = this.renderLogin.bind(this);
+ this.authenticate = this.authenticate.bind(this);
+ this.logout = this.logout.bind(this);
+ this.authHandler = this.authHandler.bind(this);
+ // this.handleChange = this.handleChange.bind(this);
+ this.state = {
+ uid: null,
+ owner: null,
+ username: null,
+ userProfilePic: null
+ };
+ }
+
+ componentDidMount() {
+ firebase.auth(fireApp).onAuthStateChanged((user) => {
+ if (user) {
+ this.authHandler(null, { user });
+ }
+ });
+ // base.onAuth((user) => {
+ // if (user) {
+ // this.authHandler(null, { user });
+ // }
+ // });
+ }
+
+ handleRoute = e => {
+ this.currentUrl = e.url;
+ };
+
+ authenticate(provider) {
+ console.log(`Trying to log in with ${provider}`);
+ firebase.auth(fireApp).signInWithPopup(provider).then(() => {
+ this.authHandler;
+ });
+ // base.authWithOAuthPopup(provider, this.authHandler);
+ }
+
+ logout() {
+ // base.unauth();
+ firebase.auth(fireApp).signOut();
+ this.setState({ uid: null, username: null, userProfilePic: null });
+ }
+
+ authHandler(err, authData) {
+ console.log(authData);
+ if (err) {
+ console.error(err);
+ return;
+ }
+
+ // grab the database info
+ const globalRef = fireApp.database().ref('global');
+
+ // query the firebase once for the store data
+ globalRef.once('value', (snapshot) => {
+ const data = snapshot.val() || {};
+
+ // claim it as our own if there is no owner already
+ if(!data.owner) {
+ globalRef.set({
+ owner: authData.user.uid
+ });
+ }
+
+ this.setState({
+ uid: authData.user.uid,
+ owner: data.owner || authData.user.uid,
+ username: authData.user.displayName,
+ userProfilePic: authData.user.photoURL,
+ });
+ });
+
+ }
+
+
+ render() {
+ return (
+
+ );
+ }
+}
diff --git a/components/boardLink/index.js b/components/boardLink/index.js
new file mode 100644
index 0000000..1602f04
--- /dev/null
+++ b/components/boardLink/index.js
@@ -0,0 +1,37 @@
+import { h, Component } from 'preact';
+import { Link } from 'preact-router/match';
+import '@material/list/dist/mdc.list.min.css';
+import style from './style';
+
+export default class BoardLink extends Component {
+ constructor() {
+ super();
+
+ this.areYouFuckingSure = this.areYouFuckingSure.bind(this);
+ }
+
+ state = {
+ deletedBoard: 'boooooooi'
+ }
+
+ areYouFuckingSure() {
+ let r = confirm(`You are about to delete ${this.props.details.name}. \nThis can't be undone! \nAre you sure you want to delete the board ${this.props.details.name}`);
+ if (r === true) {
+ this.props.removeBoard(this.props.index);
+ }
+ }
+
+ render() {
+ const i = this.props;
+ return (
+
+
+ {i.details.name}
+
+
+ delete
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/boardLink/style.css b/components/boardLink/style.css
new file mode 100644
index 0000000..9fa0d3f
--- /dev/null
+++ b/components/boardLink/style.css
@@ -0,0 +1,18 @@
+nav a.activeBoard {
+ background: #9a67ea;
+ color: #ffffff;
+}
+
+nav .boardLinkWrapper a.activeBoard {
+ background: #9a67ea;
+ color: #ffffff;
+}
+
+nav a.activeBoard + a{
+ background: #9a67ea;
+ color: #ffffff;
+}
+
+.mdc-list-item__end-detail{
+ flex: 0 1 5%;
+}
\ No newline at end of file
diff --git a/components/boardcard/index.js b/components/boardcard/index.js
new file mode 100644
index 0000000..6cb1c48
--- /dev/null
+++ b/components/boardcard/index.js
@@ -0,0 +1,37 @@
+import { h, Component } from 'preact';
+import style from './style';
+import Card from 'preact-material-components/Card';
+import { Link } from 'preact-router';
+import 'preact-material-components/Card/style.css';
+import 'preact-material-components/Button/style.css';
+
+export default class BoardCard extends Component {
+ constructor() {
+ super();
+
+ const colors = ['#F47373', '#697689', '#37D67A', '#2CCCE4', '#ff8a65', '#ba68c8', '#e91e63', '#673ab7', '#3f51b5', '#2196f3', '#009688', '#ffc107'];
+ this.state = {
+ background: colors[Math.floor(12 * Math.random())]
+ };
+ }
+ render() {
+ return (
+
+
+
+
+ {this.props.boardname.name}
+
+
+
+
+
+ show
+
+
+
+
+
+ );
+ }
+}
diff --git a/components/boardcard/style.css b/components/boardcard/style.css
new file mode 100644
index 0000000..f40a75b
--- /dev/null
+++ b/components/boardcard/style.css
@@ -0,0 +1,38 @@
+.cardWrap{
+ display: inline-block;
+ width: 20%;
+ min-width: 300px;
+ margin: 10px 5px;
+}
+
+.cardWrap h1{
+ font-size: 25px;
+ text-transform: uppercase;
+ color: white;
+}
+
+.cardBackcolor{
+ background: #333;
+ color: white;
+ margin-left: -16px;
+ margin-top: -16px;
+ margin-right: -16px;
+ margin-bottom: -16px;
+ height: 175px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+}
+
+.cardWrap button{
+ width: 100%;
+}
+
+.linkCard{
+ width: 100%;
+ width: calc(50% - 8px);
+ margin-right: 8px;
+}
+
+/* fix the button margin */
\ No newline at end of file
diff --git a/components/confirmLeave/index.js b/components/confirmLeave/index.js
new file mode 100644
index 0000000..bbfb464
--- /dev/null
+++ b/components/confirmLeave/index.js
@@ -0,0 +1,39 @@
+import { h, Component } from 'preact';
+import Dialog from 'preact-material-components/Dialog';
+import Button from 'preact-material-components/Button';
+import 'preact-material-components/List/style.css';
+import 'preact-material-components/Button/style.css';
+import 'preact-material-components/Dialog/style.css';
+import style from './style.css';
+
+export default class ConfirmLeave extends Component {
+ constructor() {
+ super();
+ this.handleAccept = this.handleAccept.bind(this);
+ }
+
+ handleAccept() {
+ this.props.handleLeave(this.props.team);
+ }
+ render(){
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/confirmLeave/style.css b/components/confirmLeave/style.css
new file mode 100644
index 0000000..8cffcf8
--- /dev/null
+++ b/components/confirmLeave/style.css
@@ -0,0 +1,5 @@
+.leaveButton{
+ width: calc(50% - 8px);
+ margin-right: 8px;
+ margin-left: 8px;
+}
\ No newline at end of file
diff --git a/components/createTeam/index.js b/components/createTeam/index.js
new file mode 100644
index 0000000..e3a2d44
--- /dev/null
+++ b/components/createTeam/index.js
@@ -0,0 +1,37 @@
+import { h, Component } from 'preact';
+import style from './style';
+import Card from 'preact-material-components/Card';
+import 'preact-material-components/Card/style.css';
+
+export default class CreateTeam extends Component {
+ createTeam(event) {
+ event.preventDefault();
+ const team = {
+ name: this.name.value,
+ members: {
+ [this.props.uuid]: true
+ }
+ };
+ this.props.addTeam(team);
+ this.createTeamForm.reset();
+ }
+ render() {
+ return (
+
+
+
+
+ new team
+
+
+
+
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/createTeam/style.css b/components/createTeam/style.css
new file mode 100644
index 0000000..eae13b1
--- /dev/null
+++ b/components/createTeam/style.css
@@ -0,0 +1,77 @@
+.cardWrap{
+ display: inline-block;
+ width: 20%;
+ min-width: 300px;
+ margin: 10px 5px;
+}
+
+.cardWrap h1{
+ font-size: 25px;
+ text-transform: uppercase;
+ color: white;
+}
+
+.cardBackcolor{
+ background: #9c27b0;
+ color: white;
+ margin-left: -16px;
+ margin-top: -16px;
+ margin-right: -16px;
+ margin-bottom: -16px;
+ height: 175px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+}
+
+.buttonSubmit{
+ font-family: Roboto, sans-serif;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-size: 0.875rem;
+ font-weight: 500;
+ letter-spacing: 0.04em;
+ line-height: 2.25rem;
+ text-decoration: none;
+ text-transform: uppercase;
+ display: inline-block;
+ position: relative;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ min-width: 88px;
+ height: 36px;
+ padding: 0 16px;
+ border: none;
+ outline: none;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-appearance: none;
+ overflow: hidden;
+ vertical-align: middle;
+ border-radius: 2px;
+ color: white;
+}
+
+.teamInput{
+ height: 35px;
+ width: 142px;
+ margin-left: 0px;
+ margin-right: 8px;
+ padding: 5px 10px;
+ border: none;
+ border-bottom: 2px solid #eee;
+ background: none;
+ color: #333;
+ font-size: 15px;
+}
+
+.teamInput:focus{
+ border: none;
+ outline: none;
+ border-bottom: 2px solid #9c27b0;
+ color: #9c27b0;
+}
\ No newline at end of file
diff --git a/components/data/index.js b/components/data/index.js
new file mode 100644
index 0000000..ec595f2
--- /dev/null
+++ b/components/data/index.js
@@ -0,0 +1,144 @@
+const personen = [
+ {
+ title: 'MV',
+ personen: [
+ {
+ name: 'Yannick Frisart',
+ functie: 'Front-end',
+ img: 'https://20578.tk/panel/img/test.png'
+ },
+ {
+ name: 'Thijs van Rijn',
+ functie: 'Designer',
+ img: 'https://20578.tk/panel/img/test.png'
+ }
+ ]
+ },
+ {
+ title: 'MD',
+ personen: [
+ {
+ name: 'Rick Woltheus',
+ functie: 'Back-end',
+ img: 'https://20578.tk/panel/img/test.png'
+ },
+ {
+ name: 'Coen Filipsen',
+ functie: 'Communicatie',
+ img: 'https://20578.tk/panel/img/test.png'
+ }
+ ]
+ },
+ {
+ title: 'Stagiairs',
+ personen: [
+ {
+ name: 'Maurice',
+ functie: 'Stagair',
+ img: 'https://20578.tk/panel/img/test.png'
+ },
+ {
+ name: 'Patrick',
+ functie: 'Stagair',
+ img: 'https://20578.tk/panel/img/test.png'
+ }
+ ]
+ }
+];
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters
+function escapeRegexCharacters(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
+function getSuggestions(value) {
+ const escapedValue = escapeRegexCharacters(value.trim());
+
+ if (escapedValue === '') {
+ return [];
+ }
+
+ const regex = new RegExp('^' + escapedValue, 'i');
+
+ return personen
+ .map(section => {
+ return {
+ title: section.title,
+ personen: section.personen.filter(persoon => regex.test(persoon.name))
+ };
+ })
+ .filter(section => section.personen.length > 0);
+}
+
+function getSuggestionValue(suggestion) {
+ return suggestion.name;
+}
+
+function renderSuggestion(suggestion) {
+ return (
+ {suggestion.name}
+ );
+}
+
+function renderSectionTitle(section) {
+ return (
+ {section.title}
+ );
+}
+
+function getSectionSuggestions(section) {
+ return section.personen;
+}
+
+class App extends React.Component {
+ constructor() {
+ super();
+
+ this.state = {
+ value: '',
+ suggestions: []
+ };
+ }
+
+ onChange = (event, { newValue, method }) => {
+ this.setState({
+ value: newValue
+ });
+ };
+
+ onSuggestionsFetchRequested = ({ value }) => {
+ this.setState({
+ suggestions: getSuggestions(value)
+ });
+ };
+
+ onSuggestionsClearRequested = () => {
+ this.setState({
+ suggestions: []
+ });
+ };
+
+ render() {
+ const { value, suggestions } = this.state;
+ const inputProps = {
+ placeholder: "Type 'c'",
+ value,
+ onChange: this.onChange
+ };
+
+ return (
+
+ );
+ }
+}
+
+ReactDOM.render(, document.getElementById('app'));
diff --git a/components/data/style.css b/components/data/style.css
new file mode 100644
index 0000000..e69de29
diff --git a/components/groups/index.js b/components/groups/index.js
new file mode 100644
index 0000000..81e48b2
--- /dev/null
+++ b/components/groups/index.js
@@ -0,0 +1,154 @@
+import { h, Component } from 'preact';
+import base from '../../base';
+
+import Item from '../item';
+import AddItem from '../addItem';
+
+import '@material/button/dist/mdc.button.min.css';
+import style from './style';
+// import dist from 'react-autosuggest';
+import { BlockPicker } from 'react-color';
+
+export default class BoardGroup extends Component {
+ constructor(props) {
+ super(props);
+
+ this.addItem = this.addItem.bind(this);
+ this.updateItem = this.updateItem.bind(this);
+ this.removeItem = this.removeItem.bind(this);
+ this.handleDeleteGroupItems = this.handleDeleteGroupItems.bind(this);
+ this.handleColorChange = this.handleColorChange.bind(this);
+
+ this.state = {
+ items: {},
+ displayColorPicker: false,
+ color: this.props.details.color
+ };
+ }
+
+ componentWillMount(nextProps) {
+ this.ref = base.syncState(`/items/${this.props.index}/`, {
+ context: this,
+ state: 'items'
+ });
+ }
+
+ componentWillUnmount() {
+ base.removeBinding(this.ref);
+ }
+
+ addItem(item) {
+ // update our state
+ const items = { ...this.state.items };
+ // add in our new fish
+ const timestamp = Date.now();
+ items[`item_${timestamp}`] = item;
+ // set state
+ this.setState({ items });
+ }
+
+ updateItem(key, updatedOpdracht) {
+ const items = { ...this.state.items };
+ items[key] = updatedOpdracht;
+ this.setState({ items });
+ }
+
+ handleChange(e, key) {
+ const group = this.props.details;
+ const updatedGroup = {
+ ...group,
+ [e.target.name]: e.target.value
+ };
+ this.props.updateGroup(key, updatedGroup);
+ }
+
+ removeItem = (key) => {
+ const items = { ...this.state.items };
+ items[key] = null;
+ this.setState({ items });
+ };
+
+ handleColorClick = () => {
+ this.setState({ displayColorPicker: !this.state.displayColorPicker });
+ };
+
+ handleColorClose = () => {
+ this.setState({ displayColorPicker: false });
+ };
+
+ handleColorChange = (color) => {
+ this.setState({ color: color.hex });
+ const group = this.props.details;
+ const updatedGroup = {
+ ...group,
+ color: this.state.color
+ };
+ this.props.updateGroup(this.props.index, updatedGroup);
+ };
+
+ handleDeleteGroupItems(){
+ base.remove(`/items/${this.props.index}`);
+ this.props.removeGroup(this.props.index);
+ }
+
+ render() {
+ const details = this.props.details;
+ return (
+
+
+
+
+
+ this.handleChange(e, this.props.index)} type="text" value={details.name} placeholder="This is a example header (Click to edit)" />
+ |
+ Door wie |
+ p2 |
+ p3 |
+ p4 |
+ status |
+ doel |
+ deadline |
+ hoelang erover gedaan |
+ delete |
+
+
+
+ {
+ Object
+ .keys(this.state.items)
+ .map(key => )
+ }
+
+
+
+ |
+ |
+
+
+
+ {this.state.displayColorPicker ? : null}
+
+ |
+
+
+ |
+
+
+
+
+ );
+ }
+}
diff --git a/components/groups/style.css b/components/groups/style.css
new file mode 100644
index 0000000..3906950
--- /dev/null
+++ b/components/groups/style.css
@@ -0,0 +1,119 @@
+.groupWrap{
+ width: 100%;
+ padding: 15px;
+ position: relative;
+}
+
+.deleteItem{
+ position: absolute;
+ right: 2px;
+ display: none;
+ background:none;
+ border: none;
+ outline: none;
+ border: 1px solid #cecece;
+ border-radius: 3px;
+}
+
+.groupWrap:hover .deleteItem{
+ display: block;
+}
+
+.group{
+ width: 100%;
+ display: table;
+}
+
+.group thead{
+ width: 100%;
+ padding: 2px 0 6px 7.5px;
+ display: block;
+}
+
+.group thead tr{
+ display: table-row;
+ /* width: 100%; */
+}
+
+.group thead th{
+ text-align: center;
+ text-overflow: ellipsis;
+ /* overflow: hidden; */
+ white-space: nowrap;
+ font-size: 13px;
+ font-weight: 300;
+ /* margin: 0 1px; */
+ /* padding: 0 0px; */
+ display: table-cell;
+ width: 10%;
+}
+
+.group tbody{
+ width: 100%;
+}
+
+.inputHeader{
+ background: none;
+ border: none;
+ outline: none;
+ text-align: left;
+ font-size: 18px;
+ width: 100%;
+ min-width: 300px;
+ margin: 0 1px 0 0;
+ border: 0.5px dotted transparent;
+}
+
+.inputHeader:focus{
+ border: 0.5px dotted #eee;
+}
+
+.color {
+ height: 36px;
+ border-radius: 2px;
+ background: deeppink;
+ width: 100%;
+ display: block;
+}
+
+.swatch {
+ padding: 0px;
+ background: #fff;
+ border-radius: 2px;
+ /* box-shadow: 0 0 0 1px rgba(0,0,0,.1); */
+ cursor: pointer;
+ color: white;
+ display: block;
+ text-align: center;
+ line-height: 35px;
+ box-shadow: 0 2px 4px -1px rgba(0,0,0,.2), 0 4px 5px 0 rgba(0,0,0,.14), 0 1px 10px 0 rgba(0,0,0,.12);
+}
+
+.popover {
+ position: absolute;
+ z-index: 2;
+ top: 40px;
+ left: 0;
+ border-radius: 6px;
+ width: 100%;
+ box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
+}
+
+.cover {
+ position: fixed;
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ left: 0px;
+}
+
+.wrapColor{
+ display: inline-block;
+ position: relative;
+ width: 100%;
+ margin-left: 0px;
+}
+
+.tdAddItem{
+ padding: 0;
+}
\ No newline at end of file
diff --git a/components/header/index.js b/components/header/index.js
new file mode 100644
index 0000000..0f4b1e1
--- /dev/null
+++ b/components/header/index.js
@@ -0,0 +1,47 @@
+import { h, Component } from 'preact';
+import { Link } from 'preact-router/match';
+import userMenu from '../user';
+import style from './style';
+
+import logo from '../../assets/img/logo.svg';
+import UserMenu from '../user/index';
+
+export default class Header extends Component {
+ constructor() {
+ super();
+ this.renderLoggedInNav = this.renderLoggedInNav.bind(this);
+ }
+
+ renderLoggedInNav() {
+ return (
+
+
+
+ );
+ }
+ render() {
+ if (this.props.uid !== null) {
+ return ;
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/components/header/style.css b/components/header/style.css
new file mode 100644
index 0000000..cdd94a3
--- /dev/null
+++ b/components/header/style.css
@@ -0,0 +1,79 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+.header {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 50px;
+ padding: 0;
+ background: #9c27b0;
+ color: white;
+ z-index: 50;
+ display: flex;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
+}
+
+.headWrap{
+ height: 100%;
+ display: inline-block;
+ position: relative;
+ flex: 1 1 75%;
+}
+
+.headWrap nav {
+ float: right;
+ font-size: 100%;
+}
+
+.headWrap nav a {
+ display: inline-block;
+ height: 50px;
+ line-height: 50px;
+ padding: 0 15px;
+ min-width: 50px;
+ text-align: center;
+ background: rgba(255,255,255,0);
+ text-decoration: none;
+ color: #fff;
+ vertical-align: top;
+}
+
+/* .headWrap nav a div{
+ width: 100%;
+} */
+
+.headWrap nav a.boooooooi {
+ padding: 0;
+}
+
+.headWrap nav a.boooooooi div {
+ width: 50px;
+}
+
+.headWrap nav a div div {
+ top: 50px !important;
+}
+
+.headWrap nav a div div ul li p{
+ padding-left: 15px;
+}
+
+.headWrap nav a div div ul li{
+ transition: all .3s ease;
+ background: #fff;
+}
+
+.headWrap nav a div div ul li:hover{
+ background-color: #f3f3f3;
+}
+
+.headWrap nav a:hover,
+.headWrap nav a:active {
+ background: #9a67ea;
+ color: #fff
+}
+
+.header nav a.active {
+ background: #320b86;
+ color: #ffffff;
+}
\ No newline at end of file
diff --git a/components/item/index.js b/components/item/index.js
new file mode 100644
index 0000000..168ce64
--- /dev/null
+++ b/components/item/index.js
@@ -0,0 +1,149 @@
+import { h, Component } from 'preact';
+import style from './style';
+import SelectPerson from '../selectPerson';
+import SelectStatus from '../selectStatus';
+
+import trashIcon from '../../assets/img/trash-alt.svg';
+
+export default class Item extends Component {
+ handleChange(e, key) {
+ const item = this.props.details;
+ const updatedOpdracht = {
+ ...item,
+ [e.target.name]: e.target.value
+ };
+ this.props.updateItem(key, updatedOpdracht);
+ }
+
+
+ render() {
+ const details = this.props.details;
+ const index = this.props.index;
+ return (
+
+
+
+ this.handleChange(e, this.props.index)}
+ type="text"
+ value={details.desc}
+ placeholder="This is a example description (Click to edit)"
+ />
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+ this.handleChange(e, this.props.index)}
+ type="date"
+ value={details.finishGoal}
+ placeholder="dd/mm/yyyy"
+ />
+
+ |
+
+
+ this.handleChange(e, this.props.index)}
+ type="date"
+ value={details.deadline}
+ placeholder="dd/mm/yyyy"
+ />
+
+ |
+
+
+ this.handleChange(e, this.props.index)}
+ type="number"
+ value={details.tooktime}
+ placeholder="000"
+ />
+
+ |
+
+
+
+
+ |
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/item/style.css b/components/item/style.css
new file mode 100644
index 0000000..bc9eb1f
--- /dev/null
+++ b/components/item/style.css
@@ -0,0 +1,106 @@
+tbody{
+ display: table-row-group
+}
+
+tbody tr.tableRow{
+ /* width: 100%; */
+ display: table-row;
+}
+
+tbody tr.tableRow td{
+ margin: 1px;
+ border-bottom: 1px solid #e6e6e6;
+ white-space: nowrap;
+ padding: 0;
+ width: 10%;
+ display: table-cell;
+}
+
+.innerWrap{
+ background: #f0f0f0;
+ padding: 0;
+ height: 35px;
+ color: #596496;
+ display: block;
+ text-decoration: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ outline: none;
+ width: auto;
+ font-size: 13px;
+}
+
+.innerWrap input{
+ background: none;
+ width: 100%;
+ height: 100%;
+ border: none;
+ outline: none;
+ box-shadow: none;
+ padding: 5px 10px;
+ display: flex;
+ color: #596496;
+ font-size: 13px;
+ font-family: Arial, Helvetica, sans-serif;
+ text-align: center;
+}
+
+.innerWrap input.inputDesc{
+ /* width: 20vw; */
+ min-width: 250px;
+ text-align: left;
+}
+
+.perwrap {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.personimg{
+ height: 70%;
+}
+
+.suggestionContent {
+ display: flex;
+ align-items: center;
+ background-repeat: no-repeat;
+}
+
+button.deleteItem{
+ background: none;
+ outline: none;
+ border: none;
+ border-radius: none;
+ box-shadow: none;
+ display: block;
+ width: 100%;
+ height: 35px;
+ padding: 3px;
+ margin: 0;
+}
+
+button.deleteItem img{
+ height: 25px;
+}
+
+input.deadline{
+ padding: 2px;
+}
+
+/* input.deadline::before{
+ content: '';
+} */
+input.deadline::-webkit-datetime-edit-year-field:not([aria-valuenow]),
+input.deadline::-webkit-datetime-edit-month-field:not([aria-valuenow]),
+input.deadline::-webkit-datetime-edit-day-field:not([aria-valuenow]) {
+ color: transparent;
+}
+
+/* ::-webkit-datetime-edit-month-field { color: blue; }
+::-webkit-datetime-edit-day-field { color: green; }
+::-webkit-datetime-edit-year-field { color: purple; } */
\ No newline at end of file
diff --git a/components/newBoard/index.js b/components/newBoard/index.js
new file mode 100644
index 0000000..3c6922f
--- /dev/null
+++ b/components/newBoard/index.js
@@ -0,0 +1,27 @@
+import { h, Component } from 'preact';
+import style from './style';
+
+export default class NewBoard extends Component{
+ createBoard(event) {
+ event.preventDefault();
+ const board = {
+ name: this.name.value,
+ };
+ this.props.addBoard(board);
+ this.addBoardForm.reset();
+ }
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+NewBoard.propTypes = {
+ addBoard: Component.PropTypes.func.isRequired
+};
\ No newline at end of file
diff --git a/components/newBoard/style.css b/components/newBoard/style.css
new file mode 100644
index 0000000..90ac371
--- /dev/null
+++ b/components/newBoard/style.css
@@ -0,0 +1,67 @@
+.newboard{
+ display: flex;
+ align-items: center;
+ padding: 10px;
+}
+
+.newboard img{
+ height: 18px;
+ margin: 5px
+}
+
+.newboardForm{
+ width: 100%;
+ display: flex;
+ padding: 0;
+ margin: 0;
+}
+
+.newboardForm input{
+ width: 90%;
+ background: none;
+ box-shadow: none;
+ outline: none;
+ border: none;
+ border-bottom: 2px solid #A09C9C;
+ font-size: 17px;
+ padding: 10px;
+ margin: 0;
+ color: #333;
+ transition: all .2s ease-in-out;
+}
+
+.newboardForm input::placeholder{
+ color: #A09C9C;
+}
+
+.newboardForm button{
+ background: none;
+ outline: none;
+ border: none;
+ box-shadow: none;
+ /* border: 2px solid #f44336; */
+ border-bottom: 2px solid #A09C9C;
+ font-size: 20px;
+ color: #ba000d;
+ padding: 0 10px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all .2s ease;
+}
+
+.newboardForm input:focus{
+ border-color: #ff7961;
+ color: #f44336;
+}
+
+
+.newboardForm input:focus + button{
+ border-color: #ff7961;
+}
+
+.newboardForm button:hover{
+ background: #ff7961;
+ color: #fafafa;
+ border-color: #ff7961;
+}
\ No newline at end of file
diff --git a/components/newGroup/index.js b/components/newGroup/index.js
new file mode 100644
index 0000000..d6cee0e
--- /dev/null
+++ b/components/newGroup/index.js
@@ -0,0 +1,66 @@
+import { h, Component } from 'preact';
+import { BlockPicker } from 'react-color';
+import Textfield from 'preact-material-components/Textfield';
+import 'preact-material-components/Textfield/style.css';
+import style from './style';
+
+export default class NewGroup extends Component {
+ state = {
+ displayColorPicker: false,
+ color: '#f47373'
+ }
+
+ // handleTest = (event) => {
+ // console.log(this.value);
+ // }
+
+ createGroup(event) {
+ event.preventDefault();
+ const group = {
+ name: this.name.value,
+ color: this.state.color
+ };
+ this.props.addGroup(group);
+ this.addGroupForm.reset();
+ }
+
+ handleClick = () => {
+ this.setState({ displayColorPicker: !this.state.displayColorPicker });
+ };
+
+ handleClose = () => {
+ this.setState({ displayColorPicker: false });
+ };
+
+ handleChange = (color) => {
+ this.setState({ color: color.hex });
+ };
+
+ render() {
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/newGroup/style.css b/components/newGroup/style.css
new file mode 100644
index 0000000..1b83f37
--- /dev/null
+++ b/components/newGroup/style.css
@@ -0,0 +1,94 @@
+.newGroup{
+ display: block;
+ width: 100%;
+ padding: 0 17px;
+}
+
+.newGroupForm{
+ width: 100%;
+ display: flex;
+}
+
+.newGroupForm input{
+ width: 90%;
+ background: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ outline: none;
+ border: none;
+ border-left: 7.5px solid #eee;
+ border-top: 1px solid #eee;
+ border-right: 1px solid #eee;
+ border-bottom: 1px solid #eee;
+ font-size: 14px;
+ padding: 10px;
+ margin: 0;
+ color: #333;
+ -webkit-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+ height: 35px;
+}
+
+.newGroupForm input:focus{
+ border-color: #f44336;
+ color: #333;
+}
+
+.newGroupH3{
+ margin: 0;
+ padding: 0;
+}
+
+.color {
+ height: 36px;
+ border-radius: 2px;
+ background: deeppink;
+ width: 100%;
+ display: block;
+}
+
+.swatch {
+ padding: 0px;
+ background: #fff;
+ border-radius: 2px;
+ /* box-shadow: 0 0 0 1px rgba(0,0,0,.1); */
+ cursor: pointer;
+ color: white;
+ display: block;
+ text-align: center;
+ line-height: 35px;
+ box-shadow: 0 2px 4px -1px rgba(0,0,0,.2), 0 4px 5px 0 rgba(0,0,0,.14), 0 1px 10px 0 rgba(0,0,0,.12);
+}
+
+.popover {
+ position: absolute;
+ z-index: 2;
+ top: 40px;
+ left: 0;
+ border-radius: 6px;
+ width: 100%;
+ box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
+}
+
+.cover {
+ position: fixed;
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ left: 0px;
+}
+
+.wrapColor{
+ display: inline-block;
+ position: relative;
+ width: 15%;
+ margin-left: 2px;
+}
+
+.tdAddItem{
+ padding: 0;
+}
+
+h3{
+ font-weight: 400;
+}
\ No newline at end of file
diff --git a/components/selectPerson/index.js b/components/selectPerson/index.js
new file mode 100644
index 0000000..151c502
--- /dev/null
+++ b/components/selectPerson/index.js
@@ -0,0 +1,234 @@
+import { h, Component } from 'preact';
+import Autosuggest from 'react-autosuggest';
+
+const uuidv4 = require('uuid/v4');
+
+import base from '../../base';
+import style from './style';
+
+const personen = [
+ {
+ title: 'MV',
+ personen: [
+ {
+ name: 'Yannick Frisart',
+ functie: 'Front-end',
+ img: 'https://20578.tk/board/user-profilepics/yannick.png'
+ },
+ {
+ name: 'Thijs van Rijn',
+ functie: 'Designer',
+ img: 'https://20578.tk/board/user-profilepics/thijs.png'
+ }
+ ]
+ },
+ {
+ title: 'MD',
+ personen: [
+ {
+ name: 'Rick Woltheus',
+ functie: 'Back-end',
+ img: 'https://20578.tk/board/user-profilepics/rick.png'
+ },
+ {
+ name: 'Coen Filipsen',
+ functie: 'Communicatie',
+ img: 'https://20578.tk/board/user-profilepics/coen.png'
+ }
+ ]
+ },
+ {
+ title: 'Stagiairs',
+ personen: [
+ {
+ name: 'Maurice',
+ functie: 'Stagair',
+ img: 'https://20578.tk/board/user-profilepics/none.png'
+ },
+ {
+ name: 'Patrick',
+ functie: 'Stagair',
+ img: 'https://20578.tk/board/user-profilepics/none.png'
+ }
+ ]
+ },
+ {
+ title: 'Clear',
+ personen: [
+ {
+ name: '',
+ functie: 'reset',
+ img: 'https://20578.tk/board/user-profilepics/none.png'
+ }
+ ]
+ }
+];
+
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters
+function escapeRegexCharacters(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
+function getSuggestions(value) {
+ const escapedValue = escapeRegexCharacters(value.trim());
+
+ if (escapedValue === '') {
+ return personen;
+ }
+
+ // const regex = new RegExp('^' + escapedValue, 'i');
+
+ return personen;
+}
+
+function getSuggestionValue(suggestion) {
+ return suggestion.name;
+}
+
+function renderSuggestion(suggestion) {
+ return (
+
+

+
{suggestion.name}
+
{suggestion.functie}
+
+ );
+}
+
+function renderSectionTitle(section) {
+ return (
+ {section.title}
+ );
+}
+
+function getImg(newValue) {
+ if (newValue === 'Yannick Frisart') {
+ return 'https://20578.tk/board/user-profilepics/yannick.png';
+ }
+ else if (newValue === 'Thijs van Rijn') {
+ return 'https://20578.tk/board/user-profilepics/thijs.png';
+ }
+ else if (newValue === 'Rick Woltheus') {
+ return 'https://20578.tk/board/user-profilepics/rick.png';
+ }
+ else if (newValue === 'Coen Filipsen') {
+ return 'https://20578.tk/board/user-profilepics/coen.png';
+ }
+ else if (newValue === 'Maurice') {
+ return 'https://20578.tk/board/user-profilepics/none.png';
+ }
+ else if (newValue === 'Patrick') {
+ return 'https://20578.tk/board/user-profilepics/none.png';
+ }
+ return 'https://20578.tk/board/user-profilepics/none.png';
+}
+
+function getSectionSuggestions(section) {
+ return section.personen;
+}
+
+// const renderInputComponent = inputProps => (
+//
+// );
+
+export default class SelectPerson extends Component {
+ constructor(props) {
+ super(props);
+ // Autosuggest is a controlled component.
+ // This means that you need to provide an input value
+ // and an onChange handler that updates this value (see below).
+ // Suggestions also need to be provided to the Autosuggest,
+ // and they are initially empty because the Autosuggest is closed.
+
+ this.state = {
+ value: '',
+ imgProfilePic: 'https://20578.tk/board/user-profilepics/none.png',
+ suggestions: [],
+ randomKey: ''
+ };
+ }
+
+ componentWillMount(nextProps) {
+ base.fetch(`/items/${this.props.groupI}/${this.props.index}/${this.props.personI}`, {
+ context: this,
+ then(data){
+ this.setState({
+ value: data,
+ imgProfilePic: getImg(data)
+ });
+ }
+ });
+ this.setState({
+ randomKey: uuidv4()
+ });
+ }
+
+ onChange = (event, { newValue, method }) => {
+ this.setState({
+ value: newValue,
+ imgProfilePic: getImg(newValue)
+ });
+ const item = this.props.details;
+ const updatedOpdracht = {
+ ...item,
+ [this.props.personI]: newValue
+ };
+ this.props.updateItem(this.props.index, updatedOpdracht);
+ };
+
+ onSuggestionsFetchRequested = ({ value }) => {
+ this.setState({
+ suggestions: getSuggestions(value)
+ });
+ };
+
+ onSuggestionsClearRequested = () => {
+ this.setState({
+ suggestions: []
+ });
+ };
+
+
+ render() {
+ const { value, suggestions } = this.state;
+ const inputProps = {
+ placeholder: 'Asign a person',
+ value,
+ onChange: this.onChange
+ };
+
+ const renderInputComponent = inputProps => (
+
+ );
+
+ // Finally, render it!
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/selectPerson/style.css b/components/selectPerson/style.css
new file mode 100644
index 0000000..8ceb077
--- /dev/null
+++ b/components/selectPerson/style.css
@@ -0,0 +1,159 @@
+.container {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+
+input.input {
+ /* width: 100%;
+ height: 100%; */
+ display: inline-block;
+ /* padding: 10px 20px; */
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+ font-size: 16px;
+ border: none;
+ padding: 0;
+ /* border: 1px solid #aaa; */
+ /* border-radius: 4px; */
+ width: 0px;
+ height: 0px;
+}
+
+input.inputFocused {
+ outline: none;
+ /* width: 100%;
+ height: 100%;
+ padding: 10px 20px; */
+}
+
+/* input.inputFocused + label{
+ display: none;
+} */
+
+input.inputOpen {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.suggestionsContainer {
+ display: none;
+}
+
+.suggestionsContainerOpen {
+ display: block;
+ position: absolute;
+ top: 36px;
+ width: 280px;
+ height: auto;
+ background-color: #fafafa;
+ box-shadow: 0px 3px 3px -2px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 1px 8px 0px rgba(0, 0, 0, 0.12);
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+ font-size: 16px;
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+ z-index: 2;
+}
+
+.suggestionsList {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ display: block;
+}
+
+.suggestion {
+ cursor: pointer;
+ padding: 10px 20px;
+ display: block
+}
+
+.suggestionHighlighted {
+ background-color: #ddd;
+}
+
+.sectionContainer {
+ border-top: 1px dashed #ccc;
+ display: block;
+}
+
+.sectionContainerFirst {
+ border-top: 0;
+ display: block;
+}
+
+.sectionTitle {
+ padding: 10px 0 0 10px;
+ font-size: 12px;
+ color: #777;
+ display: block
+}
+
+.suggestionName{
+ font-size: 16px;
+ color: #596496;
+ flex: 1 0;
+}
+
+.suggestionFunctie{
+ font-size: 12px;
+ vertical-align: bottom;
+}
+
+.suggestionWrapper{
+ display: flex;
+ width: 100%;
+ height: 100%;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.assignedOpdrachtPic{
+ height: 30px;
+ margin: 0 15px 0 0;
+}
+
+.inputPersonAssign{
+ position: relative;
+ width: 100%;
+ display: block;
+ height: 100%;
+}
+
+input.inputFieldPersonAssign{
+ width: 0px;
+ height: 0px;
+ appearance: none;
+}
+
+.inputPersonAssignWrap{
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.inputPersonAssignWrap:focus{
+ display: none;
+}
+
+.inputPersonAssignImg{
+ height: 80%;
+}
+
+/* .wrapInputBoi{
+ width: 0px;
+ height: 0px;
+ overflow: hidden;
+} */
+
+.wrapInputBoi input:focus{
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/components/selectStatus/index.js b/components/selectStatus/index.js
new file mode 100644
index 0000000..d5c5efd
--- /dev/null
+++ b/components/selectStatus/index.js
@@ -0,0 +1,223 @@
+import { h, Component } from 'preact';
+import Autosuggest from 'react-autosuggest';
+
+const uuidv4 = require('uuid/v4');
+
+import base from '../../base';
+import style from './style';
+
+const statusses = [
+ {
+ title: 'Done',
+ statusses: [
+ {
+ name: 'Done',
+ color: '#00c875'
+ },
+ {
+ name: 'Ready for testing',
+ color: '#0086c0'
+ }
+ ]
+ },
+ {
+ title: 'In process',
+ statusses: [
+ {
+ name: 'Working on it',
+ color: '#fdab3d'
+ },
+ {
+ name: 'Work needed (rejected)',
+ color: '#a25ddc'
+ },
+ {
+ name: `Need help (I'm stuck)`,
+ color: '#e2445c'
+ }
+ ]
+ },
+ {
+ title: 'To do',
+ statusses: [
+ {
+ name: 'To do',
+ color: '#c4c4c4'
+ },
+ {
+ name: 'Cancelled',
+ color: '#a00037'
+ }
+ ]
+ }
+];
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters
+function escapeRegexCharacters(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
+function getSuggestions(value) {
+ // const escapedValue = escapeRegexCharacters(value.trim());
+
+ return statusses;
+
+ // const regex = new RegExp('^' + escapedValue, 'i');
+
+ // return statusses
+ // .map(section => {
+ // return {
+ // title: section.title,
+ // statusses: section.statusses.filter(status => regex.test(status.name)),
+ // color: section.statusses.filter(status => regex.test(status.color))
+ // };
+ // })
+ // .filter(section => section.statusses.length > 0);
+}
+
+function getSuggestionValue(suggestion) {
+ return suggestion.name;
+}
+
+function renderSuggestion(suggestion) {
+ return (
+
+ {suggestion.name}
+
+ );
+}
+
+function renderSectionTitle(section) {
+ return (
+ {section.title}
+ );
+}
+
+function getColor(newValue) {
+ if (newValue === 'Done') {
+ return '#00c875';
+ }
+ else if (newValue === 'Ready for testing') {
+ return '#0086c0';
+ }
+ else if (newValue === 'Working on it') {
+ return '#fdab3d';
+ }
+ else if (newValue === 'Work needed (rejected)') {
+ return '#a25ddc';
+ }
+ else if (newValue === `Need help (I'm stuck)`) {
+ return '#e2445c';
+ }
+ else if (newValue === 'To do') {
+ return '#c4c4c4'
+ }
+ else if (newValue === 'Cancelled') {
+ return '#a00037'
+ }
+}
+
+function getSectionSuggestions(section) {
+ return section.statusses;
+}
+
+// const renderInputComponent = inputProps => (
+//
+// );
+
+export default class SelectStatus extends Component {
+ constructor(props) {
+ super(props);
+ // Autosuggest is a controlled component.
+ // This means that you need to provide an input value
+ // and an onChange handler that updates this value (see below).
+ // Suggestions also need to be provided to the Autosuggest,
+ // and they are initially empty because the Autosuggest is closed.
+
+ this.state = {
+ value: '',
+ color: '#c4c4c4',
+ suggestions: [],
+ randomKey: ''
+ };
+ getColor(this.state.value);
+ }
+
+ componentWillMount(nextProps) {
+ base.fetch(`/items/${this.props.groupI}/${this.props.index}/status`, {
+ context: this,
+ then(data){
+ this.setState({
+ value: data,
+ color: getColor(data)
+ });
+ }
+ });
+ this.setState({
+ randomKey: uuidv4()
+ })
+ }
+
+ onChange = (event, { newValue, method }) => {
+ this.setState({
+ value: newValue,
+ color: getColor(newValue)
+ });
+ const item = this.props.details;
+ const updatedOpdracht = {
+ ...item,
+ [this.props.statusI]: newValue
+ };
+ this.props.updateItem(this.props.index, updatedOpdracht);
+ };
+
+ onSuggestionsFetchRequested = ({ value }) => {
+ this.setState({
+ suggestions: getSuggestions(value)
+ });
+ };
+
+ onSuggestionsClearRequested = () => {
+ this.setState({
+ suggestions: []
+ });
+ };
+
+
+ render() {
+ const { value, suggestions } = this.state;
+ const inputProps = {
+ placeholder: 'Asign a status',
+ value,
+ onChange: this.onChange
+ };
+
+ const renderInputComponent = inputProps => (
+
+ );
+
+ // Finally, render it!
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/selectStatus/style.css b/components/selectStatus/style.css
new file mode 100644
index 0000000..17c18af
--- /dev/null
+++ b/components/selectStatus/style.css
@@ -0,0 +1,111 @@
+.container {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+
+input.input {
+ width: 100%;
+ height: 100%;
+ display: inline-block;
+ padding: 10px 20px;
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+ font-size: 16px;
+ border: none;
+ color: white;
+ /* padding: 0; */
+ /* border: 1px solid #aaa; */
+ /* border-radius: 4px; */
+ /* width: 0px; */
+ /* height: 0px; */
+}
+
+input.input::placeholder{
+ color: white;
+}
+
+input.inputFocused {
+ outline: none;
+ width: 100%;
+ height: 100%;
+ padding: 10px 20px;
+}
+
+input.inputOpen {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.suggestionsContainer {
+ display: none;
+}
+
+.suggestionsContainerOpen {
+ display: block;
+ position: absolute;
+ top: 36px;
+ width: 280px;
+ background-color: #fafafa;
+ box-shadow: 0px 3px 3px -2px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 1px 8px 0px rgba(0, 0, 0, 0.12);
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+ font-size: 16px;
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+ z-index: 2;
+}
+
+.suggestionsList {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ display: block;
+}
+
+.suggestion {
+ cursor: pointer;
+ padding: 10px 20px;
+ display: block
+}
+
+.suggestionHighlighted {
+ background-color: #ddd;
+}
+
+.sectionContainer {
+ border-top: 1px dashed #ccc;
+ display: block;
+}
+
+.sectionContainerFirst {
+ border-top: 0;
+ display: block;
+}
+
+.sectionTitle {
+ padding: 10px 0 0 10px;
+ font-size: 12px;
+ color: #777;
+ display: block
+}
+
+.suggestionName{
+ font-size: 16px;
+ color: #596496;
+ flex: 1 0;
+}
+
+.suggestionFunctie{
+ font-size: 12px;
+ vertical-align: bottom;
+}
+
+.suggestionWrapper{
+ display: flex;
+ width: 100%;
+ height: 100%;
+ justify-content: flex-start;
+ align-items: center;
+}
diff --git a/components/sideNav/index.js b/components/sideNav/index.js
new file mode 100644
index 0000000..77ccb42
--- /dev/null
+++ b/components/sideNav/index.js
@@ -0,0 +1,34 @@
+import { h, Component } from 'preact';
+import { Link } from 'preact-router/match';
+import style from './style';
+import '@material/list/dist/mdc.list.min.css';
+
+import BoardLink from '../boardLink';
+import NewBoard from '../newBoard';
+
+export default class Sidenav extends Component {
+ render({ teamName }, { addBoard }) {
+ return (
+
+ );
+ }
+}
+
+Sidenav.propTypes = {
+ addBoard: Component.PropTypes.func.isRequired
+};
\ No newline at end of file
diff --git a/components/sideNav/style.css b/components/sideNav/style.css
new file mode 100644
index 0000000..7e0dcb9
--- /dev/null
+++ b/components/sideNav/style.css
@@ -0,0 +1,69 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+.sidebar{
+ width: 25vw;
+ min-height: calc(100vh - 50px);
+ max-width: 250px;
+ background: #f5f5f5;
+ padding: 0;
+ /* padding-top: 1px; */
+ margin: 0;
+ box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
+ z-index: 2;
+ position: fixed;
+ left: 0;
+ top: 50px
+}
+
+.sidebar nav{
+ display: flex;
+ flex-direction: column;
+}
+
+.sidebar nav a{
+ color: #222;
+ padding: 12.5px 25px;
+ text-decoration: none;
+ margin: 0;
+ /* flex: 3; */
+}
+
+.sidebar nav a:hover,
+.sidebar nav a:active,
+.sidebar nav a:hover + a:nth-child(2),
+.sidebar nav a:active + a:nth-child(2){
+ background: #320b86;
+ color: #fff
+}
+
+.sidebar nav a.activeBoard {
+ background: #9a67ea;
+ color: #ffffff;
+}
+
+.boardLinkHeader {
+ padding: 10px 0 5px 15px;
+ margin: 0;
+ font-weight: 700;
+ font-size: 1.5em;
+}
+
+.boardLinkWrapper{
+ border-bottom: 1px solid #666666;
+ border-top: 1px solid #666666;
+ display: flex;
+ flex-direction: column;
+}
+
+nav .boardLinkWrapper a{
+ /* padding: 10px 35px; */
+ flex: 4 0 90%;
+ height: 100%;
+}
+
+nav .boardLinkWrapper a:nth-child(2){
+ padding: 0;
+ flex: 1 2 5%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
\ No newline at end of file
diff --git a/components/teamCard/index.js b/components/teamCard/index.js
new file mode 100644
index 0000000..4f6e56d
--- /dev/null
+++ b/components/teamCard/index.js
@@ -0,0 +1,39 @@
+import { h, Component } from 'preact';
+import ConfirmLeave from '../confirmLeave';
+import style from './style';
+import Card from 'preact-material-components/Card';
+import { Link } from 'preact-router';
+import 'preact-material-components/Card/style.css';
+import 'preact-material-components/Button/style.css';
+
+export default class TeamCard extends Component {
+ constructor() {
+ super();
+
+ const colors = ['#F47373', '#697689', '#37D67A', '#2CCCE4', '#ff8a65', '#ba68c8', '#e91e63', '#673ab7', '#3f51b5', '#2196f3', '#009688', '#ffc107'];
+ this.state = {
+ background: colors[Math.floor(12 * Math.random())]
+ };
+ }
+ render() {
+ return (
+
+
+
+
+ {this.props.index}
+
+
+
+
+
+
+ show
+
+
+
+
+
+ );
+ }
+}
diff --git a/components/teamCard/style.css b/components/teamCard/style.css
new file mode 100644
index 0000000..f40a75b
--- /dev/null
+++ b/components/teamCard/style.css
@@ -0,0 +1,38 @@
+.cardWrap{
+ display: inline-block;
+ width: 20%;
+ min-width: 300px;
+ margin: 10px 5px;
+}
+
+.cardWrap h1{
+ font-size: 25px;
+ text-transform: uppercase;
+ color: white;
+}
+
+.cardBackcolor{
+ background: #333;
+ color: white;
+ margin-left: -16px;
+ margin-top: -16px;
+ margin-right: -16px;
+ margin-bottom: -16px;
+ height: 175px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+}
+
+.cardWrap button{
+ width: 100%;
+}
+
+.linkCard{
+ width: 100%;
+ width: calc(50% - 8px);
+ margin-right: 8px;
+}
+
+/* fix the button margin */
\ No newline at end of file
diff --git a/components/teamInfo/index.js b/components/teamInfo/index.js
new file mode 100644
index 0000000..ae19a59
--- /dev/null
+++ b/components/teamInfo/index.js
@@ -0,0 +1,21 @@
+import { h, Component } from 'preact';
+import BoardCard from '../boardcard';
+
+import style from './style';
+
+export default class TeamInfo extends Component {
+ render() {
+ return (
+
+
+
{this.props.teamname}
+ {
+ Object
+ .keys(this.props.boards)
+ .map(key =>
)
+ }
+
+
+ );
+ }
+}
diff --git a/components/teamInfo/style.css b/components/teamInfo/style.css
new file mode 100644
index 0000000..95016b6
--- /dev/null
+++ b/components/teamInfo/style.css
@@ -0,0 +1,7 @@
+.headWrap{
+ display: block;
+}
+
+.team{
+ padding: 15px;
+}
\ No newline at end of file
diff --git a/components/user/index.js b/components/user/index.js
new file mode 100644
index 0000000..f22d8b9
--- /dev/null
+++ b/components/user/index.js
@@ -0,0 +1,59 @@
+import { h, Component } from 'preact';
+import Menu from 'preact-material-components/Menu';
+import Button from 'preact-material-components/Button';
+import 'preact-material-components/List/style.css';
+import 'preact-material-components/Menu/style.css';
+import 'preact-material-components/Button/style.css';
+import style from './style';
+
+export default class UserMenu extends Component {
+ render() {
+ return (
+
+
+
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/components/user/style.css b/components/user/style.css
new file mode 100644
index 0000000..5acf589
--- /dev/null
+++ b/components/user/style.css
@@ -0,0 +1,27 @@
+nav a.boooi{
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+ vertical-align: top;
+}
+
+nav a.boooi div.mdc-menu-anchor div{
+ top: 50px !important;
+}
+
+nav a.booi div.booi2{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+a.boooi{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+div.boooooi{
+ top: 50px !important;
+}
\ No newline at end of file
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..7d52a71
--- /dev/null
+++ b/index.js
@@ -0,0 +1,5 @@
+import './style';
+import App from './components/app';
+
+export default App;
+
diff --git a/routes/Teams/index.js b/routes/Teams/index.js
new file mode 100644
index 0000000..1924a9e
--- /dev/null
+++ b/routes/Teams/index.js
@@ -0,0 +1,69 @@
+import { h, Component } from 'preact';
+import style from './style';
+import base from '../../base';
+import TeamCard from '../../components/teamCard';
+import CreateTeam from '../../components/createTeam';
+
+export default class Teams extends Component {
+ constructor() {
+ super();
+
+ this.removeTeam = this.removeTeam.bind(this);
+ this.addTeam = this.addTeam.bind(this);
+ }
+
+ state = {
+ teams: {}
+ }
+
+ componentWillMount(nextProps, nextState){
+ this.ref = base.syncState(`users/${this.props.uuid}/teams`, {
+ context: this,
+ state: 'teams'
+ });
+ }
+
+
+ componentWillUpdate(nextProps, nextState){
+ this.ref = base.syncState(`users/${this.props.uuid}/teams`, {
+ context: this,
+ state: 'teams'
+ });
+ }
+
+ componentWillUnmount() {
+ base.removeBinding(this.ref);
+ }
+
+ removeTeam = (key) => {
+ const teams = { ...this.state.teams };
+ teams[key] = null;
+ this.setState({ teams });
+ base.remove(`teams/${key}/members/${this.props.uuid}`);
+ };
+
+ addTeam(team) {
+ // update our state
+ const teams = { ...this.state.teams };
+ // Add in our team
+ teams[team.name] = true;
+ // set state
+ this.setState({ teams });
+ }
+
+ render() {
+ return (
+
+
teams
+
+ {
+ Object
+ .keys(this.state.teams)
+ .map(key => )
+ }
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/routes/Teams/style.css b/routes/Teams/style.css
new file mode 100644
index 0000000..7495a46
--- /dev/null
+++ b/routes/Teams/style.css
@@ -0,0 +1,93 @@
+.content{
+ display: block;
+ width: 100%;
+}
+
+.content h2{
+ text-align: center;
+}
+
+.teamsContent{
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
+.cardWrap{
+ display: inline-block;
+ width: 20%;
+ min-width: 300px;
+ margin: 5px;
+}
+
+.cardWrap h1{
+ font-size: 25px;
+ text-transform: uppercase;
+ color: white;
+}
+
+.cardBackcolor{
+ background: #9c27b0;
+ color: white;
+ margin-left: -16px;
+ margin-top: -16px;
+ margin-right: -16px;
+ margin-bottom: -16px;
+ height: 175px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+}
+
+.buttonSubmit{
+ font-family: Roboto, sans-serif;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-size: 0.875rem;
+ font-weight: 500;
+ letter-spacing: 0.04em;
+ line-height: 2.25rem;
+ text-decoration: none;
+ text-transform: uppercase;
+ display: inline-block;
+ position: relative;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ min-width: 88px;
+ height: 36px;
+ padding: 0 16px;
+ border: none;
+ outline: none;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-appearance: none;
+ overflow: hidden;
+ vertical-align: middle;
+ border-radius: 2px;
+ color: white;
+}
+
+.teamInput{
+ height: 35px;
+ width: 142px;
+ margin-left: 0px;
+ margin-right: 8px;
+ padding: 5px 10px;
+ border: none;
+ border-bottom: 2px solid #eee;
+ background: none;
+ color: #333;
+ font-size: 15px;
+}
+
+.teamInput:focus{
+ border: none;
+ outline: none;
+ border-bottom: 2px solid #9c27b0;
+ color: #9c27b0;
+}
\ No newline at end of file
diff --git a/routes/board/index.js b/routes/board/index.js
new file mode 100644
index 0000000..456e4f7
--- /dev/null
+++ b/routes/board/index.js
@@ -0,0 +1,75 @@
+import { h, Component } from 'preact';
+import style from './style';
+
+import BoardGroup from '../../components/groups';
+import NewGroup from '../../components/newGroup';
+import base from '../../base';
+
+export default class Board extends Component {
+ constructor() {
+ super();
+ this.addGroup = this.addGroup.bind(this);
+ this.updateGroup = this.updateGroup.bind(this);
+ this.removeGroup = this.removeGroup.bind(this);
+ this.state = {
+ groups: {}
+ };
+ }
+
+
+ componentWillMount(nextProps) {
+ this.ref = base.syncState(`/groups/${this.props.boardName}`, {
+ context: this,
+ state: 'groups'
+ });
+ }
+
+ componentWillUnmount() {
+ base.removeBinding(this.ref);
+ }
+
+ addGroup(group) {
+ // update our state
+ const groups = { ...this.state.groups };
+ // add in our new group
+ const timestamp = Date.now();
+ groups[`group_${timestamp}`] = group;
+ // set state
+ this.setState({ groups });
+ }
+
+ updateGroup(key, updatedGroup) {
+ const groups = { ...this.state.groups };
+ groups[key] = updatedGroup;
+ this.setState({ groups });
+ }
+
+ removeGroup = (key) => {
+ const groups = { ...this.state.groups };
+ groups[key] = null;
+ this.setState({ groups });
+ };
+
+ render({ teamname }, { boards, members, user }) {
+ return (
+
+
{teamname}
+
+ {
+ Object
+ .keys(this.state.groups)
+ .map(key => )
+ }
+
+ {/* */}
+
+
+ );
+ }
+}
+
+// , {boards, members, user}
diff --git a/routes/board/style.css b/routes/board/style.css
new file mode 100644
index 0000000..d5429b5
--- /dev/null
+++ b/routes/board/style.css
@@ -0,0 +1,15 @@
+.board{
+ width: calc(100% - 250px);
+ height: auto;
+ max-height: calc(100vh - 50px);
+}
+
+.board::-webkit-scrollbar{
+ display: none;
+}
+
+.boardGroupWrapper{
+ width: 100%;
+ display: block;
+ height: auto;
+}
\ No newline at end of file
diff --git a/routes/home/index.js b/routes/home/index.js
new file mode 100644
index 0000000..e80ccdc
--- /dev/null
+++ b/routes/home/index.js
@@ -0,0 +1,15 @@
+import { h, Component } from 'preact';
+import { Link } from 'preact-router/match';
+import style from './style';
+
+export default class Home extends Component {
+ render() {
+ return (
+
+
Home
+
This is the Home component.
+
go to Webgem
+
+ );
+ }
+}
diff --git a/routes/home/style.css b/routes/home/style.css
new file mode 100644
index 0000000..803eb57
--- /dev/null
+++ b/routes/home/style.css
@@ -0,0 +1,6 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+.home {
+ padding: 90px 20px;
+ min-height: 100%;
+ width: 100%;
+}
diff --git a/routes/login/index.js b/routes/login/index.js
new file mode 100644
index 0000000..9606774
--- /dev/null
+++ b/routes/login/index.js
@@ -0,0 +1,57 @@
+import { h, Component } from 'preact';
+import style from './style';
+
+import webgemLogo from '../../assets/img/logo_webgem.svg';
+
+export default class Login extends Component {
+ renderLogin() {
+ return (
+
+
+
+
+
+
+
+

+
+
+
+
+
+
Login
+
+ {/*
*/}
+
+
+
+
+
+
+
+
+ );
+ }
+ render() {
+ if (!this.props.uid) {
+ return {this.renderLogin()}
;
+ }
+ return (
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/routes/login/style.css b/routes/login/style.css
new file mode 100644
index 0000000..a8965f2
--- /dev/null
+++ b/routes/login/style.css
@@ -0,0 +1,220 @@
+/* Login page */
+.login{
+ display: flex;
+ justify-content: center;
+ width: 62.11%;
+ box-sizing: border-box;
+ min-width: 360px;
+ flex-direction: row;
+ align-items: center;
+ height: 650px;
+ box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
+ border-radius: 15px;
+ background: linear-gradient(228.62deg, #FF3CAC 0%, #784BA0 51.53%, #2B86C5 100%);
+ overflow: hidden;
+}
+
+/* login Wrapper */
+.loginWrap{
+ display: flex;
+ box-sizing: border-box;
+ justify-content: center;
+ align-items: center;
+ height: calc(100vh - 50px);
+ width: 100%;
+ background-blend-mode: overlay;
+ background: linear-gradient(225deg, rgba(250, 217, 97, 0.6) 0%, rgba(255, 90, 206, 0.6) 100%);
+}
+
+.loginWrap *{
+ box-sizing: border-box
+}
+
+.loginWith{
+ display: flex;
+ justify-content: space-around;
+ flex-wrap: wrap;
+ align-items: stretch;
+ width: 100%;
+ margin-top: 50px;
+}
+
+.loginWith button{
+ border: none;
+ outline: none;
+ padding: 10px;
+ border-radius: 4px;
+}
+
+.signup{
+ width: 50%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background-image: url("https://20578.tk/board/background-pics/background-login@2x.jpg");
+ background-size: cover;
+ background-position: center;
+ position: relative;
+}
+
+.loginhalf{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ width: 50%;
+ background: white;
+ height: 100%;
+}
+
+.lineSub {
+ height: 3px;
+ width: 80%;
+ opacity: 0.8;
+ box-shadow: 0 0 2px 0 rgba(0,0,0,0.12);
+ background: linear-gradient(225deg, #FAD961 0%, #FF5ACD 100%);
+ display: block;
+ margin: 1.76% 0;
+}
+
+.lineMain {
+ height: 3px;
+ width: 100%;
+ box-shadow: 0 0 2px 0 rgba(0,0,0,0.12);
+ background: linear-gradient(225deg, #FAD961 0%, #FF5ACD 100%);
+ display: block;
+ margin: 15px 0;
+}
+
+.logoWrap{
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ flex-direction: column;
+ width: 55%;
+ z-index: 3;
+}
+
+.logoImg{
+ height: 35px;
+}
+
+.backgroundGradient{
+ background: linear-gradient(228.62deg, #FF3CAC 0%, #784BA0 51.53%, #2B86C5 100%);
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ opacity: 0.52;
+}
+
+.loginHalf h2{
+ height: 42px;
+ width: 104px;
+ color: #4A4A4A;
+ font-family: Roboto;
+ font-size: 36px;
+ font-weight: 900;
+ line-height: 42px;
+ text-align: center;
+}
+
+.loginHalfH2{
+ margin: 0;
+ color: #393939;
+ font-family: Roboto;
+ font-size: 36px;
+ font-weight: 900;
+ line-height: 37px;
+ text-align: center;
+ text-transform: uppercase;
+}
+
+button.loginBut{
+ background: linear-gradient(75deg ,#7028E4 -30%, #4776E6 120%);
+ border: none;
+ outline: none;
+ text-align: center;
+ width: 300px;
+ height: 50px;
+ border-radius: 25px;
+ color: white;
+ margin: 5px 0;
+ color: #FFFFFF;
+ font-family: Roboto;
+ font-size: 19px;
+ font-weight: 300;
+}
+
+.lineLogin{
+ width: 80%;
+ background: linear-gradient(225deg, #FF3CAC 0%, #784BA0 51.53%, #2B86C5 100%);
+ height: 4px;
+ margin-bottom: 10px;
+ margin-top: 3px;
+}
+
+/* Form login */
+.loginForm{
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 75%;
+}
+
+.loginForm input{
+ width: 90%;
+ height: 40px;
+ border: none;
+ outline: none;
+ color: #888888;
+ font-family: Roboto;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 28px;
+ display: inline-block;
+ border-bottom: 2px solid rgba(20%,20%,20%,0.2);
+ transition: all .3s ease;
+}
+
+.loginForm input:focus{
+ outline: none;
+ border-color: rgba(20%,20%,20%,0.5);
+}
+
+.loginForm input::placeholder{
+ opacity: 0.2;
+ transition: all .3s ease;
+}
+
+.loginForm input:focus::placeholder{
+ opacity: 0.8;
+}
+
+.loginForm label{
+ display: inline-block;
+ width: 10%;
+}
+
+.loginForm .inputWrap{
+ margin: 5px 0;
+ width: 100%;
+}
+
+.loginSubmit {
+ width: 100%;
+ color: #86149D;
+ font-family: Roboto;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 33px;
+ border: none;
+ outline: none;
+ background: none;
+ text-align: right;
+ padding: 10px;
+ padding-right: 20px;
+}
\ No newline at end of file
diff --git a/routes/profile/index.js b/routes/profile/index.js
new file mode 100644
index 0000000..566f7a6
--- /dev/null
+++ b/routes/profile/index.js
@@ -0,0 +1,47 @@
+import { h, Component } from 'preact';
+import style from './style';
+
+export default class Profile extends Component {
+ state = {
+ time: Date.now(),
+ count: 10
+ };
+
+ // gets called when this route is navigated to
+ componentDidMount() {
+ // start a timer for the clock:
+ this.timer = setInterval(this.updateTime, 1000);
+ }
+
+ // gets called just before navigating away from the route
+ componentWillUnmount() {
+ clearInterval(this.timer);
+ }
+
+ // update the current time
+ updateTime = () => {
+ this.setState({ time: Date.now() });
+ };
+
+ increment = () => {
+ this.setState({ count: this.state.count+1 });
+ };
+
+ // Note: `user` comes from the URL, courtesy of our router
+ render({ user }, { time, count }) {
+ return (
+
+
Profile: {user}
+
This is the user profile for a user named { user }.
+
+
Current time: {new Date(time).toLocaleString()}
+
+
+
+ {' '}
+ Clicked {count} times.
+
+
+ );
+ }
+}
diff --git a/routes/profile/style.css b/routes/profile/style.css
new file mode 100644
index 0000000..52453e1
--- /dev/null
+++ b/routes/profile/style.css
@@ -0,0 +1,6 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+.profile {
+ padding: 90px 20px;
+ min-height: 100%;
+ width: 100%;
+}
diff --git a/routes/team/index.js b/routes/team/index.js
new file mode 100644
index 0000000..deae3b7
--- /dev/null
+++ b/routes/team/index.js
@@ -0,0 +1,95 @@
+import { h, Component } from 'preact';
+import style from './style';
+import Sidenav from '../../components/sideNav';
+
+import base from '../../base';
+import { Router, route } from 'preact-router';
+import Board from '../board/index';
+import TeamInfo from '../../components/teamInfo/index';
+// import BoardLink from '../../components/boardLink/index';
+// import {PropTypes} from 'preact-compat';
+
+export default class Team extends Component {
+ constructor() {
+ super();
+ this.addBoard = this.addBoard.bind(this);
+ this.removeBoard = this.removeBoard.bind(this);
+ // this.removeFish = this.removeFish.bind(this);
+ // this.updateFish = this.updateFish.bind(this);
+ // this.loadSamples = this.loadSamples.bind(this);
+ // this.addToOrder = this.addToOrder.bind(this);
+ // this.removeFromOrder = this.removeFromOrder.bind(this);
+ }
+
+ state = {
+ boards: {},
+ members: {},
+ key: '032412'
+ }
+
+ componentWillMount(nextProps) {
+ this.ref = base.syncState(`teams/${this.props.teamName}/boards`, {
+ context: this,
+ state: 'boards'
+ });
+ this.ref2 = base.syncState(`teams/${this.props.teamName}/members`, {
+ context: this,
+ state: 'members'
+ });
+ }
+
+ componentWillUnmount() {
+ base.removeBinding(this.ref);
+ base.removeBinding(this.ref2);
+ }
+
+ handleRoute = e => {
+ this.setState({ key: Math.random() });
+ this.currentUrl = e.url;
+ };
+
+ addBoard(board) {
+ // update our state
+ const boards = { ...this.state.boards };
+ // add in our new fish
+ const timestamp = Date.now();
+ boards[`board-${timestamp}`] = board;
+ // set state
+ this.setState({ boards });
+ }
+
+ removeBoard = (key) => {
+ const boards = { ...this.state.boards };
+ base.fetch(`groups/${key}/`, {
+ context: this,
+ then(data) {
+ Object
+ .keys(data)
+ .map(key => base.remove(`/items/${key}`));
+ base.remove(`groups/${key}`);
+ }
+ });
+ boards[key] = null;
+ this.setState({ boards });
+ route(`/team/${this.props.teamName}/`, true);
+ };
+
+ render({ teamName }, { boards, members, user }) {
+ return (
+
+ );
+ }
+}
+// , {boards, members, user}
diff --git a/routes/team/style.css b/routes/team/style.css
new file mode 100644
index 0000000..d43c6b3
--- /dev/null
+++ b/routes/team/style.css
@@ -0,0 +1,37 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+.team{
+ padding: 0;
+ min-height: 100%;
+ width: 100%;
+}
+
+.team *{
+ display: inline-block;
+ vertical-align: top;
+}
+
+.team * table{
+ display: table;
+}
+.team * tr{
+ display: table-row;
+}
+.team * td{
+ display: table-cell;
+}
+.team * th{
+ display: table-cell;
+}
+
+.hiddenSide{
+ width: 25vw;
+ min-height: calc(100vh - 50px);
+ max-width: 250px;
+ background: #f5f5f5;
+ padding: 0;
+ /* padding-top: 1px; */
+ margin: 0;
+ z-index: 2;
+ left: 0;
+ top: 50px
+}
\ No newline at end of file
diff --git a/style/index.css b/style/index.css
new file mode 100644
index 0000000..4e416f5
--- /dev/null
+++ b/style/index.css
@@ -0,0 +1,48 @@
+/* https://material.io/color/#!/?view.left=0&view.right=0&primary.color=F5F5F5&secondary.color=D81B60 */
+
+/* updated Color theme: https://material.io/color/#!/?view.left=0&view.right=0&primary.color=673AB7&secondary.color=F44336&secondary.text.color=FAFAFA */
+:root{
+ --mdc-theme-primary: #9c27b0;
+ --theme-primary--light: #9a67ea;
+ --theme-primary--dark: #320b86;
+ --mdc-theme-secondary: #f44336;
+ --theme-secondary--light: #ff7961;
+ --theme-secondary--dark: #ba000d;
+ --mdc-theme-background: #fafafa;
+}
+html, body {
+ height: 100%;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ background: #FAFAFA;
+ font-family: 'Roboto', sans-serif;
+ font-weight: 300;
+ color: #444;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body{
+ padding: 50px 0 0 0;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+button{
+ background-color: var(--mdc-theme-primary);
+}
+
+.mdc-button--accent{
+ background-color: var(--mdc-theme-secondary);
+}
+
+h1,h2,h3,h4,h5,h6{
+ font-weight: 400;
+}
+
+h2{
+ margin-left: 18px;
+}
\ No newline at end of file