Add initial management page (fixes #171)
This commit is contained in:
Родитель
afc4f96222
Коммит
dd5cfdace2
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 5.1 KiB |
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче