0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Added error handling and validation for offer

closes https://github.com/TryGhost/Team/issues/1159

- validates offer fields before save client-side
This commit is contained in:
Rishabh 2021-10-19 13:05:18 +05:30
parent 54f5f659f7
commit eddeb07a52
3 changed files with 68 additions and 17 deletions

View file

@ -160,6 +160,7 @@ export default class OffersController extends Controller {
}
try {
yield this.offer.validate();
yield offer.save();
// replace 'offer.new' route with 'offer' route

View file

@ -24,7 +24,7 @@
<div class="gh-main-section-block no-margin">
<h4 class="gh-main-section-header small bn">Basic</h4>
<div class="gh-main-section-content grey">
<GhFormGroup @errors={{this.errors}} @property="name" class="no-margin">
<GhFormGroup @errors={{this.offer.errors}} @property="name" @hasValidated={{this.offer.hasValidated}} class="no-margin">
<label for="name" class="fw6">Name</label>
<GhTextInput
@name="name"
@ -34,8 +34,10 @@
@input={{this.setOfferName}}
data-test-input="offer-name"
@class="gh-input" />
<GhErrorMessage @errors={{this.errors}} @property="name" />
<p>Will be shown to members on the Stripe Checkout page</p>
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="name" />
</span>
<p>Visible to members on Stripe Checkout page.</p>
</GhFormGroup>
</div>
@ -58,7 +60,7 @@
<GhErrorMessage @errors={{this.errors}} @property="product-cadence" />
</GhFormGroup>
<div class="gh-offer-discount">
<GhFormGroup @errors={{this.errors}} @property="amount">
<GhFormGroup @errors={{this.offer.errors}} @property="amount" @hasValidated={{this.offer.hasValidated}}>
<label for="amount" class="fw6">Amount off</label>
<div class="gh-offer-value percentage">
{{#if (eq this.offer.type 'fixed')}}
@ -84,11 +86,13 @@
@class="gh-input"
/>
{{/if}}
<GhErrorMessage @errors={{this.errors}} @property="amount" />
</div>
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="amount" />
</span>
</GhFormGroup>
<div class="gh-offer-type">
<GhFormGroup @errors={{this.errors}} @property="offer-type" class="no-margin">
<GhFormGroup @errors={{this.offer.errors}} @property="type" @hasValidated={{this.offer.hasValidated}} class="no-margin">
<span class="gh-select">
<OneWaySelect
@value={{this.offer.type}}
@ -101,7 +105,7 @@
/>
{{svg-jar "arrow-down-small"}}
</span>
<GhErrorMessage @errors={{this.errors}} @property="duration" />
<GhErrorMessage @errors={{this.offer.errors}} @property="type" />
</GhFormGroup>
</div>
</div>
@ -120,10 +124,12 @@
/>
{{svg-jar "arrow-down-small"}}
</span>
<span class="error">
<GhErrorMessage @errors={{this.errors}} @property="duration" />
</span>
</GhFormGroup>
{{#if (eq this.offer.duration "repeating")}}
<GhFormGroup @errors={{this.errors}} @property="duration-months" @class="duration-months">
<GhFormGroup @errors={{this.offer.errors}} @property="durationInMonths" @class="duration-months">
<label for="duration-months" class="fw6">Number of months</label>
<GhTextInput
@name="duration-months"
@ -132,7 +138,9 @@
@disabled={{this.isDiscountSectionDisabled}}
@id="duration-months"
@class="gh-input" />
<GhErrorMessage @errors={{this.errors}} @property="duration-months" />
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="durationInMonths" />
</span>
</GhFormGroup>
{{/if}}
</div>
@ -141,7 +149,7 @@
<h4 class="gh-main-section-header small bn">Portal settings</h4>
<div class="gh-main-section-content grey">
<div class="form-col2">
<GhFormGroup @errors={{this.errors}} @property="display-title">
<GhFormGroup @errors={{this.offer.errors}} @property="displayTitle" @hasValidated={{this.offer.hasValidated}}>
<label for="display-title" class="fw6">Display title</label>
<GhTextInput
@name="display-title"
@ -150,9 +158,11 @@
@placeholder="Black Friday Special"
@id="display-title"
@class="gh-input" />
<GhErrorMessage @errors={{this.errors}} @property="display-title" />
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="displayTitle" />
</span>
</GhFormGroup>
<GhFormGroup @errors={{this.errors}} @property="code">
<GhFormGroup @errors={{this.offer.errors}} @property="code" @hasValidated={{this.offer.hasValidated}}>
<label for="code" class="fw6">Offer code</label>
<GhTextInput
@name="code"
@ -161,7 +171,9 @@
@input={{this.setOfferCode}}
@id="code"
@class="gh-input" />
<GhErrorMessage @errors={{this.errors}} @property="code" />
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="code" />
</span>
</GhFormGroup>
</div>
<GhFormGroup @errors={{this.errors}} @property="url" @class="gh-offer-url">
@ -182,16 +194,19 @@
</div>
<GhErrorMessage @errors={{this.errors}} @property="url" />
</GhFormGroup>
<GhFormGroup @errors={{this.errors}} @property="description" class="no-margin">
<GhFormGroup @errors={{this.offer.errors}} @property="displayDescription" class="no-margin">
<label for="description" class="fw6">Description</label>
<GhTextarea
@id="description"
@name="description"
@placeholder="Take advantage of this limited-time offer."
@value={{this.offer.displayDescription}}
@input={{this.setPortalDescription}}
@stopEnterKeyDownPropagation="true"
/>
<GhErrorMessage @errors={{this.errors}} @property="description" />
<span class="error">
<GhErrorMessage @errors={{this.offer.errors}} @property="displayDescription" />
</span>
</GhFormGroup>
</div>
</div>

View file

@ -2,7 +2,7 @@ import BaseValidator from './base';
import validator from 'validator';
export default BaseValidator.create({
properties: ['name'],
properties: ['name', 'amount', 'displayTitle', 'displayDescription', 'code', 'durationInMonths'],
name(model) {
if (!model.name) {
@ -13,5 +13,40 @@ export default BaseValidator.create({
model.errors.add('name', 'Name cannot be longer than 191 characters.');
this.invalidate();
}
},
amount(model) {
if (!model.amount) {
model.errors.add('amount', 'Please enter Amount.');
this.invalidate();
}
},
displayTitle(model) {
if (!model.displayTitle) {
model.errors.add('displayTitle', 'Please enter Display title.');
this.invalidate();
}
},
displayDescription(model) {
if (!validator.isLength(model.displayDescription || '', 0, 191)) {
model.errors.add('displayDescription', 'Display description cannot be longer than 191 characters.');
this.invalidate();
}
},
durationInMonths(model) {
if (model.duration === 'repeating' && !model.durationInMonths) {
model.errors.add('durationInMonths', 'Please enter duration in months.');
this.invalidate();
}
},
code(model) {
if (!model.code) {
model.errors.add('code', 'Please enter code.');
this.invalidate();
}
}
});