Skip to content
Browse files

Finish the home page

- Create and test the navigation component.
- Test the Home controller.
- Add the html and css for the home page.
  • Loading branch information...
ggarciajr committed Jan 27, 2016
1 parent 7864f7d commit 4cbdc19c050c4a1910eaeb9cc4e909d468e9e4d9
@@ -65,7 +65,21 @@ instance Yesod App where
-- you to use normal widget features in default-layout.

pc <- widgetToPageContent $ do

-- add CDN-hosted
addStylesheetRemote "https:////"
addStylesheetRemote ",300"

-- Takes a list of css files and generate one big css file.
$(combineStylesheets 'StaticR
[ css_style_css

-- this is an array of static js files that yesod will
-- combine into one single js file and load it via a
-- <script> tag.
$(combineScripts 'StaticR
[ js_bundle_js
$(widgetFile "default-layout")
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")

@@ -0,0 +1,67 @@
import * as React from 'react';
import render from 'react-dom';

class Navigation extends React.Component {
constructor(props) {
this.state = { opened : false };

// React + ES6 has no automatically autobinding
// So we need to explicitly use .bind(this) or fat arrows.
this.toggle = this.toggle.bind(this);

toggle(e) {
this.setState({ opened: !this.state.opened })

render() {
return (
<div className="home-menu pure-menu pure-menu-horizontal pure-menu-fixed">
<div className="pure-u-1 pure-u-md-1-3">
<div className="pure-menu">
<a className="pure-menu-heading" href="#">
<i className="fa fa-clock-o"></i>
<a href="#" className="custom-toggle" id="toggle" onClick={this.toggle}>
<s className="bar"></s>
<s className="bar"></s>
<div className="pure-u-1 pure-u-md-2-3 menu-bottom" ref="menuBottom">
<div className="pure-menu pure-menu-horizontal">
<ul className="pure-menu-list">
<li className="pure-menu-item" pure-menu-selected>
<a href="#" className="pure-menu-link">{this.props.language.home}</a>
<li className="pure-menu-item">
<a href="#" className="pure-menu-link">{this.props.language.tryFree}</a>
<li className="pure-menu-item">
<a href="#" className="pure-menu-link">{this.props.language.signUp}</a>
<li className="pure-menu-item">
<a href="#" className="pure-menu-link">{this.props.language.signIn}</a>

Navigation.propTypes = {
language: React.PropTypes.shape({
title: React.PropTypes.string.isRequired,
home: React.PropTypes.string.isRequired,
signUp: React.PropTypes.string.isRequired,
signIn: React.PropTypes.string.isRequired,
tryFree: React.PropTypes.string.isRequired
export default Navigation;
@@ -0,0 +1,61 @@
import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import ReactDOM from 'react-dom'
import Navigation from './navigation';

describe('Navigation', () => {
it('Throw an error if prop language is not provide', () => {
expect(() => TestUtils.renderIntoDocument(<Navigation />)()).toThrow();

it('Throw an error if prop language.title is not provide', () => {
const lang = {};
expect(() => TestUtils.renderIntoDocument(<Navigation language={lang} />)()).toThrow();

it('Throw an error if prop language.home is not provide', () => {
const lang = {title: "Foo"};
expect(() => TestUtils.renderIntoDocument(<Navigation language={lang} />)()).toThrow();

it('Throw an error if prop language.signUp is not provide', () => {
const lang = {title: "Foo", home: "Foo"};
expect(() => TestUtils.renderIntoDocument(<Navigation language={lang} />)()).toThrow();

it('Throw an error if prop language.signIn is not provide', () => {
const lang = {title: "Foo", home: "Foo", signUp: "Foo"};
expect(() => TestUtils.renderIntoDocument(<Navigation language={lang} />)()).toThrow();

it('Throw an error if prop language.tryFree is not provide', () => {
const lang = {title: "Foo", home: "Foo", signUp: "Foo", singIn: "Foo"};
expect(() => TestUtils.renderIntoDocument(<Navigation language={lang} />)()).toThrow();

it ("Render all 5 links pluss the toggle button with the correct language", () => {
const lang = {title: "Nav Title", home: "Nav Home", signUp: "Nav Sign Up", signIn: "Nav Sign In", tryFree: "Nav Try For Free"};
const navigation = TestUtils.renderIntoDocument(<Navigation language={lang} />);
const links = ReactDOM.findDOMNode(navigation).querySelectorAll('a');
const menu = {
title: links[0].text,
toggle: { text: links[1].text , class: links[1].getAttribute('class') },
home: links[2].text,
tryFree: links[3].text,
signUp: links[4].text,
signUp: links[4].text,
signIn: links[5].text,
const expectedMenu = {
title: 'Nav Title',
toggle: { text: '' , class: 'custom-toggle' },
home: 'Nav Home',
tryFree: 'Nav Try For Free',
signUp: 'Nav Sign Up',
signIn: 'Nav Sign In',
@@ -1,4 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Navigation from './components/navigation.js';

(function() {
'use strict';
console.log("webpack is working.");
// makes Webpack to compile the scss
const navigationContainer = document.getElementById('header');
<Navigation language={navigationContainer.dataset}/>,
@@ -0,0 +1,36 @@
var webpack = require('webpack');

module.exports = function(config) {
browsers: ['Chrome'],
singleRun: true,
frameworks: ['mocha'],
files: [
preprocessors: {
'test.webpack.js': ['webpack', 'sourcemap']
reporters: ['mocha'],
plugins: [
webpack: {
module: {
loaders: [{ test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules|static/,
query: { presets: ['es2015', 'react'] }
watch: true
webpackServer: {
noInfo: true
@@ -1 +1,42 @@
Title: Flora Time Tracker
NavigationHome: Home
NavigationTryFree: Try for free
NavigationSignUp: Sign up
NavigationSignIn: Sign in

SplashHead: A simple time tracker
SplashSubHead: Track the time you spent on tasks effortlessly.
SplashButton: Get Started

FeaturesHead: Features
FeaturesTimeTrackingHead: Time Tracking
FeaturesTimeTrackingContent: Easily track the time spent on tasks of different projects.
FeaturesReportingHead: Reporting
FeaturesReportingContent: Generate HTML or CSV reports to send to your manager or client.
FeaturesDashboardHead: Friendly Dashboard
FeaturesDashboardContent: Different types of charts providing an overview of the tracked time and earned income.
FeaturesOpenSourcedHead: Open Source
FeaturesOpenSourcedContent: Contribute with the project or fork and customize it for your needs.

RibbonHead: No account needed.
RibbonContent: By using an unique url you can access your workspace and start tracking time without the need to create an account.
RibbonTryForFree: Try for free

MoreInfoHead: More information
MoreInfoFormName: Your Name
MoreInfoFormNamePlaceHolder: Your Name
MoreInfoFormEmail: Your Email
MoreInfoFormEmailPlaceHolder: Your Email
MoreInfoFormMessage: Your message
MoreInfoFormMessagePlaceHolder: Write your message
MoreInfoFormSend: Send message

MoreInfoContributionHead: Contributions Policy
MoreInfoContributionContent: The project is hosted on github and everyone are welcome to open pull requests for bug fixing or for implementation of new features.

MoreInfoDonationsHead: Donations
MoreInfoDonationsContent: You can also donate to support the project and contribute with.
MoreInfoDonationsButton20: Donate 20.00
MoreInfoDonationsButton30: Donate 30.00
MoreInfoDonationsButton40: Donate 40.00
MoreInfoDonationsButton50: Donate 50.00
@@ -1 +1,42 @@
Title: Flora Rastreador de Tempo
NavigationHome: Início
NavigationTryFree: Teste de graça
NavigationSignUp: Assine
NavigationSignIn: Acesse

SplashHead: Um simples rastreador de tempo
SplashSubHead: Rastreia de maneira fácil o tempo que você gasta em tarefas.
SplashButton: Use agora

FeaturesHead: Funcionalidades
FeaturesTimeTrackingHead: Rastreador de Tempo
FeaturesTimeTrackingContent: Rastreia de maneira fácil o tempo gasto em tarefas de diferentes projetos.
FeaturesReportingHead: Relatórios
FeaturesReportingContent: Gere relatórios em HTML ou CSV para enviar para gerentes e clientes.
FeaturesDashboardHead: Painel de Gráficos
FeaturesDashboardContent: Diferentes tipos de gráficos fornecem uma imagem do tempo rastreado e do dinheiro recebido.
FeaturesOpenSourcedHead: Código Aberto
FeaturesOpenSourcedContent: Contribua com o projeto ou customize para as suas necessidades.

RibbonHead: Não é necessário ter conta
RibbonContent: Ao usar uma URL única, você pode acessar a sua área de trabalho e começar a rastrear o tempo gasto em suas tarefas sem a necessidade de criar uma conta.
RibbonTryForFree: Teste de graça

MoreInfoHead: Mais informações
MoreInfoFormName: Nome
MoreInfoFormNamePlaceHolder: Digite seu nome.
MoreInfoFormEmail: Email
MoreInfoFormEmailPlaceHolder: Digite seu email
MoreInfoFormMessage: Mensagem
MoreInfoFormMessagePlaceHolder: Escreva sua mensagem
MoreInfoFormSend: Enviar mensagem

MoreInfoContributionHead: Política de Contribuição
MoreInfoContributionContent: O projeto está hospedado no github e qualquer um é bem-vindo à abrir pull requests para a correção de bugs ou implementação de novas funcionalidades.

MoreInfoDonationsHead: Doações
MoreInfoDonationsContent: Você também pode contribuir doando valores para ajudar a manter o projeto.
MoreInfoDonationsButton20: Doe 20.00
MoreInfoDonationsButton30: Doe 30.00
MoreInfoDonationsButton40: Doe 40.00
MoreInfoDonationsButton50: Doe 50.00
@@ -0,0 +1,42 @@
"name": "flora",
"version": "1.0.0",
"description": "Time tracker built with Haskell",
"main": "index.js",
"license": "MIT",
"repository": {
"type": "git",
"url": ""
"dependencies": {
"purecss-sass": "0.6.0+1",
"react": "0.14.6",
"react-dom": "0.14.6"
"devDependencies": {
"babel-core": "6.4.0",
"babel-loader": "6.2.1",
"babel-preset-es2015": "6.3.13",
"babel-preset-react": "6.3.13",
"css-loader": "0.23.1",
"expect": "1.13.4",
"extract-text-webpack-plugin": "1.0.0",
"karma": "^0.13.19",
"karma-cli": "^0.1.2",
"karma-mocha": "0.2.1",
"karma-webpack": "1.7.0",
"karma-chrome-launcher": "0.2.2",
"karma-sourcemap-loader": "0.3.7",
"karma-mocha-reporter": "1.1.5",
"mocha": "2.3.4",
"node-sass": "3.4.2",
"sass-loader": "3.1.2",
"style-loader": "0.13.0",
"webpack": "1.12.9",
"webpack-sources": "0.1.0",
"react-addons-test-utils": "0.14.6"
"scripts": {
"test": "karma start"
@@ -0,0 +1,24 @@
* Most of these are inherited from Base, but I want to change a few.
body {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
line-height: 1.7em;
color: #7f8c8d;
font-size: 16px;
label {
color: #34495e;
@@ -0,0 +1,16 @@
* I want my pure-button elements to look a little different
.pure-button {
background-color: #1f8dd6;
color: white;
padding: 0.5em 2em;
border-radius: 5px;
&.primary {
background: white;
color: #1f8dd6;
border-radius: 5px;
font-size: 120%;
Oops, something went wrong.

0 comments on commit 4cbdc19

Please sign in to comment.
You can’t perform that action at this time.