Maquette de la nouvelle navigation par défilement

pull/138/head
mama 2017-12-05 12:58:24 +01:00
parent fc752be767
commit 1de78d28e8
10 changed files with 243 additions and 219 deletions

View File

@ -0,0 +1,12 @@
#sim .tip {
font-style: italic;
margin-bottom: .6em;
text-align: center;
}
#sim .tip p {
margin: 0;
}
#sim .tip progress {
margin-left: 1em;
}

View File

@ -0,0 +1,46 @@
import React, { Component } from 'react'
import { connect } from "react-redux"
import { withRouter } from "react-router"
import './ProgressTip.css'
@withRouter
@connect(state => ({
done: state.done,
foldedSteps: state.foldedSteps,
nextSteps: state.nextSteps,
}))
export default class ProgressTip extends Component {
state = {
nbFoldedStepsForFirstEstimation: null
}
componentWillReceiveProps(newProps) {
if (newProps.done && this.state.nbFoldedStepsForFirstEstimation == null)
this.setState({
nbFoldedStepsForFirstEstimation: newProps.foldedSteps.length
})
}
render() {
let {done, nextSteps, foldedSteps} = this.props
if (!done) return null
return (
<div className="tip">
{nextSteps.length != 0 &&
this.state.nbFoldedStepsForFirstEstimation ===
foldedSteps.length && (
<p>Votre première estimation est disponible !</p>
)}
{nextSteps.length != 0 && (
<p>
Il vous reste environ {nextSteps.length}{' '}
{nextSteps.length === 1 ? 'questions' : 'question'} pour
affiner le calcul
<progress
value={foldedSteps.length}
max={foldedSteps.length + nextSteps.length}
/>
</p>
)}
</div>
)
}
}

View File

@ -1,20 +1,28 @@
#resultsWrapper {
height: 40%;
#resultsZone {
height: 49%;
display: flex;
align-items: flex-end;
}
#results {
width: 100%;
}
#resultsContent {
position: relative;
margin: 0 auto;
padding: .1em .3em;
width: 95%;
padding: .6em 0;
width: 100%;
max-width: 45em;
background: #2975D1;
color: white;
box-shadow: 0px 0px 20px 2px rgba(0, 0, 0, 0.25);
}
#results button {
display: block;
margin: 1em auto;
}
#results-actions {
background: #333350;
}

View File

@ -1,68 +1,71 @@
import R from 'ramda'
import React, { Component } from 'react'
import classNames from 'classnames'
import {Link} from 'react-router-dom'
import {connect} from 'react-redux'
import { withRouter } from 'react-router'
import R from "ramda"
import React, { Component } from "react"
import classNames from "classnames"
import { Link } from "react-router-dom"
import { connect } from "react-redux"
import { withRouter } from "react-router"
import './Results.css'
import {clearDict} from 'Engine/traverse'
import {encodeRuleName} from 'Engine/rules'
import RuleValueVignette from './rule/RuleValueVignette'
import "./Results.css"
import { clearDict } from "Engine/traverse"
import { encodeRuleName } from "Engine/rules"
import RuleValueVignette from "./rule/RuleValueVignette"
import ProgressTip from "Components/ProgressTip"
@withRouter
@connect(
state => ({
analysis: state.analysis,
targetName: state.targetName,
conversationStarted: !R.isEmpty(state.form),
conversationFirstAnswer: R.path(['form', 'conversation', 'values'])(state),
situationGate: state.situationGate
})
)
@connect(state => ({
analysis: state.analysis,
targetName: state.targetName,
conversationStarted: !R.isEmpty(state.form),
conversationFirstAnswer: R.path(["form", "conversation", "values"])(state),
situationGate: state.situationGate,
done: state.done,
}))
export default class Results extends Component {
render() {
let {
analysis,
targetName,
conversationStarted,
conversationFirstAnswer,
location
} = this.props
render() {
let {
analysis,
targetName,
conversationStarted,
conversationFirstAnswer,
location,
done
} = this.props
if (!analysis) return null
if (!analysis) return null
let {targets} = analysis
let { targets } = analysis
let onRulePage = R.contains('/regle/')(location.pathname)
return (
<div id="resultsWrapper">
<section ref={el => this.el = el} id="results">
{onRulePage && conversationStarted ?
<div id ="results-actions">
<Link id="toSimulation" to={'/simu/' + encodeRuleName(targetName)}>
<i className="fa fa-arrow-circle-left" aria-hidden="true"></i>Reprendre la simulation
</Link>
</div>
: <div id="results-titles">
<h2><i className="fa fa-calculator" aria-hidden="true"></i>{targets.length == 1 ? 'Votre objectif' : 'Vos objectifs'}</h2>
</div>
}
<Link
className="edit"
to="/"
>
<i className="fa fa-pencil-square-o" aria-hidden="true" />
{' '}
<span>Modifier</span>
</Link>
<ul>
{targets.map( rule => <li key={rule.nom}>
<RuleValueVignette {...rule} conversationStarted={conversationStarted} />
</li>)}
</ul>
</section>
</div>
)
}
let onRulePage = R.contains("/regle/")(location.pathname)
return (
<div id="resultsZone">
<section id="results">
<ProgressTip />
<div id="resultsContent">
<div id="results-titles">
<h2>
<i className="fa fa-calculator" aria-hidden="true" />
{targets.length == 1 ? "Votre objectif" : "Vos objectifs"}
</h2>
</div>
<Link className="edit" to="/">
<i className="fa fa-pencil-square-o" aria-hidden="true" />
{" "}
<span>Modifier</span>
</Link>
<ul>
{targets.map(rule => (
<li key={rule.nom}>
<RuleValueVignette
{...rule}
conversationStarted={conversationStarted}
/>
</li>
))}
</ul>
</div>
{done && <button>Comprendre mes résultats</button>}
</section>
</div>
)
}
}

View File

@ -0,0 +1,3 @@
.resultsGrid {
margin-top: 6em;
}

View File

@ -9,7 +9,7 @@ import { humanFigure } from './rule/RuleValueVignette'
import { capitalise0 } from '../utils'
import { nameLeaf } from 'Engine/rules'
import './ResultsGrid.css'
// Filtered variables and rules can't be filtered in a uniform way, for now
let paidBy = R.pathEq(['explanation', 'cotisation', 'dû par'])

View File

@ -1,10 +1,9 @@
#sim {
margin: 3% auto;
margin: 0 auto;
color: #333350;
transition: background-color .5s;
height: 100%;
width: 90%;
max-width: 45em;
font-size: 130%;
@ -75,17 +74,3 @@
box-shadow: none;
opacity: 1;
}
#sim .tip {
font-style: italic;
margin-bottom: 2em;
}
#sim .tip p {
margin: 0;
}
#sim .tip progress {
margin-left: 1em;
}

View File

@ -1,87 +1,64 @@
import React, { Component } from 'react'
import R from 'ramda'
import Aide from '../Aide'
import Satisfaction from '../Satisfaction'
import { reduxForm } from 'redux-form'
import { scroller, Element } from 'react-scroll'
import React, { Component } from "react"
import R from "ramda"
import Aide from "../Aide"
import Satisfaction from "../Satisfaction"
import { reduxForm } from "redux-form"
import { scroller, Element } from "react-scroll"
@reduxForm({
form: 'conversation',
destroyOnUnmount: false
form: "conversation",
destroyOnUnmount: false
})
export default class Conversation extends Component {
state = {
nbFoldedStepsForFirstEstimation: null
}
componentWillReceiveProps(newProps) {
if (newProps.done && this.state.nbFoldedStepsForFirstEstimation == null)
this.setState({
nbFoldedStepsForFirstEstimation: newProps.foldedSteps.length
})
}
render() {
let {
foldedSteps,
currentQuestion,
reinitalise,
textColourOnWhite,
done,
nextSteps
} = this.props
componentWillReceiveProps(nextProps) {
if (nextProps.foldedSteps.length == this.props.foldedSteps.length)
return null
// scroller.scrollTo('myScrollToElement', {
// duration: 200,
// delay: 100,
// smooth: true
// })
console.log('will scroll')
setTimeout(
() =>
scroller.scrollTo("myScrollToElement", {
duration: 200,
delay: 0,
smooth: true
}),
1
)
}
render() {
let {
foldedSteps,
currentQuestion,
reinitalise,
textColourOnWhite,
done,
nextSteps
} = this.props
return (
<>
{!R.isEmpty(foldedSteps) && (
<div id="foldedSteps">
<div className="header">
<h2>
<i className="fa fa-mouse-pointer" aria-hidden="true" />Vos
réponses
</h2>
<button
onClick={reinitalise}
style={{ color: textColourOnWhite }}
>
<i className="fa fa-trash" aria-hidden="true" />
Tout effacer
</button>
</div>
{foldedSteps}
</div>
)}
<Element name="myScrollToElement" id="myScrollToElement">
{done && (
<div className="tip">
{nextSteps.length != 0 &&
this.state.nbFoldedStepsForFirstEstimation ===
foldedSteps.length && (
<p>Votre première estimation est disponible !</p>
)}
{nextSteps.length != 0 && (
<p>
Il vous reste environ {nextSteps.length}{' '}
{nextSteps.length === 1 ? 'questions' : 'question'} pour
affiner le calcul
<progress
value={foldedSteps.length}
max={foldedSteps.length + nextSteps.length}
/>
</p>
)}
</div>
)}
<div id="currentQuestion">
{currentQuestion || <Satisfaction simu={this.props.simu} />}
</div>
</Element>
<Aide />
</>
)
}
return (
<>
{!R.isEmpty(foldedSteps) && (
<div id="foldedSteps">
<div className="header">
<button
onClick={reinitalise}
style={{ color: textColourOnWhite }}
>
<i className="fa fa-trash" aria-hidden="true" />
Tout effacer
</button>
</div>
{foldedSteps}
</div>
)}
<Element name="myScrollToElement" id="myScrollToElement">
{foldedSteps.length != 0 && <button> Modifier mes réponses</button>}
<div id="currentQuestion">
{currentQuestion || <Satisfaction simu={this.props.simu} />}
</div>
</Element>
<Aide />
</>
)
}
}

View File

@ -4,14 +4,26 @@
height: 55%;
}
#myScrollToElement button {
display: block;
margin: 1em auto;
}
#myScrollToElement, #foldedSteps {
padding: 1em 1em;
}
#foldedSteps {
margin: 3em .3em;
margin-bottom: 6em;
}
#foldedSteps .header button {
font-size: 80%;
color: #2975D1;
border: none;
display: block;
margin: 0 auto;
}
#foldedSteps .header button i {
margin-right: .3em;

View File

@ -1,67 +1,45 @@
import React, { Component } from 'react'
import './Layout.css'
import './reset.css'
import './ribbon.css'
import React, { Component } from "react"
import "./Layout.css"
import "./reset.css"
import "./ribbon.css"
import { Link, Route, Router, Switch, Redirect } from 'react-router-dom'
import { Link, Route, Router, Switch, Redirect } from "react-router-dom"
import Home from 'Components/Home'
import Rule from 'Components/rule/Rule'
import Route404 from 'Components/Route404'
import Contact from 'Components/Contact'
import Simulateur from 'Components/Simulateur'
import RulesList from 'Components/RulesList'
import Home from "Components/Home"
import Rule from "Components/rule/Rule"
import Route404 from "Components/Route404"
import Contact from "Components/Contact"
import Simulateur from "Components/Simulateur"
import RulesList from "Components/RulesList"
import ReactPiwik from 'Components/Tracker'
import createHistory from 'history/createBrowserHistory'
import ReactPiwik from "Components/Tracker"
import createHistory from "history/createBrowserHistory"
const piwik = new ReactPiwik({
url: 'stats.data.gouv.fr',
siteId: 39,
trackErrors: true
url: "stats.data.gouv.fr",
siteId: 39,
trackErrors: true
})
export default class Layout extends Component {
history = createHistory()
render() {
let displayWarning = ['/simu/', '/regle/', '/regles'].find(
t => window.location.href.toString().indexOf(t) > -1
)
history = createHistory()
render() {
// track the initial pageview
ReactPiwik.push(["trackPageView"])
// track the initial pageview
ReactPiwik.push(['trackPageView'])
return (
<Router history={piwik.connectToHistory(this.history)}>
<>
<div id="header">
{displayWarning && (
<span id="ribbon">
<Link to="/contact">
<em>version beta</em>{' '}
<i className="fa fa-flask" aria-hidden="true" />
</Link>
</span>
)}
{
// this.props.location.pathname != '/' &&
// <Link to="/">
// <img id="site-logo" src={require('../images/logo.png')} />
// </Link>
}
</div>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/contact" component={Contact} />
<Route path="/regle/:name" component={Rule} />
<Route path="/regles" component={RulesList} />
<Route path="/simu/:targets" component={Simulateur} />
<Redirect from="/simu/" to="/" />
<Redirect from="/simu/:name/intro" to="/simu/:name" />
<Route component={Route404} />
</Switch>
</>
</Router>
)
}
return (
<Router history={piwik.connectToHistory(this.history)}>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/contact" component={Contact} />
<Route path="/regle/:name" component={Rule} />
<Route path="/regles" component={RulesList} />
<Route path="/simu/:targets" component={Simulateur} />
<Redirect from="/simu/" to="/" />
<Redirect from="/simu/:name/intro" to="/simu/:name" />
<Route component={Route404} />
</Switch>
</Router>
)
}
}