Skip to content

Commit

Permalink
Issue mozilla#1307: Quick reorg into presentational components and st…
Browse files Browse the repository at this point in the history
…ate-reactive containers
  • Loading branch information
lmorchard committed Sep 6, 2016
1 parent b053050 commit 9eb0dde
Show file tree
Hide file tree
Showing 24 changed files with 314 additions and 225 deletions.
45 changes: 45 additions & 0 deletions frontend/src/app-new/components/DiscussDialog.js
@@ -0,0 +1,45 @@
import React from 'react';

export default class DiscussDialog extends React.Component {
render() {
return (
<div className="modal-container">
<div id="discuss-modal" className="modal feedback-modal modal-bounce-in">
<header>
<h3 className="title" data-l10n-id="discussNotifyTitle">Just one second...</h3>
</header>
<form>

<div className="modal-content modal-form">
<div data-l10n-id="discussNotifyMessageAccountless" className="centered">
<p>In the spirit of experimentation, we are using an external forum service. You will need to create an account if you wish to participate on the forums.</p>
<p>If you don't feel like creating another account, you can
always leave feedback through Test Pilot.
<br />
(We really do read this stuff)
</p>
</div>
</div>
<div className="modal-actions">
<button onClick={e => this.submit(e)} data-hook="submit-feedback" data-l10n-id="discussNotifySubmitButton" className="submit button large default">Take me to the forum</button>
<a onClick={e => this.cancel(e)} data-l10n-id="discussNotifyCancelButton" className="cancel modal-escape" href="">Cancel</a>
</div>
</form>
</div>
</div>
);
}

submit(e) {
e.preventDefault();
// HACK: this should really open a new tab!
window.location = this.props.href;
this.props.onDismiss();
}

cancel(e) {
e.preventDefault();
this.props.onDismiss();
}

}
@@ -1,14 +1,9 @@
import React from 'react';
import { connect } from 'react-redux';

import Header from '../components/Header';
import Footer from '../components/Footer';

export default connect(
state => state
)((props) => <ErrorPage {...props} />);

class ErrorPage extends React.Component {
export default class ErrorPage extends React.Component {
render() {
return (
<div className="full-page-wrapper space-between">
Expand Down
@@ -1,5 +1,4 @@
import React from 'react';
import { connect } from 'react-redux';

import classnames from 'classnames';

Expand All @@ -15,20 +14,9 @@ import ExperimentDisableDialog from '../components/ExperimentDisableDialog';
import ExperimentTourDialog from '../components/ExperimentTourDialog';
import MainInstallButton from '../components/MainInstallButton';

import { getExperiments } from '../reducers/experiments';

const CHANGE_HEADER_ON = 105;

export default connect(
state => ({
experiments: getExperiments(state.experiments),
isFirefox: state.browser.isFirefox,
hasAddon: state.addon.hasAddon,
installed: state.addon.installed
})
)((props) => <ExperimentPage {...props} />);

class ExperimentPage extends React.Component {
export default class ExperimentPage extends React.Component {

constructor(props) {
super(props);
Expand All @@ -45,7 +33,7 @@ class ExperimentPage extends React.Component {
}

render() {
const { params, dispatch, experiments, installed, hasAddon, isFirefox } = this.props;
const { params, navigateTo, experiments, installed, hasAddon, isFirefox } = this.props;

// Show the loading animation if experiments haven't been loaded yet.
if (experiments.length === 0) { return <LoadingPage />; }
Expand Down Expand Up @@ -99,7 +87,7 @@ class ExperimentPage extends React.Component {
<span data-l10n-id="experimentPromoHeader" className="block">Ready for Takeoff?</span>
</h2>
<p data-l10n-id="experimentPromoSubheader">We're building next-generation features for Firefox. Install Test Pilot to try them!</p>
<MainInstallButton dispatch={dispatch} hasAddon={hasAddon} isFirefox={isFirefox}
<MainInstallButton hasAddon={hasAddon} isFirefox={isFirefox}
eventCategory="HomePage Interactions" />
</div>
</div>
Expand Down Expand Up @@ -245,7 +233,7 @@ class ExperimentPage extends React.Component {
<div className="card-list experiments">
{ experiments.map((listExperiment, key) =>
(listExperiment.slug !== experiment.slug) &&
<ExperimentRowCard key={key} dispatch={dispatch}
<ExperimentRowCard key={key} navigateTo={navigateTo}
experiment={listExperiment} hasAddon={hasAddon}
eventCategory="ExperimentsDetailPage Interactions" />) }
</div>
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/app-new/components/ExperimentRowCard.js
@@ -1,5 +1,4 @@
import React from 'react';
import { push as routerPush } from 'react-router-redux';

import classnames from 'classnames';

Expand Down Expand Up @@ -113,7 +112,7 @@ export default class ExperimentRowCard extends React.Component {
}

openDetailPage(evt) {
const { dispatch, eventCategory, experiment } = this.props;
const { navigateTo, eventCategory, experiment } = this.props;
const { title } = experiment;

evt.preventDefault();
Expand All @@ -122,7 +121,7 @@ export default class ExperimentRowCard extends React.Component {
eventAction: 'Open detail page',
eventLabel: title
});
dispatch(routerPush(`/experiments/${experiment.slug}`));
navigateTo(`/experiments/${experiment.slug}`);
}

}
Expand Down
@@ -1,24 +1,12 @@
import React from 'react';
import { connect } from 'react-redux';
import cookies from 'js-cookie';

import Header from '../components/Header';
import Footer from '../components/Footer';
import ExperimentRowCard from '../components/ExperimentRowCard';
import EmailDialog from '../components/EmailDialog';

import { getExperiments } from '../reducers/experiments';

export default connect(
state => ({
experiments: getExperiments(state.experiments),
isFirefox: state.browser.isFirefox,
hasAddon: state.addon.hasAddon,
installed: state.addon.installed
})
)((props) => <ExperimentsListPage {...props} />);

class ExperimentsListPage extends React.Component {
export default class ExperimentsListPage extends React.Component {

constructor(props) {
super(props);
Expand All @@ -35,7 +23,7 @@ class ExperimentsListPage extends React.Component {
}

render() {
const { dispatch, experiments, hasAddon } = this.props;
const { navigateTo, experiments, hasAddon } = this.props;
const { showEmailDialog } = this.state;

return (
Expand All @@ -60,7 +48,7 @@ class ExperimentsListPage extends React.Component {
<div data-hook="experiment-list">
<div className="card-list experiments">
{ experiments.map((experiment, key) =>
<ExperimentRowCard key={key} dispatch={dispatch}
<ExperimentRowCard key={key} navigateTo={navigateTo}
experiment={experiment} hasAddon={hasAddon}
eventCategory="HomePage Interactions" />) }
</div>
Expand Down
42 changes: 23 additions & 19 deletions frontend/src/app-new/components/Header.js
Expand Up @@ -3,20 +3,37 @@ import { Link } from 'react-router';

import classnames from 'classnames';

// import { sendMessage } from '../lib/addon';
import { sendToGA } from '../lib/utils';

import RetireConfirmationDialog from './RetireConfirmationDialog';
import DiscussDialog from './DiscussDialog';

export default class Header extends React.Component {

constructor() {
super();
this.state = { showSettings: false };
this.state = {
showSettings: false,
showDiscussDialog: false,
showRetireDialog: false
};
}

render() {
const { showSettings } = this.state;
const { showSettings, showRetireDialog, showDiscussDialog } = this.state;

return (
<header id="main-header" className="responsive-content-wrapper">

{showRetireDialog &&
<RetireConfirmationDialog onDismiss={() => this.setState({ showRetireDialog: false })} />}

{showDiscussDialog &&
<DiscussDialog
href="https://discourse.mozilla-community.org/c/test-pilot"
onDismiss={() => this.setState({ showDiscussDialog: false })} />}

<h1>
<Link to="/" className="wordmark" data-l10n-id="siteName">Firefox Test Pilot</Link>
</h1>
Expand All @@ -27,7 +44,7 @@ export default class Header extends React.Component {
data-hook="settings-button" data-l10n-id="menuTitle">Settings</div>
{showSettings && <div className="settings-menu">
<ul>
<li><a onClick={e => this.wiki(e)}data-l10n-id="menuWiki" data-hook="wiki"
<li><a onClick={e => this.wiki(e)} data-l10n-id="menuWiki" data-hook="wiki"
href="https://wiki.mozilla.org/Test_Pilot" target="_blank">Test Pilot Wiki</a></li>
<li><a onClick={e => this.discuss(e)} data-l10n-id="menuDiscuss" data-hook="discuss"
href="https://discourse.mozilla-community.org/c/test-pilot" target="_blank">Discuss Test Pilot</a></li>
Expand Down Expand Up @@ -71,20 +88,14 @@ export default class Header extends React.Component {
}

retire(evt) {
console.log('RETIRE LINK');
evt.preventDefault();
sendToGA('event', {
eventCategory: 'Menu Interactions',
eventAction: 'drop-down menu',
eventLabel: 'Retire'
});
/* TODO
this.renderSubview(new RetireDialogView({
id: 'retire-dialog',
onSubmit: () => {
app.trigger('router:new-page', {page: 'retire'});
}
}), 'body');
*/
this.setState({ showRetireDialog: true });
}

discuss(evt) {
Expand All @@ -94,14 +105,7 @@ export default class Header extends React.Component {
eventAction: 'drop-down menu',
eventLabel: 'Discuss'
});
/* TODO
this.renderSubview(new DiscussNotifyView({
id: 'discuss-dialog',
onSubmit: () => {
window.location = evt.target.getAttribute('href');
}
}), 'body');
*/
this.setState({ showDiscussDialog: true });
}

wiki() {
Expand Down
@@ -1,25 +1,13 @@
import React from 'react';
import { connect } from 'react-redux';

import Footer from '../components/Footer';
import ExperimentRowCard from '../components/ExperimentRowCard';
import MainInstallButton from '../components/MainInstallButton';

import { getExperiments } from '../reducers/experiments';

export default connect(
state => ({
experiments: getExperiments(state.experiments),
isFirefox: state.browser.isFirefox,
hasAddon: state.addon.hasAddon,
installed: state.addon.installed
})
)((props) => <LandingPage {...props} />);

class LandingPage extends React.Component {
export default class LandingPage extends React.Component {

render() {
const { dispatch, experiments, hasAddon, isFirefox } = this.props;
const { navigateTo, experiments, hasAddon, isFirefox } = this.props;

return (
<section data-hook="landing-page">
Expand All @@ -43,7 +31,7 @@ class LandingPage extends React.Component {
</div>

<div className="centered-banner responsive-content-wrapper">
<MainInstallButton dispatch={dispatch} hasAddon={hasAddon} isFirefox={isFirefox}
<MainInstallButton hasAddon={hasAddon} isFirefox={isFirefox}
eventCategory="HomePage Interactions" />
</div>

Expand All @@ -53,7 +41,7 @@ class LandingPage extends React.Component {
<div data-hook="experiment-list">
<div className="card-list experiments">
{ experiments.map((experiment, key) =>
<ExperimentRowCard key={key} dispatch={dispatch}
<ExperimentRowCard key={key} navigateTo={navigateTo}
experiment={experiment} hasAddon={hasAddon}
eventCategory="HomePage Interactions" />) }
</div>
Expand All @@ -78,7 +66,7 @@ class LandingPage extends React.Component {
</div>

<div className="centered-banner responsive-content-wrapper">
<MainInstallButton dispatch={dispatch} hasAddon={hasAddon} isFirefox={isFirefox}
<MainInstallButton hasAddon={hasAddon} isFirefox={isFirefox}
eventCategory="HomePage Interactions" />
</div>

Expand Down
@@ -1,13 +1,8 @@
import React from 'react';
import { connect } from 'react-redux';

import Footer from '../components/Footer';

export default connect(
state => state
)((props) => <LegacyPage {...props} />);

class LegacyPage extends React.Component {
export default class LegacyPage extends React.Component {
render() {
return (
<div className="full-page-wrapper space-between">
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions frontend/src/app-new/components/NotFoundPage.js
@@ -0,0 +1,20 @@
import React from 'react';

export default function NotFoundPage() {
return (
<div className="full-page-wrapper centered" data-hook="no-found-page">
<div className="centered-banner">
<div id="four-oh-four" className="modal delayed-fade-in">
<h1 data-l10n-id="notFoundHeader" className="title">Four Oh Four!</h1>
<br/>
<div className="modal-actions">
<a data-l10n-id="home" className="button default large" href="/">Home</a>
</div>
</div>
<div className="copter-wrapper">
<div className="copter fade-in-fly-up"></div>
</div>
</div>
</div>
);
}
26 changes: 26 additions & 0 deletions frontend/src/app-new/components/OnboardingPage.js
@@ -0,0 +1,26 @@
import React from 'react';

import Header from './Header';
import Footer from './Footer';

export default function OnboardingPage() {
return (
<div className="full-page-wrapper space-between">
<Header />
<div className="centered-banner">
<div id="onboarding" className="modal">
<div className="modal-content centered">
<div className="toolbar-button-onboarding"></div>
<p data-l10n-id="onboardingMessage">We put an icon in your toolbar so you can always find Test Pilot.</p>
</div>
</div>
<div className="copter-wrapper">
<div className="copter fade-in-fly-up"></div>
</div>
</div>
<footer id="main-footer" className="content-wrapper">
<Footer />
</footer>
</div>
);
}

0 comments on commit 9eb0dde

Please sign in to comment.