improvements to modals for mobile. improvements to billing page layout.

This commit is contained in:
Cole 2018-09-26 07:57:56 -04:00
parent 57cee01051
commit 6c01e2d4c4
5 changed files with 291 additions and 248 deletions

View File

@ -66,15 +66,123 @@ export default class FormSettings extends React.Component {
}
}
render() {
let {form} = this.props
renderSyntaxModal() {
return (
<>
<Modal
title="Email Syntax"
opened={this.state.modal === MODAL_SYNTAX}
onClose={this.closeModal}
>
<div>
<div>
<p>
the email body can contain simple HTML that's valid in an email.
No <span className="code">&lt;script&gt;</span> or{' '}
<span className="code">&lt;style&gt;</span> tags can be{' '}
included. For a list of recommended HTML tags see{' '}
<a
href="https://explore.reallygoodemails.com/new-to-email-coding-heres-where-to-start-2494422f0bd4"
target="_blank"
>
this guide to HTML in email
</a>
.
</p>
<p>
The following special variables are recognized by Formspree,
using the{' '}
<a
href="https://mustache.github.io/mustache.5.html"
target="_blank"
>
mustache
</a>{' '}
template language.
</p>
<pre>
{`
{{ _time }} The date and time of the submission.
{{ _host }} The URL of the form (without "https://").
{{ <fieldname> }} Any named input value in your form.
{{# _fields }} Starts a list of all fields.
{{ _name }} Within _fields, the current field name
{{ _value }} and field value.
{{/ _fields }} Closes the _fields block.
`.trim()}
</pre>
<div className="container right">
<button onClick={this.closeModal}>OK</button>
</div>
</div>
</div>
</Modal>
</>
)
}
renderRevertModal() {
return (
<>
<Modal
title="Revert changes"
opened={this.state.modal === MODAL_REVERT}
onClose={this.closeModal}
>
<div>
<div>
<h2>Are you sure?</h2>
<p>
Reverting will discard the changes you've made to your email
template.
</p>
</div>
<div className="container right">
<button onClick={this.closeModal}>Cancel</button>
<button onClick={this.revert}>Revert</button>
</div>
</div>
</Modal>
</>
)
}
renderPreviewModal(from_name, subject, style, body) {
return (
<>
<Modal
title="Preview"
opened={this.state.modal === MODAL_PREVIEW}
onClose={this.closeModal}
>
<div id="whitelabel-preview-modal">
<iframe
className="preview"
src={
'/forms/whitelabel/preview?' +
qs.stringify({
from_name,
subject,
style,
body
})
}
/>
<div className="container right">
<button onClick={this.closeModal}>OK</button>
</div>
</div>
</Modal>
</>
)
}
render() {
let {from_name, subject, style, body} = {
...this.defaultValues,
...form.template,
...this.props.template,
...this.state.changes
}
var shownCode
switch (this.state.activeTab) {
case 'CSS':
@ -142,6 +250,7 @@ export default class FormSettings extends React.Component {
</a>
</div>
</div>
{this.renderSyntaxModal()}
<div className="col-1-1">
<div className="code-tabs">
{this.availableTabs.map(tabName => (
@ -160,6 +269,7 @@ export default class FormSettings extends React.Component {
</div>
<div className="container">
{this.renderPreviewModal(from_name, subject, style, body)}
<div className="col-1-3">
<button onClick={this.preview}>Preview</button>
</div>
@ -169,6 +279,7 @@ export default class FormSettings extends React.Component {
: '\u00A0'}
</div>
<div className="col-1-6 right">
{this.renderRevertModal()}
<button
onClick={this.attemptRevert}
disabled={Object.keys(this.state.changes).length === 0}
@ -185,97 +296,7 @@ export default class FormSettings extends React.Component {
</button>
</div>
</div>
</div>
<Modal
title="Revert changes"
opened={this.state.modal === MODAL_REVERT}
onClose={this.closeModal}
>
<div>
<div>
<h2>Are you sure?</h2>
<p>
Reverting will discard the changes you've made to your email
template.
</p>
</div>
<div className="container right">
<button onClick={this.closeModal}>Cancel</button>
<button onClick={this.revert}>Revert</button>
</div>
</div>
</Modal>
<Modal
title="Preview"
opened={this.state.modal === MODAL_PREVIEW}
onClose={this.closeModal}
>
<div id="whitelabel-preview-modal">
<iframe
className="preview"
src={
'/forms/whitelabel/preview?' +
qs.stringify({
from_name,
subject,
style,
body
})
}
/>
<div className="container right">
<button onClick={this.closeModal}>OK</button>
</div>
</div>
</Modal>
<Modal
title="Email Syntax"
opened={this.state.modal === MODAL_SYNTAX}
onClose={this.closeModal}
>
<div>
<div>
<p>
the email body can contain simple HTML that's valid in an email.
No <span className="code">&lt;script&gt;</span> or{' '}
<span className="code">&lt;style&gt;</span> tags can be{' '}
included. For a list of recommended HTML tags see{' '}
<a
href="https://explore.reallygoodemails.com/new-to-email-coding-heres-where-to-start-2494422f0bd4"
target="_blank"
>
this guide to HTML in email
</a>
.
</p>
<p>
The following special variables are recognized by Formspree,
using the{' '}
<a
href="https://mustache.github.io/mustache.5.html"
target="_blank"
>
mustache
</a>{' '}
template language.
</p>
<pre>
{`
{{ _time }} The date and time of the submission.
{{ _host }} The URL of the form (without "https://").
{{ <fieldname> }} Any named input value in your form.
{{# _fields }} Starts a list of all fields.
{{ _name }} Within _fields, the current field name
{{ _value }} and field value.
{{/ _fields }} Closes the _fields block.
`.trim()}
</pre>
<div className="container right">
<button onClick={this.closeModal}>OK</button>
</div>
</div>
</div>
</Modal>
</div>
</>
)
}

View File

@ -166,9 +166,10 @@ button + button {
}
.row:after {
content: "";
content: ".";
display: none;
}
.card {
border-width: 0
}
@ -373,19 +374,24 @@ button + button {
}
.modal {
position: relative;
& > * {
z-index: -1000;
background: #fefefe;
border: #333333 solid 1px;
border-radius: 5px;
margin-left: -385px;
position: fixed;
left: 50%;
top: -100%;
z-index: 11;
top: 10%;
width: 770px;
transform: translate(0, -500%);
transition: transform 0.5s ease-out;
padding: 0.3em 1.3em 1.3em 1.3em;
transform: translate(0, 10%);
opacity: 0;
transition-property: transform, opacity;
transition-duration: 0.2s;
transition-timing-function: ease-out;
.x {
a {
@ -401,12 +407,21 @@ button + button {
}
& + * { clear: both; }
}
@media (max-width: 760px) {
margin-left: 0;
position: absolute;
left: 0;
width: 100%;
}
}
&.narrow {
& > * {
width: 500px;
margin-left: -290px;
@media (min-width: 761px) {
&.narrow {
& > * {
width: 500px;
margin-left: -290px;
}
}
}
@ -462,10 +477,16 @@ button + button {
}
}
&.target > * {
z-index: 1000;
opacity: 1;
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
top: 10%;
@media (max-width: 760px) {
-webkit-transform: translate(0, -100%);
-ms-transform: translate(0, -100%);
transform: translate(0, -100%);
}
}
.red {
@ -501,9 +522,6 @@ button + button {
}
#whitelabel {
.container {
padding-bottom: 0;
}
#from_name::after {
content: ' submissions@formspree.io';
@ -531,10 +549,9 @@ button + button {
#whitelabel-preview-modal {
.preview {
padding: 12px;
margin: 12px;
border: 5px dotted #444;
width: 700px;
height: 600px;
border: 2px dotted #AAA;
width: 100%;
height: 450px;
}
}

View File

@ -114,10 +114,6 @@ body#card {
padding-top: 1em;
padding-bottom: 1em;
@media (max-width: 760px) {
padding-bottom: 0 !important;
}
&.block {
padding-bottom: 1.5em;
padding-top: 1.5em;

View File

@ -6,132 +6,149 @@
{% block section %}
<div class="row">
<div class="container">
<div class="col-1-2">
<div class="card">
<h3>Plan</h3>
{% if current_user.has_feature('dashboard') %}
<p>You are a {{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }} user.</p>
{% if sub.cancel_at_period_end %}
<p>You've cancelled your subscription and it is ending on {{ sub.current_period_end }}.</p>
<div class="container">
<p>You are a {{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }} user.</p>
{% if sub.cancel_at_period_end %}
<p>You've cancelled your subscription and it is ending on {{ sub.current_period_end }}.</p>
</div>
<form action="/account/resubscribe" method="POST">
<button type="submit">Resubscribe</button>
<button type="submit">Resubscribe</button>
</form>
{% else %}
<p>Your subscription will automatically renew on {{ sub.current_period_end }}.</p>
{% else %}
<p>Your subscription will automatically renew on {{ sub.current_period_end }}.</p>
</div>
<div class="modal" id="cancel-feedback" aria-hidden="true">
<div class="container">
<div class="x">
<h4>Why are you cancelling?</h4>
<a href="#">&times;</a>
</div>
<form action="/account/downgrade" method="POST">
<textarea name="why" placeholder="Was it a missing feature? Bad service? Just don't need us anymore?"></textarea>
<button type="submit">Cancel Subscription</button>
</form>
</div>
</div>
<a href="#cancel-feedback" class="button">Cancel subscription</a>
{% endif %}
{% else %}
When you upgrade to <strong>{{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }}</strong> you will get
<ol style="text-align: left">
<li>Unlimited submissions</li>
<li>Access to submission archives</li>
<li>Ability to hide your email from your page's HTML and replace it with a random-like URL</li>
<li>Ability to create forms linked to other email accounts</li>
</ol>
<div class="container">
When you upgrade to <strong>{{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }}</strong> you will get
<ol style="text-align: left">
<li>Unlimited submissions</li>
<li>Access to submission archives</li>
<li>Ability to hide your email from your page's HTML and replace it with a random-like URL</li>
<li>Ability to create forms linked to other email accounts</li>
</ol>
</div>
<h6 class="light">You are using a free account and should upgrade.</h6>
<form method="post" action="/account/upgrade">
<button id="stripe-upgrade"
data-key="{{ config.STRIPE_PUBLISHABLE_KEY }}"
data-image="/static/img/logo.png"
data-name="{{ config.SERVICE_NAME }}"
data-description="{{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }} monthly subscription"
data-amount="999"
data-email="{{ current_user.email }}"
data-allowRememberMe=false
data-zip-code=true
data-locale=true
data-panel-label="Subscribe"
>Upgrade for 9.99 / month
</button>
<button id="stripe-upgrade"
data-key="{{ config.STRIPE_PUBLISHABLE_KEY }}"
data-image="/static/img/logo.png"
data-name="{{ config.SERVICE_NAME }}"
data-description="{{ config.SERVICE_NAME }} {{ config.UPGRADED_PLAN_NAME }} monthly subscription"
data-amount="999"
data-email="{{ current_user.email }}"
data-allowRememberMe=false
data-zip-code=true
data-locale=true
data-panel-label="Subscribe"
>Upgrade for 9.99 / month
</button>
</form>
{% endif %}
</div>
</div>
<div class="col-1-2">
<h3>Wallet</h3>
{% if cards %}
<table id="card-list">
{% for card in cards %}
<tr>
<td>
<div class="arrow"><i class="fa fa-chevron-right" aria-hidden="true"></i></div>
</td>
<td><i class="fa fa-{{ card.css_name }}" aria-hidden="true"></i></td>
<td>••••{{ card.last4 }}</td>
<td>{{ card.exp_month }}/{{ card.exp_year }}</td>
</tr>
<tr>
<td colspan="4">
<div class="actions" style="float:right;width:50%;padding-left:20%;">
{% if card.default %}
<p>
<button style="color:white;background:#359173;border:none;" class="disabled" disabled>Default
</button>
</p>
{% else %}
<form action="{{ url_for('change-default-card', cardid=card.id) }}" method="POST">
<button type="submit" style="margin-bottom: 18px;">Make Default</button>
</form>
{% endif %}
<form action="{{ url_for('delete-card', cardid=card.id) }}" method="POST">
<button type="submit">Delete</button>
</form>
</div>
<div class="row">
<p>Number: ••••{{ card.last4 }}</p>
<p>Type: {{ card.brand }} {{ card.funding }} card</p>
<p>Origin: {{ card.country }} <img
src="{{ url_for('static', filename='img/countries/%s.png' % card.country.lower()) }}"
width="25"></p>
<p>CVC Check: {% if card.cvc_check == "pass" %}Passed
<i class="fa fa-check-circle-o" aria-hidden="true"></i>{% elif card.cvc_check == "fail" %}Failed
<i class="fa fa-times-circle-o" aria-hidden="true"></i>{% else %}Unknown
<i class="fa fa-question-circle" aria-hidden="true"></i>{% endif %}</p>
</div>
</td>
</tr>
{% endfor %}
</table>
<h3>Wallet</h3>
{% if cards %}
<div class="container">
<table id="card-list">
{% for card in cards %}
<tr>
<td>
<div class="arrow"><i class="fa fa-chevron-right" aria-hidden="true"></i></div>
</td>
<td><i class="fa fa-{{ card.css_name }}" aria-hidden="true"></i></td>
<td>••••{{ card.last4 }}</td>
<td>{{ card.exp_month }}/{{ card.exp_year }}</td>
</tr>
<tr>
<td colspan="4">
<div class="actions" style="float:right;width:50%;padding-left:20%;">
{% if card.default %}
<p>
<button style="color:white;background:#359173;border:none;" class="disabled" disabled>Default
</button>
</p>
{% else %}
<form action="{{ url_for('change-default-card', cardid=card.id) }}" method="POST">
<button type="submit" style="margin-bottom: 18px;">Make Default</button>
</form>
{% endif %}
<form action="{{ url_for('delete-card', cardid=card.id) }}" method="POST">
<button type="submit">Delete</button>
</form>
</div>
<div class="row">
<p>Number: ••••{{ card.last4 }}</p>
<p>Type: {{ card.brand }} {{ card.funding }} card</p>
<p>Origin: {{ card.country }} <img
src="{{ url_for('static', filename='img/countries/%s.png' % card.country.lower()) }}"
width="25"></p>
<p>CVC Check: {% if card.cvc_check == "pass" %}Passed
<i class="fa fa-check-circle-o" aria-hidden="true"></i>{% elif card.cvc_check == "fail" %}Failed
<i class="fa fa-times-circle-o" aria-hidden="true"></i>{% else %}Unknown
<i class="fa fa-question-circle" aria-hidden="true"></i>{% endif %}</p>
</div>
</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
<p>We couldn't find any active cards in your wallet. Please make sure to add a card
by {{ sub.current_period_end }} or your subscription won't renew.</p>
<p>We couldn't find any active cards in your wallet. Please make sure to add a card
by {{ sub.current_period_end }} or your subscription won't renew.</p>
{% endif %}
{% include "users/card.html" %}
</div>
</div>
<div class="row">
<div class="container section">
<div class="col-1-1">
<h3>Invoices</h3>
<div class="card">
<table id="invoices">
<col width="20%">
<col width="35%">
<col width="10%">
<col width="10%">
<col width="25%">
{% for invoice in invoices %}
{% if invoice.attempted %}
<tr>
<td>{{ invoice.date|epoch_to_date }}</td>
<td>{{ invoice.id }}</td>
<td>${{ invoice.total/100 }}</td>
<td>{% if invoice.paid %}Paid{% else %}Unpaid{% endif %}</td>
<td><a href="{{ url_for('invoice', invoice_id=invoice.id[3:]) }}" class="button" target="_blank">View
Details</a></td>
</tr>
{% endif %}
{% endfor %}
</table>
<div class="create-form">
<a href="#edit-billing" class="button">
Edit Invoice Address
</a>
<div class="modal narrow" id="edit-billing" aria-hidden="true">
<div class="container">
<table id="invoices">
<col width="20%">
<col width="35%">
<col width="10%">
<col width="10%">
<col width="25%">
{% for invoice in invoices %}
{% if invoice.attempted %}
<tr>
<td>{{ invoice.date|epoch_to_date }}</td>
<td>{{ invoice.id }}</td>
<td>${{ invoice.total/100 }}</td>
<td>{% if invoice.paid %}Paid{% else %}Unpaid{% endif %}</td>
<td><a href="{{ url_for('invoice', invoice_id=invoice.id[3:]) }}" class="button" target="_blank">View
Details</a></td>
</tr>
{% endif %}
{% endfor %}
</table>
</div>
<div class="modal narrow" id="edit-billing" aria-hidden="true">
<div class="container">
<div class="x"><h4>Edit Invoice Address</h4><a href="#">&times;</a></div>
<form method="POST" action="{{ url_for('update-invoice-address') }}">
@ -141,23 +158,14 @@
</div>
</form>
</div>
</div>
</div>
<a href="#edit-billing" class="button">
Edit Invoice Address
</a>
</div>
</div>
</div>
</div>
<div class="modal" id="cancel-feedback" aria-hidden="true">
<div class="container">
<div class="x">
<h4>Why are you cancelling?</h4>
<a href="#">&times;</a>
</div>
<form action="/account/downgrade" method="POST">
<textarea name="why" placeholder="Was it a missing feature? Bad service? Just don't need us anymore?"></textarea>
<button type="submit">Cancel Subscription</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -1,23 +1,24 @@
<div class="create-form">
<a href="#add-card" class="button">
Add Card
</a>
<div class="modal narrow" id="add-card" aria-hidden="true">
<div class="container">
<div class="x">
<h4>Add Card</h4><a href="#">&times;</a></div>
<form method="POST" action="{{ url_for('add-card') }}" id="payment-form">
<div id="card-element" class="field"></div>
<div class="col-1-1">
<input type="submit" class="submit card" value="Add Card">
</div>
</form>
<div class="col-1-1 small">
<p>Secured with <i class="fa fa-cc-stripe" aria-hidden="true"></i>. {{ config.SERVICE_NAME }} never sees your card number</p>
<div class="modal narrow" id="add-card" aria-hidden="true">
<div class="container">
<div class="x">
<h4>Add Card</h4><a href="#">&times;</a>
</div>
<form method="POST" action="{{ url_for('add-card') }}" id="payment-form">
<div id="card-element" class="field"></div>
<div class="col-1-1">
<input type="submit" class="submit card" value="Add Card">
</div>
</form>
<div class="col-1-1 small">
<p>Secured with <i class="fa fa-cc-stripe" aria-hidden="true"></i>. {{ config.SERVICE_NAME }} never sees your card number</p>
</div>
</div>
</div>
<a href="#add-card" class="button">
Add Card
</a>
<script>
var stripe = Stripe('{{ config.STRIPE_PUBLISHABLE_KEY }}');
var elements = stripe.elements();