Added mock product price modal

no refs.
- added static price modal to product detail page
This commit is contained in:
Peter Zimon 2021-04-09 13:00:41 +02:00
parent 7b99c555c5
commit 80357855aa
9 changed files with 188 additions and 4 deletions

View File

@ -0,0 +1,9 @@
<span class="gh-select">
<OneWaySelect
@options={{this.availablePeriods}}
@optionValuePath="period"
@optionLabelPath="label"
@optionTargetPath="period"
/>
{{svg-jar "arrow-down-small"}}
</span>

View File

@ -0,0 +1,20 @@
import Component from '@ember/component';
const PERIODS = [
{label: 'Daily', period: 'daily'},
{label: 'Weekly', period: 'members'},
{label: 'Monthly', period: 'monthly'},
{label: 'Every 3 months', period: '3-months'},
{label: 'Every 6 months', period: '6-months'},
{label: 'Yearly', period: 'yearly'},
{label: 'Custom', period: 'custom'},
{label: 'One time', period: 'one-time'},
{label: 'Unbilled', period: 'unbilled'}
];
export default Component.extend({
init() {
this._super(...arguments);
this.availablePeriods = PERIODS;
}
});

View File

@ -0,0 +1,106 @@
<header class="modal-header" data-test-modal="webhook-form">
<h1 data-test-text="title">New price</h1>
</header>
<button class="close" href title="Close" {{action "closeModal"}} {{action (optional this.noop) on="mouseDown"}}>
{{svg-jar "close"}}
</button>
<form>
<div class="modal-body">
<div class="gh-main-section-block">
<h4 class="gh-main-section-header small bn">Pricing</h4>
<div class="gh-main-section-content grey gh-product-priceform-block">
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="name">
<label for="name" class="fw6">Name</label>
<GhTextInput
@value=''
@name="name"
@id="name"
@class="gh-input" />
<GhErrorMessage @errors={{this.price.errors}} @property="name" />
</GhFormGroup>
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="description">
<label for="description" class="fw6">Description</label>
<GhTextInput
@value=''
@name="description"
@id="description"
@class="gh-input" />
<GhErrorMessage @errors={{this.price.errors}} @property="description" />
</GhFormGroup>
<div class="gh-product-priceform-period">
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="billing-period">
<label for="billing-period" class="fw6">Billing period</label>
<GhProductsPriceBillingperiod @triggerId="period-input" />
</GhFormGroup>
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="price">
<label for="price" class="fw6">Price</label>
<div class="flex items-center justify-center gh-input-group gh-labs-price-label">
<GhTextInput
@value=''
@type="number"
{{!-- @input={{action (mut this._scratchStripeMonthlyAmount) value="target.value"}} --}}
{{!-- @focus-out={{action "validateStripePlans"}} --}}
/>
<span class="gh-input-append"><span class="ttu">USD</span>/month</span>
</div>
<GhErrorMessage @errors={{this.price.errors}} @property="price" />
</GhFormGroup>
</div>
</div>
<h4 class="gh-main-section-header small bn">Advanced</h4>
<div class="gh-main-section-content grey gh-product-priceform-block">
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="trial-period">
<label for="trial-period" class="fw6">Trial period</label>
<div class="flex items-center justify-center gh-input-group gh-labs-price-label">
<GhTextInput
@value=''
@name="trial-period"
@id="trial-period"
@class="gh-input" />
<span class="gh-input-append">days</span>
</div>
<GhErrorMessage @errors={{this.price.errors}} @property="trial-period" />
</GhFormGroup>
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="welcome-page">
<label for="welcome-page" class="fw6">Welcome page</label>
<GhTextInput
@value=''
@name="welcome-page"
@id="welcome-page"
@class="gh-input" />
<p>Redirect to this URL after signing up with this price</p>
<GhErrorMessage @errors={{this.price.errors}} @property="welcome-page" />
</GhFormGroup>
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="stripe-url">
<label for="stripe-url" class="fw6">Stripe Checkout URL</label>
<GhTextInput
@value='https://example.com/checkout'
@name="stripe-url"
@id="stripe-url"
@disabled={{true}}
@class="gh-input" />
<GhErrorMessage @errors={{this.price.errors}} @property="stripe-url" />
</GhFormGroup>
</div>
</div>
</div>
</form>
<div class="modal-footer">
<button
class="gh-btn"
{{action "closeModal"}}
{{!-- disable mouseDown so it doesn't trigger focus-out validations --}}
{{action (optional this.noop) on="mouseDown"}}
data-test-button="cancel-webhook"
>
<span>Cancel</span>
</button>
<GhTaskButton @buttonText="Save price"
@successText={{this.successText}}
{{!-- @task={{this.saveWebhook}} --}}
@class="gh-btn gh-btn-black gh-btn-icon"
data-test-button="save-webhook" />
</div>

View File

@ -0,0 +1,3 @@
import ModalComponent from 'ghost-admin/components/modal-base';
export default ModalComponent.extend({});

View File

@ -8,6 +8,7 @@ export default class ProductController extends Controller {
@service settings;
@tracked showLeaveSettingsModal = false;
@tracked showPriceModal = false;
leaveRoute(transition) {
if (this.settings.get('hasDirtyAttributes')) {
@ -30,6 +31,11 @@ export default class ProductController extends Controller {
this.leaveSettingsTransition = null;
}
@action
closePriceModal() {
this.showPriceModal = false;
}
@task({drop: true})
*saveTask() {
return yield this.settings.save();

View File

@ -55,7 +55,6 @@ Router.map(function () {
this.route('settings.products', {path: '/settings/products'});
this.route('settings.product', {path: '/settings/product'});
this.route('settings.price', {path: '/settings/price'});
this.route('settings.theme', {path: '/settings/theme'}, function () {
this.route('uploadtheme');

View File

@ -74,6 +74,30 @@
margin: 6vw 0;
}
.fullscreen-modal-body-scrolling .modal-body {
max-height: calc(100vh - 12vw - 12vmin - 24px - 34px - 64px); /* top and bottom margins + extra padding at the bottom + modal header & footer */
overflow-y: scroll;
margin: 0 -32px;
padding: 0 32px;
}
.fullscreen-modal-body-scrolling .modal-footer {
position: relative;
margin: 20px -32px 0;
padding: 0 32px;
}
.fullscreen-modal-body-scrolling .modal-footer:before {
position: absolute;
content: "";
top: -20px;
left: -32px;
right: -32px;
height: 6px;
background: hsla(0,0%,100%,0);
box-shadow: 0 -0.3px 1px rgb(0 0 0 / 3%), 0 -4px 7px rgb(0 0 0 / 6%);
}
/* The modal
/* ---------------------------------------------------------- */

View File

@ -141,4 +141,15 @@
.product-actions-menu.fade-out {
animation-duration: 0.01s;
pointer-events: none;
}
/* Price details */
.gh-product-priceform-block {
margin-bottom: 32px;
}
.gh-product-priceform-period {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 20px;
}

View File

@ -169,13 +169,19 @@
</LinkTo>
</li>
</ol>
<LinkTo @route="settings.product" class="gh-btn gh-btn-green">
<button type="button" class="gh-btn gh-btn-green" {{action (toggle "showPriceModal" this)}}>
<span>New price</span>
</LinkTo>
</button>
</div>
</div>
{{#if this.showPriceModal}}
<GhFullscreenModal @modal="product-price"
@close={{this.closePriceModal}}
@modifier="action wide body-scrolling product-price" />
{{/if}}
{{#if this.showLeaveSettingsModal}}
<GhFullscreenModal
@modal="leave-settings"