<file_sep>import React from "react";
import "./styles.css";

const loading = props =>
    props.loading && (
        <div
            style={{ width: `${props.size}px`, height: `${props.size}px` }}
            className="spinner"
        ></div>
    );

export default loading;
<file_sep>import React, { Component } from "react";

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { creators as authActions } from '../../../store/ducks/auth'

import HoursOfDayForm from "./components/HoursOfDayForm";
import Menu from './components/Menu'
import Result from './components/Result/Result'
import List from "./components/List";
import Loading from '../../shared/loading'

class CompTime extends Component {

  render() {
    return (
      <section className="container">
          {this.props.auth.user.email && 
            <div className="row">
                <div className="grid-item-6 align-center content-center">
                    Logado como: {this.props.auth.user.email} <button onClick={() => this.props.logOut()}>Sair</button>
                </div>
            </div>        
          }
        <HoursOfDayForm />
        <div className="row align-center space-between">
            <div className="grid-item-4 block">
                <Menu/>
            </div>
            <div className="grid-item-2">
                <Result/>
            </div>
        </div>
        <List/>
      </section>
    );
  }
}

const mapStateToProps = state => ({
    auth: state.auth,
    loading: state.global.loading
});

const mapDispatchToProps = dispatch =>
  bindActionCreators(authActions, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(CompTime)
<file_sep>import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import './static/css/setup.css'
import './static/icons/style.css'
import './static/css/layout.css'
import './static/css/utils.css'
import './static/css/form.css'
import './static/css/button.css'

ReactDOM.render(<App />, document.getElementById('root'));
<file_sep>import React, { Component } from 'react';

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import { creators as comptimeCreators } from "../../../../store/ducks/comptime";

class components extends Component {

    changeYear = e => {
        this.props.setMonthSelected("");
        this.props.setYearSelected(e.target.value);
    };

    changeMonth = e => {
        let month = `${e.target.value < 10 ? "0" : ""}${e.target.value}`;
        this.props.setMonthSelected(month);
        if (!!month == false) return;
        this.props.getComptimeList(this.props.auth.user.userId, this.props.yearSelected, month);
    };

    pastYears = () => {
        let years = []
        let currentYear = new Date().getFullYear()
        let startYear = 2019
        while ( startYear <= currentYear ) {
            years.push(startYear++);
        }  
        return years         
    }

    pastMonths = () => {
        let currentDate = new Date()
        let currentMonth = this.props.yearSelected == currentDate.getFullYear() ? currentDate.getMonth() + 1 : 12
        let months = []
        let monthsRaw = [
            {key: "1", label: "Janeiro"},
            {key: "2", label: "Fevereiro"},
            {key: "3", label: "Março"},
            {key: "4", label: "Abril"},
            {key: "5", label: "Maio"},
            {key: "6", label: "Junho"},
            {key: "7", label: "Julho"},
            {key: "8", label: "Agosto"},
            {key: "9", label: "Setembro"},
            {key: "10", label: "Outubro"},
            {key: "11", label: "Novembro"},
            {key: "12", label: "Dezembro"}
        ]
        for (let index = 1; index <= currentMonth; index++) {
            months.push(monthsRaw[index-1])
        }
        return months
    }

    render() {
        return (
            <form noValidate className="row block">
                    <div className="grid-item-6 pt-4">
                        <div className="input-box">
                            <label>Ano</label>
                            <select
                                value={this.props.yearSelected}
                                onChange={e => this.changeYear(e)}
                            >
                                <option value="">Selecione uma opção</option>
                                {
                                    this.pastYears().map( (year, index) => <option key={index} value={year}>{year}</option>)
                                }
                            </select>
                        </div>
                    </div>
                    <div className="grid-item-6 pt-4">
                        <div className="input-box">
                            <label>Mês</label>
                            <select
                                value={this.props.monthSelected}
                                disabled={!!this.props.yearSelected == false}
                                onChange={e => this.changeMonth(e)}
                            >
                                <option value="">Selecione uma opção</option>
                                {
                                    this.pastMonths().map( (month, index) => <option key={index} value={month.key}>{month.label}</option>)
                                }
                            </select>
                        </div>
                    </div>
            </form>
        );
    }
}

const mapStateToProps = state => ({
    auth: state.auth,
    yearSelected: state.comptime.yearSelected,
    monthSelected: state.comptime.monthSelected,    
});

const mapDispatchToProps = dispatch =>
    bindActionCreators(comptimeCreators, dispatch);

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(components);
<file_sep>import React from 'react';
import './styles.css'

const Card = (props) => (
    <div className="card">
        <div className="card__inner">
            {props.withHeader && 
                <div className="card__header">
                    {props.withHeader}
                </div>}
                <div className="card__content">
                    {props.children}
                </div>
                {props.withFooter && 
                <div className="card__footer">
                    {props.withFooter}
                </div>}    
        </div>
    </div>    
);

export default Card;
<file_sep>import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'
import history from '../../history'

import global from './_global'
import auth from './auth'
import comptime from './comptime'

export default combineReducers({
    global,
    auth,
    comptime,
    router: connectRouter(history)
})<file_sep>import { takeLatest, put, call, delay } from "redux-saga/effects";
import { creators as globalCreators } from "../../ducks/_global";
import { types as comptimeTypes } from "../../ducks/comptime";
import { creators as comptimeCreators } from "../../ducks/comptime";
import rsfb from "../../services/firebaseConfig";
import { push } from "connected-react-router";

function* getComptimeList(action) {
  yield put(comptimeCreators.setComptimeList([]));
  let { idUsuario, ano, mes } = action.payload;
  yield put(globalCreators.loading(true));
  const querySnapshot = yield call(
    rsfb.firestore.getCollection,
    `usuarios/${idUsuario}/${ano}${mes}`
  );
  let comptimeList = [];
  let comptimeId = "";
  querySnapshot.forEach(res => {
    let comptime = res.data().comptimeList;
    comptimeId = res.id;
    comptimeList = [...comptimeList, ...comptime];
  });
  // console.log(comptimeId)
  // console.log(comptimeList)
  if (!!comptimeList.length) {
    yield put(comptimeCreators.setComptimeListId(comptimeId));
    yield put(comptimeCreators.setComptimeList(comptimeList));
    yield calcTotalHoursBank(comptimeList);
  } else {
    console.log("no comptimelist, creating a new one");
    yield createNewComptimeList(action, idUsuario, ano, mes);
  }
  yield put(globalCreators.loading(false));
}

function* calcTotalHoursBank(comptimeList) {
  if (!!comptimeList.length == false) return false;
  let hours = 0,
    minutes = 0,
    negativeMinutes = false;

  comptimeList.map(item => {
    hours = item.difference.hours + hours;
    minutes = item.difference.minutes + minutes;
  });

  minutes < 0 ? negativeMinutes = true : negativeMinutes = false

  if (Math.abs(minutes) > 59 && negativeMinutes) {
    let convertedTime = yield timeConvert(Math.abs(minutes));
    hours = hours - convertedTime.hours;
    minutes = convertedTime.minutes;
  } else if (Math.abs(minutes) > 59 && (negativeMinutes == false)) {
    let convertedTime = yield timeConvert(Math.abs(minutes));
    hours = hours + convertedTime.hours;
    minutes = convertedTime.minutes;
  }

  if (hours > 0 && negativeMinutes) {
    hours = hours - 1 
    hours = `${hours < 10 ? "0" : ""}${hours}`
    minutes = 60 - (Math.abs(minutes));
  } else if(hours < 0 && negativeMinutes) {
    hours = hours = `-${hours < 10 ? "0" : ""}${Math.abs(hours)}`
    minutes = `${Math.abs(minutes) < 10 ? "0" : ""}${Math.abs(minutes)}`
  } else if(hours < 0 && !negativeMinutes) {
    hours = hours = `-${hours < 10 ? "0" : ""}${Math.abs(hours)}`
  } else if(hours == 0 && negativeMinutes) {
    hours = `-${hours < 10 ? "0" : ""}${Math.abs(hours)}`
    minutes = `${Math.abs(minutes) < 10 ? "0" : ""}${Math.abs(minutes)}`    
  } else {
    hours = `${hours < 10 ? "0" : ""}${hours}`
    minutes = `${Math.abs(minutes) < 10 ? "0" : ""}${Math.abs(minutes)}`   
  }
  let hoursBank = {
    hours,
    minutes
  };
  yield put(comptimeCreators.setHoursBank(hoursBank));
}

function* timeConvert(n) {
    var num = n;
    var hours = (num / 60);
    var rhours = Math.floor(hours);
    var minutes = (hours - rhours) * 60;
    var rminutes = Math.round(minutes);
    return {
        hours: rhours,
        minutes: rminutes
    };
}

function* putComptimeList(action) {
  yield put(globalCreators.loading(true));
  let { idUsuario, ano, mes, id, comptimeList } = action.payload;
  // console.log(id)
  yield call(
    rsfb.firestore.updateDocument,
    `usuarios/${idUsuario}/${ano}${mes}/${id}`,
    { comptimeList }
  );
  yield put(
    globalCreators.message({ type: "positive", text: "Comptime List updated!" })
  );
  yield delay(1000);
  yield put(globalCreators.message({ type: "", text: "" }));
  yield getComptimeList(action);
  yield put(comptimeCreators.setShowingForm(false));
}

function* createNewComptimeList(action) {
  let { idUsuario, ano, mes } = action.payload;
  let numberOfDays = new Date(ano, mes, 0).getDate();
  let comptimeList = [];
  for (let i = 1; i <= numberOfDays; i++) {
    let item = {
      day: `${i < 10 ? "0" : ""}${i}/${mes}/${ano}`,
      startingTime: "08:00",
      lunchStart: "12:00",
      lunchEnd: "13:00",
      stoppingTime: "17:00",
      difference: {
        hours: 0,
        minutes: 0
      }
    };
    comptimeList.push(item);
  }
  yield call(rsfb.firestore.addDocument, `usuarios/${idUsuario}/${ano}${mes}`, {
    comptimeList
  });
  yield getComptimeList(action);
}

export default [
  takeLatest(comptimeTypes.GET_COMPTIMELIST, getComptimeList),
  takeLatest(comptimeTypes.PUT_COMPTIMELIST, putComptimeList)
];
<file_sep>import React, { Component } from 'react';

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import { creators as comptimeCreators } from '../../../../store/ducks/comptime'

import TimeInput from 'react-keyboard-time-input';

import Modal from '../../../shared/modal'
import Loading from '../../../shared/loading'

class components extends Component {

    handleInputChange = (e, field) => {
        if( (typeof e == 'string') && Number(e.substr(0,2)) > 23) return false        
        const comptime = { ...this.props.comptime }
        comptime[field] = e
        this.props.setComptime(comptime)
    } 

    updateComptime = async (e) => {
        e.preventDefault()
        if(this.checkTime('startingTime') == false ) return false
        if(this.checkTime('lunchStart') == false ) return false
        if(this.checkTime('lunchEnd') == false ) return false
        if(this.checkTime('stoppingTime') == false ) return false
        let id = this.props.comptimeListId
        let comptimeList = [...this.props.comptimeList]
        let comptimeIndex = comptimeList.findIndex( item => item.day == this.props.comptime.day)
        let hoursBank = await this.calcHoursBankOfDay(this.props.comptime)
        await this.handleInputChange(hoursBank, 'difference')       
        comptimeList[comptimeIndex] = { ...comptimeList[comptimeIndex], ...this.props.comptime }
        this.props.putComptimeList(
          this.props.auth.user.userId,
          this.props.yearSelected,
          this.props.monthSelected,
          id,
          comptimeList
        );    
        console.log(comptimeList)   
    }

    americanDate(date) {
        let datePart = date.match(/\d+/g),
        year = datePart[0].substring(0),
        month = datePart[1], day = datePart[2];
        return day+'-'+month+'-'+year;
    }   
    
    calcHoursBankOfDay(comptime) {
        let workSchedule = 8 //in hours
        
        let startingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['startingTime']}:00`)
        let stoppingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['stoppingTime']}:00`)
        let lunchStart = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchStart']}:00`)
        let lunchEnd = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchEnd']}:00`)

        let diffMsStartStop = (stoppingTime - startingTime);
        let diffMsLunchTime = (lunchEnd - lunchStart);
        let hoursDoneLunch = Math.floor((diffMsLunchTime % 86400000) / 3600000)
        let minutesDoneLunch = Math.round(((diffMsLunchTime % 86400000) % 3600000) / 60000) 
        //anulando o banco de horas gerado por bater a volta do almoço mais cedo do que 1 hora
        if(hoursDoneLunch < 1) {
            hoursDoneLunch = 1
            minutesDoneLunch = 0
        }  
        let hoursDone = (Math.floor((diffMsStartStop % 86400000) / 3600000) ) - (hoursDoneLunch)
        let minutesDone = Math.round(((diffMsStartStop % 86400000) % 3600000) / 60000) - (minutesDoneLunch)
        
        let totalDone = {
            hours: Number,
            minutes: Number
        }
        if((hoursDone >= workSchedule) || minutesDone == '00') {
            totalDone.hours = hoursDone - workSchedule
            totalDone.minutes = minutesDone
        } else {
            totalDone.hours =  (hoursDone - workSchedule) + 1
            totalDone.minutes = (60 - minutesDone) * -1
        }
        
        return totalDone
    }

    checkTime = (field) => {
        const comptime = { ...this.props.comptime }
        switch(field) {
            case 'startingTime':
                var startingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['startingTime']}:00`)
                var lunchStart = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchStart']}:00`)
                if(startingTime > lunchStart)
                {
                    alert('O horário de entrada deve ser anterior à hora de entrada do almoço.')
                    return false
                }
                break
            case 'lunchStart':
                var lunchStart = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchStart']}:00`)
                var startingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['startingTime']}:00`)
                var lunchEnd = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchEnd']}:00`)
                if(lunchStart < startingTime)
                {
                    alert('O horário de almoço deve ser depois da hora de entrada.')
                    return false
                }
                if(lunchStart > lunchEnd)
                {
                    alert('O horário de entrada do almoço deve ser anterior a hora de saida do almoço.')
                    return false
                }
                break
            case 'lunchEnd':
                var lunchEnd = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchEnd']}:00`)
                var lunchStart = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchStart']}:00`)
                var stoppingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['stoppingTime']}:00`)
                if(lunchEnd < lunchStart)
                {
                    alert('O horário de saída do almoço deve ser depois da hora de entrada do almoço.')
                    return false
                }
                if(lunchEnd > stoppingTime)
                {
                    alert('O horário de saída do almoço deve ser anterior à hora de saída.')
                    return false
                }
                break
            case 'stoppingTime':
                var stoppingTime = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['stoppingTime']}:00`)
                var lunchEnd = new Date(`${this.americanDate(this.props.comptime.day)} ${comptime['lunchEnd']}:00`)
                if(stoppingTime < lunchEnd)
                {
                    alert('O horário de saída deve ser maior que o horário de saída do almoço.')
                    return false
                }
                break
            default:
                return true
        }
    }

    render() {
        return <div>   
            <Modal showing={this.props.showingForm}
                   close={() => this.props.setShowingForm(false)}>
                    <h1>{this.props.comptime.day}</h1>
                    <form noValidate onSubmit={(e) => this.updateComptime(e)}>
                        <div className="row">
                            <div className="grid-item-6">
                                <div className="input-box">
                                    <label>Entrada</label>
                                    <TimeInput value={this.props.comptime.startingTime} onChange={(e) => this.handleInputChange(e, 'startingTime')}/>
                                </div>                             
                            </div>
                        </div>
                        <div className="row">
                            <div className="grid-item-6">
                                <div className="input-box">
                                    <label>Entrada do almoço</label> 
                                    <TimeInput value={this.props.comptime.lunchStart}
                                           onChange={(e) => this.handleInputChange(e, 'lunchStart')} type="text"/>
                                </div>                             
                            </div>
                        </div>
                        <div className="row">
                            <div className="grid-item-6">
                                <div className="input-box">
                                    <label>Saída do almoço</label> 
                                    <TimeInput value={this.props.comptime.lunchEnd}
                                           onChange={(e) => this.handleInputChange(e, 'lunchEnd')} type="text"/>
                                </div>                             
                            </div>
                        </div>
                        <div className="row">
                            <div className="grid-item-6">
                                <div className="input-box">
                                    <label>Saída</label> 
                                    <TimeInput value={this.props.comptime.stoppingTime}
                                           onChange={(e) => this.handleInputChange(e, 'stoppingTime')} type="text"/>
                                </div>                             
                            </div>
                        </div>
                        <div className="row">
                            <div className="grid-item-6">
                                    {this.props.loading ? <Loading loading={this.props.loading} size={22}/> : <button className="block">Salvar</button>}                          
                            </div>
                        </div>
                    </form>
            </Modal>        
        </div>;
    }
}

const mapStateToProps = state => ({
    auth: state.auth,
    yearSelected: state.comptime.yearSelected,
    monthSelected: state.comptime.monthSelected,
    comptime: state.comptime.comptime,
    comptimeList: state.comptime.comptimeList,
    comptimeListId: state.comptime.comptimeListId,
    showingForm: state.comptime.showingForm,
    loading: state.global.loading
});

const mapDispatchToProps = dispatch =>
  bindActionCreators(comptimeCreators, dispatch);

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(components);
<file_sep>export const types = {
    //saga types
    GET_COMPTIMELIST: "comptime/ASYNC_GET_COMPTIMELIST",
    PUT_COMPTIMELIST: "comptime/ASYNC_PUT_COMPTIMELIST",
    //normal types
    SET_YEAR: 'comptime/SET_YEAR',
    SET_MONTH: 'comptime/SET_MONTH',
    SET_COMPTIMELIST_ID: 'comptime/SET_COMPTIMELIST_ID',
    SET_COMPTIMELIST: "comptime/SET_COMPTIMELIST",
    SET_HOURSBANK: "comptime/SET_HOURSBANK",
    SET_SHOWINGFORM: "comptime/SET_SHOWINGFORM",
    SET_COMPTIME: "comptime/SET_COMPTIME",
}

export const creators = {
    //saga creators
    getComptimeList: (idUsuario, ano, mes) => ({ 
        type: types.GET_COMPTIMELIST,
        payload: {
            idUsuario,
            ano,
            mes
        }
    }),     
    putComptimeList: (idUsuario, ano, mes, id, comptimeList, onClose) => ({
        type: types.PUT_COMPTIMELIST,
        payload: {
            idUsuario,
            ano,
            mes,
            id,
            comptimeList,
            onClose
        }
    }),    
    //normal creators  
    setYearSelected:(year) => ({ 
        type: types.SET_YEAR,
        payload: year 
    }),
    setMonthSelected:(month) => ({ 
        type: types.SET_MONTH,
        payload: month 
    }),       
    setComptimeListId:(id) => ({ 
        type: types.SET_COMPTIMELIST_ID,
        payload: id 
    }),
    setComptimeList:(comptimeList) => ({ 
        type: types.SET_COMPTIMELIST,
        payload: comptimeList 
    }),
    setHoursBank:(hoursBank) => ({ 
        type: types.SET_HOURSBANK,
        payload: hoursBank 
    }),
    setShowingForm:(boolean) => ({ 
        type: types.SET_SHOWINGFORM,
        payload: boolean 
    }),
    setComptime:(comptime) => ({ 
        type: types.SET_COMPTIME,
        payload: comptime 
    }),         
}

const INITIAL_STATE = {
    yearSelected: '',
    monthSelected: '',
    comptimeListId: '',
    comptimeList: [],
    hoursBank: {
        hours: '',
        minutes: '',
    },
    showingForm: false,
    comptime: {
        day: '',
        startingTime: '',
        lunchStart: '',
        lunchEnd: '',
        stoppingTime: '',
        difference: {
            hours: 0,
            minutes: 0
        }
    }
}

export default function comptime(state = INITIAL_STATE, action) {
    switch (action.type) {         
        case types.SET_YEAR:
            return { ...state, yearSelected: action.payload }
        case types.SET_MONTH:
            return { ...state, monthSelected: action.payload }
        case types.SET_COMPTIMELIST_ID:
            return { ...state, comptimeListId: action.payload }
        case types.SET_SHOWINGFORM:
            return { ...state, showingForm: action.payload }
        case types.SET_COMPTIMELIST:
            return { ...state, comptimeList: action.payload }
        case types.SET_HOURSBANK:
            return { ...state, hoursBank: action.payload }
        case types.SET_COMPTIME:
            return { ...state, comptime: action.payload }                                          
        default:
            return state
    }
}<file_sep>import { createStore, applyMiddleware, compose } from 'redux'
import { connectRouter, routerMiddleware } from 'connected-react-router'
import history from '../history'
import createSagaMiddleware from 'redux-saga'

import rootSaga from './sagas'
import rootReducer from './ducks'


const sagaMiddleware = createSagaMiddleware()

const middlewares = [
  sagaMiddleware,
  routerMiddleware(history),
]

//sem redux devtools
//const store = createStore(rootReducer, applyMiddleware(sagaMiddleware), )

//utilizando o redux devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(connectRouter(history)(rootReducer), composeEnhancers(
    applyMiddleware(...middlewares)
  ));

sagaMiddleware.run(rootSaga)

export default store<file_sep>import React, {Component} from 'react'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'

import { Creators as todolistActions } from '../../../store/ducks/todos'

import Header from '../../shared/header'
import Loading from '../../shared/loading'

class SecondaryPage extends Component {
    state = {
        navItems: [
            { type: "routerlink", link: "/test0", title: "title0" },
            { type: "routerlink", link: "/test1", title: "title1" },
            { type: "anchor", link: "/test2", title: "title2" }
        ]        
    }
  render() { 
    return (
        <div>
            <Header title="Template" navItems={this.state.navItems} />
            <div className="container">
                <button className="content-center align-center" onClick={() => this.props.getTodolist()}>
                    {this.props.loading ? <div className="flex"><span>Loading... </span><Loading loading={true} size={20} /></div> : "Load Todolist"}
                </button>
                {this.props.todoList.map( item => 
                    <div className="row" key={item.id}>
                        <div className="grid-item-6">
                            --- {item.title}
                        </div>
                    </div>
                )}
            </div>
        </div>
    )
  }
}

const mapStateToProps = state => ({
  todoList: state.todos.todoList,
  loading: state.global.loading
});

const mapDispatchToProps = dispatch =>
  bindActionCreators(todolistActions, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(SecondaryPage)<file_sep>export const types = {
  LOADING: "_global/LOADING",
  MESSAGE: "_global/MESSAGE",
  ERROR: "_global/ERROR"
};

export const creators = {
  loading: (bool) => ({
    type: types.LOADING,
    payload: bool
  }),
  message: message => ({
    type: types.MESSAGE,
    payload: message
  }),
  error: () => ({ type: types.ERROR })
};

const INITIAL_STATE = {
  message: { type: "", text: "" },
  loading: false,
  error: false
};

export default function global(state = INITIAL_STATE, action) {
  switch (action.type) {
    case types.LOADING:
      return { ...state, loading: action.payload };
    case types.MESSAGE:
      return { ...state, message: action.payload };
    case types.ERROR:
      return { ...state, error: !state.error };
    default:
      return state;
  }
}
<file_sep>import React, { Component } from "react";
import "./styles.css";

export default class Header extends Component {

    state = {
        active: true,
        statusClasses: ''
    }

    componentDidMount() {
        window.innerWidth >= 555 ? this.setState({ statusClasses: '' }) : this.setState({ statusClasses: 'slideFadeHeader-off' })
        window.addEventListener('resize', () => {
            if(window.innerWidth >= 555) {
                this.setState({ statusClasses: '' })
            } else {
                this.setState({ statusClasses: 'slideFadeHeader-off' })
            }
        });        
    }    

    transitionClass() {
        this.setState({ active: !this.state.active })
        this.state.active ? this.setState({ statusClasses: 'slideFadeHeader-on' }) : this.setState({ statusClasses: 'slideFadeHeader-off' })
    }    

    render() {
        return (
            <div className="header">
                <div className="header__titleContainer">
                    <h1 className="header__title">{this.props.title}</h1>
                    {
                        this.props.navItems && 
                        <button
                            className="header__navButton"
                            onClick={() => this.transitionClass()}>
                            <span className="icon-menu"></span>
                        </button>
                    }
                </div>
                <div
                    className={`header__navbar ${this.state.statusClasses}`}
                >
                    <ul>
                        {!!this.props.navItems && this.props.navItems.map( (item,index) => 
                            {
                                return (
                                    <li key={index}>
                                        {
                                            item.type !== 'routerlink' ? 
                                            <a href={item.link}>{item.title}</a> :
                                            <a href="" onClick={() => this.props.history.push(item.link)}>{item.title}</a> 
                                        }
                                    </li>
                                )
                            }
                        )}
                    </ul>
                </div>
            </div>
        );
    }
}
<file_sep>import React, { Component } from 'react';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { creators as authActions } from '../../../../store/ducks/auth'

import Loading from '../../../shared/loading'

class Signup extends Component {

    state = {
        passwordError: "",
        emailError: ""
    }

    handleInputChange = (e, field) => {
        const { user } = this.props.auth
        user[field] = e.target.value
        this.props.user(user)
        if(field == 'email') this.validateEmail()
        if(field == 'password') this.validatePassword()
    }

    validateEmail = () => {
        let email = this.props.auth.user.email
        if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
            this.setState({ emailError: "" })
        } else {
            this.setState({ emailError: "Por favor, digite um e-mail válido." })
        }
    }
    validatePassword = () => {
        let password = this.props.auth.user.password
        if(password.length >= 6) {
            this.setState({ passwordError: "" })
        } else {
            this.setState({ passwordError: "A senha deve ter, pelo menos, 6 caracteres." })
        }        
    }

    validateAndSignUp = (e) => {
        e.preventDefault()
        if(this.validateEmail() ) return false
        if(this.validatePassword() ) return false
        this.props.signUp()
    }

    render() {
        return <div className="flex flex-1 content-center align-center">
            <div className="container container-sm mb-4">
                <h1 className="text-center pt-4">Cadastro</h1>
                {this.props.message && 
                <div className="text-center pt-4">
                    <span>{this.props.message}</span>
                </div>}                
                <form noValidate onSubmit={(e) => this.validateAndSignUp(e)}>
                    <div className="row">
                        <div className="grid-item-6">
                            <div className="input-box">
                                <label>Digite um Email</label>
                                <input value={this.props.auth.user.email} onChange={(e) => this.handleInputChange(e, 'email')}/>
                                { this.state.emailError && <span className="errorMsg">{this.state.emailError}</span>}
                            </div>                             
                        </div>
                    </div>
                    <div className="row">
                        <div className="grid-item-6">
                            <div className="input-box">
                                <label>Digite uma Senha</label>
                                <input type="password" value={this.props.auth.user.password} onChange={(e) => this.handleInputChange(e, 'password')}/>
                                { this.state.passwordError && <span className="errorMsg">{this.state.passwordError}</span>}
                            </div>                             
                        </div>
                    </div>
                    <div className="row">
                        <div className="grid-item-6">
                            <div style={{ alignSelf: 'center' }}>
                                {this.props.loading ? <Loading loading={this.props.loading} size={22}/> : <button className="primary">Cadastrar</button>}
                            </div>
                            <div>
                                <button type="button" onClick={() => this.props.history.push("/signin")}>Já possui cadastro?</button> 
                            </div>                 
                        </div>
                    </div>
                </form>    
            </div>
        </div>
    }
}

const mapStateToProps = state => ({
    auth: state.auth,
    message: state.global.message.text,
    loading: state.global.loading
});

const mapDispatchToProps = dispatch =>
  bindActionCreators(authActions, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(Signup)
