mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 22:01:49 +03:00
7374b0f8c6
no issue - dropped `id` attribute added to `<GhBenefitItem>` because it was only using the index resulting in multiple `id="1"` on the page which is invalid HTML and caused Glimmer to complain - added a check for `portalPreviewIframe` existence when the portal message listener in the offer controller is fired because it was occurring out of sync with the tests and throwing async errors that were picked up in random later tests
252 lines
14 KiB
Handlebars
252 lines
14 KiB
Handlebars
<button class="close" href title="Close" type="button" {{action "closeModal"}} {{action (optional this.noop) on="mouseDown"}}>
|
||
{{svg-jar "close"}}
|
||
</button>
|
||
|
||
<div class="gh-product-modal-content" data-test-modal="edit-product">
|
||
<header class="modal-header">
|
||
<h1 data-test-text="title">{{this.title}}</h1>
|
||
</header>
|
||
|
||
<form>
|
||
<div class="modal-body gh-form-edit-product">
|
||
<div class="gh-main-section columns-3">
|
||
<div class="gh-main-section-block span-2">
|
||
<h4 class="gh-main-section-header small bn">Basic</h4>
|
||
<div class="gh-main-section-content grey gh-product-priceform-block">
|
||
{{#unless this.isFreeProduct}}
|
||
<GhFormGroup @errors={{this.errors}} @property="name" data-test-formgroup="name">
|
||
<label for="name" class="fw6">Name</label>
|
||
<GhTextInput
|
||
@value={{readonly this.product.name}}
|
||
@input={{action (mut this.product.name) value="target.value"}}
|
||
@name="name"
|
||
@placeholder="Bronze"
|
||
@id="name"
|
||
@class="gh-input"
|
||
data-test-input="product-name" />
|
||
<GhErrorMessage @errors={{this.errors}} @property="name" />
|
||
</GhFormGroup>
|
||
{{/unless}}
|
||
|
||
<GhFormGroup @errors={{this.errors}} @property="description" data-test-formgroup="description">
|
||
<label for="description" class="fw6">Description</label>
|
||
{{#if this.isFreeProduct}}
|
||
<GhTextInput
|
||
@value={{readonly this.product.description}}
|
||
@input={{action (mut this.product.description) value="target.value"}}
|
||
@name="description"
|
||
@placeholder="Free preview of {{this.settings.title}}"
|
||
@id="description"
|
||
@class="gh-input"
|
||
data-test-input="free-product-description" />
|
||
{{else}}
|
||
<GhTextInput
|
||
@value={{readonly this.product.description}}
|
||
@input={{action (mut this.product.description) value="target.value"}}
|
||
@name="description"
|
||
@placeholder="Full access to premium content"
|
||
@id="description"
|
||
@class="gh-input"
|
||
data-test-input="product-description" />
|
||
{{/if}}
|
||
<GhErrorMessage @errors={{this.errors}} @property="description" />
|
||
</GhFormGroup>
|
||
|
||
{{#unless this.isFreeProduct}}
|
||
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="prices" data-test-formgroup="prices">
|
||
<div class="gh-settings-members-pricelabelcont">
|
||
<label for="monthlyPrice">Prices</label>
|
||
<span>–</span>
|
||
<div>
|
||
<span class="gh-setting-members-currency gh-select">
|
||
<div class="gh-setting-members-currencylabel">
|
||
<span>{{this.currency}}</span>
|
||
{{svg-jar "arrow-down-small"}}
|
||
</div>
|
||
<OneWaySelect
|
||
@value={{this.selectedCurrency}}
|
||
id="currency"
|
||
name="currency"
|
||
@options={{readonly this.allCurrencies}}
|
||
@optionValuePath="value"
|
||
@optionLabelPath="label"
|
||
@update={{action "setCurrency"}}
|
||
/>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<div class="gh-setting-members-prices">
|
||
|
||
<div class="gh-input-group">
|
||
<GhTextInput
|
||
@id="monthlyPrice"
|
||
@value={{readonly this.stripeMonthlyAmount}}
|
||
@type="number"
|
||
@input={{action (mut this.stripeMonthlyAmount) value="target.value"}}
|
||
@focus-out={{action "validateStripePlans"}}
|
||
/>
|
||
<span class="gh-input-append"><span class="ttu">{{this.currency}}</span>/month</span>
|
||
</div>
|
||
<div class="gh-input-group">
|
||
<GhTextInput
|
||
@id="yearlyPrice"
|
||
@value={{readonly this.stripeYearlyAmount}}
|
||
@type="number"
|
||
@input={{action (mut this.stripeYearlyAmount) value="target.value"}}
|
||
@focus-out={{this.validateStripePlans}}
|
||
@placeholder=''
|
||
data-test-title-input={{true}}
|
||
/>
|
||
<span class="gh-input-append"><span class="ttu">{{this.currency}}</span>/year</span>
|
||
</div>
|
||
</div>
|
||
{{#if this.stripePlanError}}
|
||
<p class="response w-100"><span class="red">{{this.stripePlanError}}</span></p>
|
||
{{/if}}
|
||
</GhFormGroup>
|
||
{{#if (feature "tierWelcomePages")}}
|
||
<GhFormGroup>
|
||
<label for="welcomePage" class="fw6">Welcome page</label>
|
||
<GhUrlInput
|
||
@id="welcomePage"
|
||
@value={{readonly this.model.product.welcomePageURL}}
|
||
@baseUrl={{readonly this.siteUrl}}
|
||
@setResult={{this.setWelcomePageURL}}
|
||
@validateUrl={{this.validateWelcomePageURL}}
|
||
@placeholder={{readonly this.siteUrl}}
|
||
/>
|
||
{{#if this.isFreeProduct}}
|
||
<p>Redirect to this URL after signup for a free membership</p>
|
||
{{else}}
|
||
<p>Redirect to this URL after signup for premium membership</p>
|
||
{{/if}}
|
||
</GhFormGroup>
|
||
{{/if}}
|
||
{{/unless}}
|
||
</div>
|
||
|
||
<h4 class="gh-main-section-header small bn">Benefits</h4>
|
||
<div class="gh-main-section-content grey gh-product-form-benefits">
|
||
<div class="gh-product-benefits">
|
||
<form id="product-benefits" class="gh-blognav" novalidate="novalidate">
|
||
<SortableObjects
|
||
@sortableObjectList={{this.benefits}}
|
||
@useSwap={{false}}
|
||
@sortEndAction={{action "reorderItems"}}
|
||
>
|
||
{{#each this.benefits as |benefitItem index|}}
|
||
<DraggableObject @content={{benefitItem}} @dragHandle=".gh-blognav-grab" @isSortable={{true}}>
|
||
<GhBenefitItem
|
||
@benefitItem={{benefitItem}}
|
||
@addItem={{action "addBenefit"}}
|
||
@focusItem={{action "focusItem"}}
|
||
@deleteItem={{action "deleteBenefit"}}
|
||
@updateLabel={{action "updateLabel"}}
|
||
data-test-benefit-item={{index}} />
|
||
</DraggableObject>
|
||
{{/each}}
|
||
</SortableObjects>
|
||
<GhBenefitItem
|
||
@isFreeProduct={{this.isFreeProduct}}
|
||
@benefitItem={{this.newBenefit}}
|
||
@addItem={{action "addBenefit"}}
|
||
@deleteItem={{action "deleteBenefit"}}
|
||
@updateLabel={{action "updateLabel"}}
|
||
data-test-benefit-item="new" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="gh-main-section-block gh-product-form-tierpreview" data-test-tierpreview>
|
||
<div class="gh-product-form-tierpreview-content">
|
||
{{#if this.isFreeProduct}}
|
||
<h4 class="gh-main-section-header small bn" data-test-tierpreview-title>Free Membership Preview</h4>
|
||
{{else}}
|
||
<h4 class="gh-main-section-header small bn" data-test-tierpreview-title>Tier Preview</h4>
|
||
{{/if}}
|
||
<div class="gh-main-section-content" style="border-color: {{this.settings.accentColor}}">
|
||
<span class="checkmark" style="background-color: {{this.settings.accentColor}}"></span>
|
||
|
||
{{#if this.product.name}}
|
||
<h4 data-test-tierpreview-name>{{this.product.name}}</h4>
|
||
{{else}}
|
||
<h4 class="placeholder" data-test-tierpreview-name>Bronze</h4>
|
||
{{/if}}
|
||
|
||
{{#if this.product.description}}
|
||
<p data-test-tierpreview-description>{{this.product.description}}</p>
|
||
{{else}}
|
||
{{#if this.isFreeProduct}}
|
||
<p class="placeholder" data-test-tierpreview-description>Free preview of {{this.settings.title}}</p>
|
||
{{else}}
|
||
<p class="placeholder" data-test-tierpreview-description>Full access to premium content</p>
|
||
{{/if}}
|
||
{{/if}}
|
||
|
||
{{#if this.benefits}}
|
||
<ul data-test-tierpreview-benefits>
|
||
{{#each this.benefits as |benefitItem index|}}
|
||
<li>{{svg-jar "check-2"}} <span>{{benefitItem.name}}</span></li>
|
||
{{/each}}
|
||
</ul>
|
||
{{else}}
|
||
<ul class="placeholder" data-test-tierpreview-benefits>
|
||
{{#if this.isFreeProduct}}
|
||
<li>{{svg-jar "check-2"}} <span>Access to all public posts</span></li>
|
||
{{else}}
|
||
<li>{{svg-jar "check-2"}} <span>Expert analysis</span></li>
|
||
{{/if}}
|
||
</ul>
|
||
{{/if}}
|
||
<div class="price" data-test-tierpreview-price>
|
||
{{#if this.isFreeProduct}}
|
||
<span class="monthly-price">
|
||
<span class="currency">{{currency-symbol this.currency}}</span>
|
||
0
|
||
</span>
|
||
{{else}}
|
||
{{#if this.stripeMonthlyAmount}}
|
||
<span class="monthly-price">
|
||
<span class="currency">{{currency-symbol this.currency}}</span>
|
||
{{format-number this.stripeMonthlyAmount}}
|
||
<span class="period">/month</span>
|
||
</span>
|
||
{{else}}
|
||
<span class="monthly-price placeholder">
|
||
<span class="currency">{{currency-symbol this.currency}}</span>
|
||
0
|
||
<span class="period">/month</span>
|
||
</span>
|
||
{{/if}}
|
||
|
||
{{#if this.stripeYearlyAmount}}
|
||
<span class="yearly-price">{{currency-symbol this.currency}}{{format-number this.stripeYearlyAmount}}/year</span>
|
||
{{else}}
|
||
<span class="yearly-price placeholder">0<span class="currency">{{this.currency}}</span>/year</span>
|
||
{{/if}}
|
||
{{/if}}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="modal-footer top-shadow items-center">
|
||
<button
|
||
class="gh-btn" data-test-button="cancel-webhook" type="button" {{action "closeModal"}}
|
||
{{!-- disable mouseDown so it doesn't trigger focus-out validations --}}
|
||
{{action (optional this.noop) on="mouseDown"}}
|
||
>
|
||
<span>Cancel</span>
|
||
</button>
|
||
<GhTaskButton @buttonText="{{if this.isExistingProduct "Save" "Add tier"}}"
|
||
@successText={{this.successText}}
|
||
@task={{this.saveProduct}}
|
||
@idleClass="gh-btn-primary"
|
||
@class="gh-btn {{if this.isExistingProduct "gh-btn-black" "gh-btn-green"}} gh-btn-icon"
|
||
data-test-button="save-product" />
|
||
</div>
|