mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
Update offer details structure
- Added static UI to offer details page - Deleted offer modal
This commit is contained in:
parent
6e6c89ba00
commit
96ec92a47b
@ -1,140 +0,0 @@
|
||||
<section class="modal-content" {{did-insert this.setup}}>
|
||||
<div class="gh-offer-modal-content">
|
||||
<header class="modal-header">
|
||||
<h1>New offer</h1>
|
||||
</header>
|
||||
<form>
|
||||
<div class="modal-body">
|
||||
<div class="gh-main-section columns-3">
|
||||
<div class="gh-main-section-block no-margin span-2">
|
||||
<h4 class="gh-main-section-header small bn">Basic</h4>
|
||||
<div class="gh-main-section-content grey">
|
||||
<GhFormGroup @errors={{this.errors}} @property="name">
|
||||
<label for="name" class="fw6">Name</label>
|
||||
<GhTextInput
|
||||
@name="name"
|
||||
@placeholder="Black Friday"
|
||||
@id="name"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="name" />
|
||||
<p>User internally</p>
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
|
||||
<h4 class="gh-main-section-header small bn">Discount info</h4>
|
||||
<div class="gh-main-section-content grey">
|
||||
<GhFormGroup @errors={{this.errors}} @property="product-cadence">
|
||||
<label for="product-cadence" class="fw6">Product – cadence</label>
|
||||
<span class="gh-select">
|
||||
<OneWaySelect @value={{this.selectedVisibility}}
|
||||
@options={{this.cadences}}
|
||||
@optionValuePath="name"
|
||||
@optionLabelPath="label"
|
||||
@optionTargetPath="name"
|
||||
@update={{this.updateVisibility}}
|
||||
/>
|
||||
{{svg-jar "arrow-down-small"}}
|
||||
</span>
|
||||
<GhErrorMessage @errors={{this.errors}} @property="product-cadence" />
|
||||
</GhFormGroup>
|
||||
<div class="form-col2">
|
||||
<div class="gh-offer-type">
|
||||
<div class="gh-radio {{if (eq this.selectedDiscountType "percentage") "active"}}" {{on "click" (fn this.setDiscountType "percentage")}}>
|
||||
<div class="gh-radio-button"></div>
|
||||
<div class="gh-radio-content">
|
||||
<div class="gh-radio-label">Percentage discount</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio {{if (eq this.selectedDiscountType "fixed") "active"}}" {{on "click" (fn this.setDiscountType "fixed")}}>
|
||||
<div class="gh-radio-button"></div>
|
||||
<div class="gh-radio-content">
|
||||
<div class="gh-radio-label">Fixed amount discount</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if (eq this.selectedDiscountType "percentage")}}
|
||||
<GhFormGroup @errors={{this.errors}} @property="amount">
|
||||
<label for="amount" class="fw6">Percentage off</label>
|
||||
<GhTextInput
|
||||
@type="number"
|
||||
@name="amount"
|
||||
@placeholder=""
|
||||
@id="amount"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="amount" />
|
||||
</GhFormGroup>
|
||||
{{else}}
|
||||
<GhFormGroup @errors={{this.errors}} @property="amount">
|
||||
<label for="amount" class="fw6">Amount off</label>
|
||||
<GhTextInput
|
||||
@name="amount"
|
||||
@type="number"
|
||||
@placeholder=""
|
||||
@id="amount"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="amount" />
|
||||
</GhFormGroup>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<label for="display-title" class="fw6">Display title</label>
|
||||
<GhTextInput
|
||||
@name="display-title"
|
||||
@placeholder="Black Friday Special"
|
||||
@id="display-title"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="display-title" />
|
||||
</GhFormGroup>
|
||||
<GhFormGroup @errors={{this.errors}} @property="code">
|
||||
<label for="code" class="fw6">Offer code</label>
|
||||
<GhTextInput
|
||||
@name="code"
|
||||
@placeholder="black-friday"
|
||||
@id="code"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="code" />
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
<GhFormGroup @errors={{this.errors}} @property="description">
|
||||
<label for="description" class="fw6">Description</label>
|
||||
<GhTextarea
|
||||
@id="description"
|
||||
@name="description"
|
||||
@stopEnterKeyDownPropagation="true"
|
||||
/>
|
||||
<GhErrorMessage @errors={{this.errors}} @property="description" />
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-main-section-block no-margin">
|
||||
<h4 class="gh-main-section-header small bn">Portal preview</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer top-shadow">
|
||||
<button
|
||||
class="gh-btn"
|
||||
{{on "click" @close}}
|
||||
{{!-- disable mouseDown so it doesn't trigger focus-out validations --}}
|
||||
{{on "mousedown" (optional this.noop)}}
|
||||
data-test-button="cancel-offer"
|
||||
>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
|
||||
<GhTaskButton @buttonText="Add offer"
|
||||
@successText={{"Added"}}
|
||||
{{!-- @task={{this.addProduct}} --}}
|
||||
@class="gh-btn gh-btn-green gh-btn-icon gh-btn-add-memberproduct"
|
||||
data-test-button="save-comp-product" />
|
||||
</div>
|
||||
</section>
|
@ -1,50 +0,0 @@
|
||||
import Component from '@glimmer/component';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default class ModalsMembershipOfferComponent extends Component {
|
||||
@service config;
|
||||
@service settings;
|
||||
@service store;
|
||||
@tracked cadences = [];
|
||||
@tracked products = [];
|
||||
@tracked selectedDiscountType = 'percentage';
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*fetchProducts() {
|
||||
this.products = yield this.store.query('product', {include: 'monthly_price,yearly_price,benefits'});
|
||||
const cadences = [];
|
||||
this.products.forEach((product) => {
|
||||
cadences.push({
|
||||
label: `${product.name} - Monthly`,
|
||||
name: product.monthlyPrice.id
|
||||
});
|
||||
cadences.push({
|
||||
label: `${product.name} - Yearly`,
|
||||
name: product.yearlyPrice.id
|
||||
});
|
||||
});
|
||||
this.cadences = cadences;
|
||||
}
|
||||
|
||||
@action
|
||||
setup() {
|
||||
this.fetchProducts.perform();
|
||||
}
|
||||
|
||||
@action
|
||||
setDiscountType(discountType) {
|
||||
this.selectedDiscountType = discountType;
|
||||
}
|
||||
|
||||
@action
|
||||
updateVisibility(tab) {
|
||||
this.tab = tab;
|
||||
}
|
||||
}
|
@ -1,7 +1,51 @@
|
||||
import Controller from '@ember/controller';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default class MembersController extends Controller {
|
||||
@service config;
|
||||
@service settings;
|
||||
@service store;
|
||||
@tracked cadences = [];
|
||||
@tracked products = [];
|
||||
@tracked selectedDiscountType = 'percentage';
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.setup();
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*fetchProducts() {
|
||||
this.products = yield this.store.query('product', {include: 'monthly_price,yearly_price,benefits'});
|
||||
const cadences = [];
|
||||
this.products.forEach((product) => {
|
||||
cadences.push({
|
||||
label: `${product.name} - Monthly`,
|
||||
name: product.monthlyPrice.id
|
||||
});
|
||||
cadences.push({
|
||||
label: `${product.name} - Yearly`,
|
||||
name: product.yearlyPrice.id
|
||||
});
|
||||
});
|
||||
this.cadences = cadences;
|
||||
}
|
||||
|
||||
@action
|
||||
save() {}
|
||||
setup() {
|
||||
this.fetchProducts.perform();
|
||||
}
|
||||
|
||||
@action
|
||||
setDiscountType(discountType) {
|
||||
this.selectedDiscountType = discountType;
|
||||
}
|
||||
|
||||
@action
|
||||
updateVisibility(tab) {
|
||||
this.tab = tab;
|
||||
}
|
||||
}
|
@ -44,9 +44,7 @@ Router.map(function () {
|
||||
|
||||
this.route('settings');
|
||||
this.route('settings.general', {path: '/settings/general'});
|
||||
this.route('settings.membership', {path: '/settings/members'}, function () {
|
||||
this.route('offer');
|
||||
});
|
||||
this.route('settings.membership', {path: '/settings/members'});
|
||||
this.route('settings.members-email', {path: '/settings/members-email'});
|
||||
this.route('settings.code-injection', {path: '/settings/code-injection'});
|
||||
|
||||
|
@ -989,6 +989,20 @@
|
||||
max-width: var(--main-layout-content-maxwidth);
|
||||
}
|
||||
|
||||
.gh-canvas.circle-bg::before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: "";
|
||||
top: -450px;
|
||||
right: -250px;
|
||||
width: 970px;
|
||||
height: 970px;
|
||||
border-radius: 50%;
|
||||
z-index: 0;
|
||||
background: var(--main-color-content-greybg);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.gh-canvas-header {
|
||||
margin: 0;
|
||||
position: sticky;
|
||||
@ -999,6 +1013,11 @@
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.gh-canvas.circle-bg .gh-canvas-header {
|
||||
position: relative;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.gh-canvas-header.grey,
|
||||
.gh-main-grey .gh-canvas-header {
|
||||
background: var(--main-color-content-greybg);
|
||||
@ -1029,6 +1048,25 @@
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
/* Main layouts */
|
||||
.gh-main-layout.content-preview {
|
||||
display: grid;
|
||||
grid-template-columns: auto 460px;
|
||||
grid-gap: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: 1320px) {
|
||||
.gh-main-layout.content-preview {
|
||||
grid-gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1140px) {
|
||||
.gh-main-layout.content-preview {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main sections */
|
||||
/*
|
||||
.gh-main-section [columns-2|columns-3]
|
||||
|
@ -72,18 +72,50 @@
|
||||
}
|
||||
|
||||
.gh-offer-type {
|
||||
display: grid;
|
||||
grid-template-columns: 160px auto;
|
||||
grid-gap: 24px;
|
||||
white-space: nowrap;
|
||||
margin-top: 3px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
.gh-offer-type .gh-radio {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.gh-offer-type .gh-radio-content {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.gh-offer-type .gh-radio-label {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.gh-offer-modal-content textarea {
|
||||
|
||||
.gh-offer-form textarea {
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
.gh-offer-form .form-group {
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
/* Offers – Portal preview */
|
||||
.gh-offer-portal-preview {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gh-offer-portal-preview-mock {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--midgrey);
|
||||
border-radius: 5px;
|
||||
height: 640px;
|
||||
width: 420px;
|
||||
background: #fff;
|
||||
box-shadow: var(--box-shadow-preview-box);
|
||||
}
|
@ -1435,49 +1435,12 @@ p.theme-validation-details {
|
||||
}
|
||||
|
||||
/* Membership */
|
||||
.gh-setting-members-header {
|
||||
position: relative;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.gh-setting-members-canvas::before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: "";
|
||||
top: -450px;
|
||||
right: -250px;
|
||||
width: 970px;
|
||||
height: 970px;
|
||||
border-radius: 50%;
|
||||
z-index: 0;
|
||||
background: var(--main-color-content-greybg);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: 1140px) {
|
||||
.gh-setting-members-canvas::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gh-setting-members-basics {
|
||||
display: grid;
|
||||
grid-template-columns: auto 460px;
|
||||
grid-gap: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: 1320px) {
|
||||
.gh-setting-members-basics {
|
||||
grid-gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1140px) {
|
||||
.gh-setting-members-basics {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.gh-setting-members-basicsform {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -1630,14 +1593,7 @@ p.theme-validation-details {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
box-shadow:
|
||||
0 2.8px 2.2px rgba(0, 0, 0, 0.02),
|
||||
0 6.7px 5.3px rgba(0, 0, 0, 0.028),
|
||||
0 12.5px 10px rgba(0, 0, 0, 0.035),
|
||||
0 22.3px 17.9px rgba(0, 0, 0, 0.042),
|
||||
0 41.8px 33.4px rgba(0, 0, 0, 0.05),
|
||||
0 100px 80px rgba(0, 0, 0, 0.07)
|
||||
;
|
||||
box-shadow: var(--box-shadow-preview-box);
|
||||
width: 420px;
|
||||
height: 562px;
|
||||
margin-bottom: 32px;
|
||||
|
@ -125,6 +125,10 @@ input[type=number] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-group:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.form-group {
|
||||
max-width: 100%;
|
||||
|
@ -171,6 +171,15 @@
|
||||
0 76px 80px -5px rgba(0, 0, 0, 0.04)
|
||||
;
|
||||
|
||||
--box-shadow-preview-box:
|
||||
0 2.8px 2.2px rgba(0, 0, 0, 0.02),
|
||||
0 6.7px 5.3px rgba(0, 0, 0, 0.028),
|
||||
0 12.5px 10px rgba(0, 0, 0, 0.035),
|
||||
0 22.3px 17.9px rgba(0, 0, 0, 0.042),
|
||||
0 41.8px 33.4px rgba(0, 0, 0, 0.05),
|
||||
0 100px 80px rgba(0, 0, 0, 0.07)
|
||||
;
|
||||
|
||||
/* Inputs */
|
||||
--input-bg-color: var(--white);
|
||||
--input-border-color: var(--whitegrey-d2);
|
||||
|
@ -11,4 +11,4 @@
|
||||
|
||||
.shadow-1 { box-shadow: var(--shadow-1); }
|
||||
.shadow-2 { box-shadow: var(--shadow-2); }
|
||||
.shadow-3 { box-shadow: var(--shadow-3); }
|
||||
.shadow-3 { box-shadow: var(--shadow-3); }
|
@ -1,4 +1,4 @@
|
||||
<section class="gh-canvas">
|
||||
<section class="gh-canvas circle-bg">
|
||||
<GhCanvasHeader class="gh-canvas-header break tablet members-header">
|
||||
<h2 class="gh-canvas-title" data-test-screen-title>
|
||||
<LinkTo @route="offers" data-test-link="offers-back">Offers</LinkTo>
|
||||
@ -11,6 +11,133 @@
|
||||
</GhCanvasHeader>
|
||||
|
||||
<section class="view-container">
|
||||
Offer...
|
||||
<div class="gh-main-layout content-preview">
|
||||
<form>
|
||||
<div class="gh-main-section gh-offer-form">
|
||||
<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">
|
||||
<label for="name" class="fw6">Name</label>
|
||||
<GhTextInput
|
||||
@name="name"
|
||||
@placeholder="Black Friday"
|
||||
@id="name"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="name" />
|
||||
<p>Will be shown to members on the Stripe Checkout page</p>
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
|
||||
<h4 class="gh-main-section-header small bn">Discount info</h4>
|
||||
<div class="gh-main-section-content grey">
|
||||
<GhFormGroup @errors={{this.errors}} @property="product-cadence">
|
||||
<label for="product-cadence" class="fw6">Product – cadence</label>
|
||||
<span class="gh-select">
|
||||
<OneWaySelect @value={{this.selectedVisibility}}
|
||||
@options={{this.cadences}}
|
||||
@optionValuePath="name"
|
||||
@optionLabelPath="label"
|
||||
@optionTargetPath="name"
|
||||
@update={{this.updateVisibility}}
|
||||
/>
|
||||
{{svg-jar "arrow-down-small"}}
|
||||
</span>
|
||||
<GhErrorMessage @errors={{this.errors}} @property="product-cadence" />
|
||||
</GhFormGroup>
|
||||
{{#if (eq this.selectedDiscountType "percentage")}}
|
||||
<GhFormGroup @errors={{this.errors}} @property="amount">
|
||||
<label for="amount" class="fw6">Percentage off</label>
|
||||
<GhTextInput
|
||||
@type="number"
|
||||
@name="amount"
|
||||
@placeholder=""
|
||||
@id="amount"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="amount" />
|
||||
</GhFormGroup>
|
||||
{{else}}
|
||||
<GhFormGroup @errors={{this.errors}} @property="amount">
|
||||
<label for="amount" class="fw6">Amount off</label>
|
||||
<GhTextInput
|
||||
@name="amount"
|
||||
@type="number"
|
||||
@placeholder=""
|
||||
@id="amount"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="amount" />
|
||||
</GhFormGroup>
|
||||
{{/if}}
|
||||
<div class="gh-offer-type">
|
||||
<div class="gh-radio {{if (eq this.selectedDiscountType "percentage") "active"}}" {{on "click" (fn this.setDiscountType "percentage")}}>
|
||||
<div class="gh-radio-button"></div>
|
||||
<div class="gh-radio-content">
|
||||
<div class="gh-radio-label">Percentage discount</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio {{if (eq this.selectedDiscountType "fixed") "active"}}" {{on "click" (fn this.setDiscountType "fixed")}}>
|
||||
<div class="gh-radio-button"></div>
|
||||
<div class="gh-radio-content">
|
||||
<div class="gh-radio-label">Fixed amount discount</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<label for="display-title" class="fw6">Display title</label>
|
||||
<GhTextInput
|
||||
@name="display-title"
|
||||
@placeholder="Black Friday Special"
|
||||
@id="display-title"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="display-title" />
|
||||
</GhFormGroup>
|
||||
<GhFormGroup @errors={{this.errors}} @property="code">
|
||||
<label for="code" class="fw6">Offer code</label>
|
||||
<GhTextInput
|
||||
@name="code"
|
||||
@placeholder="black-friday"
|
||||
@id="code"
|
||||
@class="gh-input" />
|
||||
<GhErrorMessage @errors={{this.errors}} @property="code" />
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
<GhFormGroup @errors={{this.errors}} @property="description">
|
||||
<label for="description" class="fw6">Description</label>
|
||||
<GhTextarea
|
||||
@id="description"
|
||||
@name="description"
|
||||
@stopEnterKeyDownPropagation="true"
|
||||
/>
|
||||
<GhErrorMessage @errors={{this.errors}} @property="description" />
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="gh-offer-portal-preview">
|
||||
<div>
|
||||
<h4 class="gh-main-section-header small bn">Preview</h4>
|
||||
<div class="gh-offer-portal-preview-mock">Portal preview</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="gh-main-section">
|
||||
<div class="gh-main-section-block">
|
||||
<button
|
||||
type="button"
|
||||
class="gh-btn gh-btn-red gh-btn-icon"
|
||||
>
|
||||
<span>Delete offer</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
@ -1,4 +1,4 @@
|
||||
<section class="gh-canvas gh-setting-members-canvas" {{did-insert this.setup}}>
|
||||
<section class="gh-canvas circle-bg" {{did-insert this.setup}}>
|
||||
<GhCanvasHeader class="gh-canvas-header gh-setting-members-header">
|
||||
<h2 class="gh-canvas-title" data-test-screen-title>
|
||||
<LinkTo @route="settings">Settings</LinkTo>
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<section class="view-container settings-debug">
|
||||
|
||||
<div class="gh-setting-members-basics">
|
||||
<div class="gh-main-layout content-preview">
|
||||
<div class="gh-setting-members-basicsform">
|
||||
<p class="intro">Fund your work with subscription revenue. Connect your Stripe account and offer premium content to your audience. Our creators are already making over $5 million per year, while <strong>Ghost takes 0% payment fees</strong>.</p>
|
||||
<hr>
|
||||
|
Loading…
Reference in New Issue
Block a user