Add initial management page (fixes #171)

This commit is contained in:
Stuart Colville 2015-07-09 11:49:49 +01:00
Родитель afc4f96222
Коммит dd5cfdace2
19 изменённых файлов: 264 добавлений и 40 удалений

Двоичные данные
public/img/firefox.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.1 KiB

5
public/img/profile.svg Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<path fill="#C3CFD8" d="M500-0.3c276.1 0 500 223.9 500 500s-223.9 500-500 500S0 775.8 0 499.7C0 223.5 223.9-0.3 500-0.3z"/>
<circle fill="#FFFFFF" cx="500" cy="317" r="139.1"/>
<path fill="#FFFFFF" d="M751.8 643.6L751.8 643.6c0.1-2.3 0.2-4.6 0.2-6.9c0-68-55.3-127-136.2-156.3L505.9 590.4h0 c-0.4 29.8-1.4 58.8-2.8 86.6c-1 0.1-2 0.3-3.1 0.3s-2-0.2-3.1-0.3c-1.4-27.9-2.4-56.9-2.8-86.7h0L384.3 480.4 C303.3 509.7 248 568.7 248 636.7c0 2.3 0.1 4.6 0.2 6.9l7.4 49.7c57.1 72 145.4 118.2 244.4 118.2c99 0 187.3-46.2 244.4-118.2 L751.8 643.6z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 755 B

Просмотреть файл

@ -15,6 +15,7 @@
</div>
</div>
</main>
<script src="/dist/bundle.js"></script>
<script src="/dist/commons.js"></script>
<script src="/dist/payment.bundle.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,86 @@
'use strict';
var React = require('react');
var {
Accordion,
AccordionContent,
AccordionSection} = require('components/accordion');
var gettext = require('utils').gettext;
var Management = React.createClass({
displayName: 'ManagementApp',
render: function() {
return (
<div>
<header className="top-nav">
<h1 className="logo">Firefox Payments</h1>
<button>{gettext('Sign Out')}</button>
</header>
<div className="content">
<div className="user">
<p>Hello, placeholder@placeholder.com</p>
</div>
<Accordion>
<AccordionSection>
<header>
<h2>{gettext('Payment Accounts')}</h2>
<button data-activate>{gettext('Change')}</button>
</header>
<AccordionContent>
<p>Payment list will go here</p>
<ul>
<li>4111 1111 1111 1111</li>
<li>4222 2222 2222 2222</li>
</ul>
</AccordionContent>
</AccordionSection>
<AccordionSection>
<header>
<h2>{gettext('Receipts and Subscriptions')}</h2>
<button data-activate>{gettext('View/Change')}</button>
</header>
<AccordionContent>
<p>Placeholder</p>
</AccordionContent>
</AccordionSection>
<AccordionSection>
<header>
<h2>{gettext('Email Address and Password')}</h2>
<a className="button"
href="https://mozilla.org/"
target="_blank">{gettext('Change')}</a>
<p>placeholder@placeholder.com</p>
</header>
</AccordionSection>
<AccordionSection>
<header>
<h2>{gettext('Delete Account')}</h2>
<button data-activate>{gettext('Delete')}</button>
</header>
<AccordionContent>
<p>Placeholder content</p>
</AccordionContent>
</AccordionSection>
</Accordion>
</div>
</div>
);
},
});
module.exports = {
component: Management,
init: function() {
React.render(<Management />, document.getElementById('view'));
},
};

Просмотреть файл

@ -0,0 +1,11 @@
'use strict';
var $ = require('jquery');
var App = require('./app');
// Common ajax settings.
$.ajaxSetup({
dataType: 'json',
});
App.init();

Просмотреть файл

@ -15,7 +15,7 @@ var utils = require('utils');
var App = React.createClass({
displayName: 'App',
displayName: 'PaymentApp',
getInitialState: function() {
var qs = utils.parseQuery(window.location.href);

Просмотреть файл

@ -1,8 +1,8 @@
'use strict';
var $ = require('jquery');
var App = require('app');
var tracking = require('tracking');
var App = require('./app');
// Common ajax settings.
$.ajaxSetup({

Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
var classNames = require('classnames');
var cx = require('classnames');
var React = require('react');
@ -31,7 +31,7 @@ module.exports = React.createClass({
render: function() {
// This is only displayed if a cardType is passed-in.
var cardType = this.props.cardType;
var cardClassName = classNames([
var cardClassName = cx([
'card-icon',
'cctype-' + (this.cardTypeMap[cardType] || cardType),
]);

Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
var classNames = require('classnames');
var cx = require('classnames');
var React = require('react');
@ -14,7 +14,7 @@ module.exports = React.createClass({
render: function() {
var { errorMessage, ...toolTipAttrs } = this.props;
var errorClass = classNames([
var errorClass = cx([
'tooltip',
this.props.errorModifier || 'left',
]);

Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
var classNames = require('classnames');
var cx = require('classnames');
var React = require('react');
@ -17,7 +17,7 @@ module.exports = React.createClass({
var { isDisabled, text, showSpinner, ...buttonAttrs } = this.props;
var buttonClassNames = classNames({
var buttonClassNames = cx({
'spinner': showSpinner,
});

21
public/management.html Normal file
Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="/dist/main.css">
<title>Management</title>
</head>
<body class="management">
<main>
<div id="view">
<div class="spinner-cont">
<div class="spinner"/>
</div>
</div>
</main>
<script src="/dist/commons.js"></script>
<script src="/dist/management.bundle.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,46 @@
.accordion {
padding: 0 20px;
background: #fff;
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
header {
h2 {
font-size: $large-font;
font-weight: 400;
float: left;
}
button,
.button,
a.button {
width: auto;
float: right;
}
p {
clear: both;
}
}
}
.ac-section:first-child {
border-top: none;
}
.ac-section {
border-top: 1px solid #ccc;
padding: 20px 0;
overflow: auto;
background: #fff;
}
.ac-content {
clear: both;
display: none;
}
.accordion .active .ac-content {
display: block;
}

Просмотреть файл

@ -3,32 +3,24 @@
text-decoration: none;
}
.button,
a.button,
button {
@include font();
background: $button-background-color;
border: 0;
border-radius: $small-border-radius;
color: $message-text-color;
cursor: pointer;
font-size: $medium-font;
margin: 10px 0;
padding: 0.5em 1em;
transition-duration: $short-transition;
transition-property: background-color;
text-align: center;
width: 100%;
line-height: 1.5em;
@include respond-to('big') {
border-radius: $big-border-radius;
font-size: $large-font;
padding: 15px 0;
}
@include respond-to('small') {
border-radius: $small-border-radius;
font-size: $medium-font;
padding: 8px 0;
}
&:active,
&:hover,
&:focus {

Просмотреть файл

@ -0,0 +1,54 @@
@import '_settings';
.management {
background: $management-grey;
margin: 0;
padding: 0;
main {
margin: 0;
padding: 0;
}
.content {
margin: 0 auto;
max-width: 700px;
padding: 20px;
width: 100%;
}
.top-nav {
background: #fff;
border-bottom: 1px solid $stormy-grey;
overflow: hidden;
padding: 10px 20px;
width: 100%;
h1 {
background: url('#{$image-path}firefox.png') no-repeat 0 50%;
background-size: 40px;
float: left;
font-size: $extra-large-font;
font-weight: 400;
margin: 10px 0 0;
padding: 0 0 0 50px;
}
button {
float: right;
width: auto;
}
}
.user {
background: url('#{$image-path}profile.svg') no-repeat 0 50%;
background-size: 60px;
margin-top: 70px;
padding: 5px 0 5px 80px;
p {
font-size: $large-font;
}
}
}

Просмотреть файл

@ -11,8 +11,10 @@ $header-font: "Fira Sans", Helvetica, Arial, sans-serif;
$baby-blue: #E0F1FA;
$light-blue: #0096dc;
$uniform-blue: #0080D8;
// Not sure what those other blues are, this is the one that counts.
$the-real-blue: #0095dd;
$management-grey: #F2F2F2;
$stormy-grey: #BDBFBD;
$button-background-color: $the-real-blue;
$button-background-disabled-color: #8a9ba8;
@ -41,6 +43,7 @@ $text-color: #424f59;
// Font-Size Variables
$very-large-font: 42px;
$extra-large-font: 36px;
$large-font: 24px;
$medium-font: 18px;
$base-font: 14px;

Просмотреть файл

@ -4,6 +4,7 @@
@import 'inc/mixins';
@import '_typography';
@import '_accordion';
@import '_base';
@import '_buttons';
@import '_cardicons-sprite';
@ -12,3 +13,4 @@
@import '_utils';
@import '_spinner';
@import '_tooltip';
@import '_management';

Просмотреть файл

@ -7,28 +7,20 @@ var webpackConfig = require('../webpack.config.js');
module.exports = {
options: webpackConfig,
dev: {
stats: {
// Configure the console output
colors: true,
modules: true,
reasons: true
},
failOnError: true, // don't report error to grunt if webpack find errors
watch: true, // use webpacks watcher
// Default to all the options in webpackConfig
},
prod: {
failOnError: true, // don't report error to grunt if webpack find errors
output: {
path: path.join(__dirname, '../public/dist/'),
filename: 'bundle.min.js',
filename: '[name].bundle.min.js',
},
plugins: [
new webpack.optimize.UglifyJsPlugin({minimize: true})
],
watch: true, // use webpacks watcher
},
styleguide: {
entry: {
// Explicit entries for the styleguide.
'card-form': './styleguide/jsx/card-form',
'spinner': './styleguide/jsx/spinner',
},
@ -37,8 +29,5 @@ module.exports = {
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js',
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('commons.js'),
],
}
};

Просмотреть файл

@ -27,7 +27,7 @@ describe('App', function() {
function mountView() {
var FluxContainer = helpers.getFluxContainer(redux);
var app = rewire('app');
var app = rewire('apps/payment/app');
app.__set__({
'Login': FakeLogin,
'Purchase': FakePurchase,

Просмотреть файл

@ -1,13 +1,18 @@
'use strict';
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'source-map',
entry: './public/js/main.js',
entry: {
'payment': './public/js/apps/payment/main.js',
'management': './public/js/apps/management/main.js',
},
failOnError: true,
output: {
path: path.join(__dirname, 'public/dist/'),
filename: 'bundle.js',
filename: '[name].bundle.js',
publicPath: 'js/',
sourceMapFilename: '[file].map',
},
@ -22,6 +27,9 @@ module.exports = {
},
],
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('commons.js'),
],
resolve: {
// you can now require('file') instead of require('file.json')
extensions: ['', '.js', '.jsx', '.json'],
@ -31,5 +39,11 @@ module.exports = {
'node_modules/mozilla-payments-config/json/products/',
],
},
stats: {
// Configure the console output
colors: true,
modules: true,
reasons: true,
},
watch: true,
};