CSS restructure for main sections

This commit is contained in:
Peter Zimon 2021-02-10 18:48:27 +01:00
parent 7b88038d05
commit 7c2bae6f29
11 changed files with 514 additions and 495 deletions

View File

@ -1,72 +1,74 @@
<div class="gh-member-settings" ...attributes>
<section class="gh-main-section no-heading columns-2 gh-member-detail-overview">
<section class="gh-main-section no-heading gh-member-detail-overview">
<div class="gh-main-section-block">
<div class="flex items-center">
{{#if (or this.member.name this.member.email)}}
<GhMemberAvatar
@member={{this.member}}
@sizeClass={{if this.member.name 'f-subheadline fw4 lh-zero tracked-1' 'f-headline fw4 lh-zero tracked-1'}}
@containerClass="w20 h20 mr4 gh-member-detail-avatar"
/>
{{else}}
<div class="flex items-center justify-center br-100 w18 h18 mr4 gh-new-member-avatar">
<span class="gh-member-avatar-label f-subheadline fw4 lh-zero tracked-1">N</span>
</div>
{{/if}}
<div>
<h3>
{{or this.member.name this.member.email}}
</h3>
<p>
{{#if (and this.member.name this.member.email)}}
<a href="mailto:{{this.member.email}}">{{this.member.email}}</a>
{{/if}}
</p>
{{#unless this.member.isNew}}
<p class="{{if this.member.name "nudge-bottom--2"}}">
{{#if this.member.geolocation}}
{{#if (and (eq this.member.geolocation.country_code "US") @member.geolocation.region)}}
{{this.member.geolocation.region}}, US
{{else}}
{{or this.member.geolocation.country "Unknown location"}}
<div class="gh-main-section-content columns-2">
<div class="flex items-center">
{{#if (or this.member.name this.member.email)}}
<GhMemberAvatar
@member={{this.member}}
@sizeClass={{if this.member.name 'f-subheadline fw4 lh-zero tracked-1' 'f-headline fw4 lh-zero tracked-1'}}
@containerClass="w20 h20 mr4 gh-member-detail-avatar"
/>
{{else}}
<div class="flex items-center justify-center br-100 w18 h18 mr4 gh-new-member-avatar">
<span class="gh-member-avatar-label f-subheadline fw4 lh-zero tracked-1">N</span>
</div>
{{/if}}
<div>
<h3>
{{or this.member.name this.member.email}}
</h3>
<p>
{{#if (and this.member.name this.member.email)}}
<a href="mailto:{{this.member.email}}">{{this.member.email}}</a>
{{/if}}
{{else}}
Unknown location
{{/if}}
Created on {{moment-format @member.createdAtUTC "D MMM YYYY"}}
</p>
{{/unless}}
</p>
{{#unless this.member.isNew}}
<p class="{{if this.member.name "nudge-bottom--2"}}">
{{#if this.member.geolocation}}
{{#if (and (eq this.member.geolocation.country_code "US") @member.geolocation.region)}}
{{this.member.geolocation.region}}, US
{{else}}
{{or this.member.geolocation.country "Unknown location"}}
{{/if}}
{{else}}
Unknown location
{{/if}}
Created on {{moment-format @member.createdAtUTC "D MMM YYYY"}}
</p>
{{/unless}}
</div>
</div>
</div>
</div>
<div class="gh-main-section-block">
<div class="flex">
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Emails received</div>
<div class="gh-data-summary">{{@member.emailCount}}</div>
</div>
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Emails opened</div>
<div class="gh-data-summary">{{@member.emailOpenedCount}}</div>
</div>
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Avg. open rate</div>
<div class="gh-data-summary">
{{#if (is-empty @member.emailOpenRate)}}
<span data-tooltip="Insufficient data available"></span>
{{else}}
{{@member.emailOpenRate}}%
{{/if}}
<div class="flex">
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Emails received</div>
<div class="gh-data-summary">{{@member.emailCount}}</div>
</div>
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Emails opened</div>
<div class="gh-data-summary">{{@member.emailOpenedCount}}</div>
</div>
<div class="flex-auto flex flex-column justify-center items-start">
<div class="gh-heading-xs">Avg. open rate</div>
<div class="gh-data-summary">
{{#if (is-empty @member.emailOpenRate)}}
<span data-tooltip="Insufficient data available"></span>
{{else}}
{{@member.emailOpenRate}}%
{{/if}}
</div>
</div>
</div>
</div>
</div>
</section>
<section class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Basic data</h4>
<div class="gh-main-section columns-2">
<div class="gh-main-section-block">
<section class="gh-main-section">
<h4 class="gh-main-section-header small bn">Basic data</h4>
<div class="gh-main-section-block">
<div class="gh-main-section-content grey padding-top-s columns-2">
<div>
<GhFormGroup @errors={{this.member.errors}} @hasValidated={{this.member.hasValidated}} @property="name" @classNames="max-width">
<label for="member-name">Name</label>
@ -82,233 +84,230 @@
@focus-out={{action "setProperty" "email" this.scratchMember.email}} data-test-input="member-email"/>
<GhErrorMessage @errors={{this.member.errors}} @property="email" />
</GhFormGroup>
<GhFormGroup @classNames="gh-members-subscribed-checkbox mb0">
<div class="flex justify-between items-center">
<div>
<h4 class="gh-setting-title m">Subscribed to newsletter</h4>
<p class="gh-setting-desc">If disabled, member will <em>not</em> receive newsletter emails</p>
</div>
<div class="for-switch">
<label class="switch" for="subscribed-checkbox">
<Input @checked={{this.member.subscribed}} @type="checkbox" @id="subscribed-checkbox"
@name="subscribed" data-test-checkbox="member-subscribed" />
<span class="input-toggle-component"></span>
</label>
</div>
</div>
</GhFormGroup>
</div>
<GhFormGroup @classNames="gh-members-subscribed-checkbox mb0">
<div class="flex justify-between items-center">
<div>
<h4 class="gh-setting-title m">Subscribed to newsletter</h4>
<p class="gh-setting-desc">If disabled, member will <em>not</em> receive newsletter emails</p>
</div>
<div class="for-switch">
<label class="switch" for="subscribed-checkbox">
<Input @checked={{this.member.subscribed}} @type="checkbox" @id="subscribed-checkbox"
@name="subscribed" data-test-checkbox="member-subscribed" />
<span class="input-toggle-component"></span>
</label>
</div>
</div>
</GhFormGroup>
</div>
<div class="gh-main-section-block">
<div class="flex-auto flex flex-column items-stretch">
<div>
<GhFormGroup @classNames="gh-member-labels">
<label for="label-input">Labels</label>
<GhMemberLabelInput @onChange={{action "setLabels"}} @labels={{this.member.labels}} @triggerId="label-input" data-test-input="" />
</GhFormGroup>
<GhFormGroup @errors={{this.member.errors}} @hasValidated={{this.member.hasValidated}} @property="note" @classNames="mb0 gh-member-note">
<label for="member-note">Note <span class="midgrey-l2 fw4">(not visible to member)</span></label>
<GhTextarea @id="member-note" @name="note" @class="gh-member-details-textarea" @tabindex="3"
@value={{this.scratchMember.note}} @focus-out={{action "setProperty" "note" this.scratchMember.note}} data-test-input="member-note" />
<GhErrorMessage @errors={{this.member.errors}} @property="note" />
<p> Maximum: <b>500</b> characters. Youve used
{{gh-count-down-characters this.scratchMember.note 500}}</p>
</GhFormGroup>
</div>
<GhFormGroup @classNames="gh-member-labels">
<label for="label-input">Labels</label>
<GhMemberLabelInput @onChange={{action "setLabels"}} @labels={{this.member.labels}} @triggerId="label-input" data-test-input="" />
</GhFormGroup>
<GhFormGroup @errors={{this.member.errors}} @hasValidated={{this.member.hasValidated}} @property="note" @classNames="mb0 gh-member-note">
<label for="member-note">Note <span class="midgrey-l2 fw4">(not visible to member)</span></label>
<GhTextarea @id="member-note" @name="note" @class="gh-member-details-textarea" @tabindex="3"
@value={{this.scratchMember.note}} @focus-out={{action "setProperty" "note" this.scratchMember.note}} data-test-input="member-note" />
<GhErrorMessage @errors={{this.member.errors}} @property="note" />
<p> Maximum: <b>500</b> characters. Youve used
{{gh-count-down-characters this.scratchMember.note 500}}</p>
</GhFormGroup>
</div>
</div>
</div>
</section>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Member activity</h4>
<section class="gh-main-section {{if this.canShowStripeInfo "columns-2"}}">
<div class="gh-main-section-block">
<section class="gh-main-section columns-2">
<div class="gh-main-section-block">
<h4 class="gh-main-section-header small bn">Member activity</h4>
<div class="gh-main-section-content grey">
<GhMemberActivityFeed @emailRecipients={{this.member.emailRecipients}} />
</div>
{{#if this.canShowStripeInfo}}
<h4 class="gh-main-section-header">Stripe info</h4>
<div class="gh-main-section-block">
<div class="gh-member-stripe">
{{#if this.isLoading}}
<div class="pa20 bg-grouped-table gh-content-box grey mt2">
<div class="flex justify-center flex-auto">
<div class="gh-loading-spinner"> </div>
</div>
</div>
{{#if this.canShowStripeInfo}}
<div class="gh-main-section-block">
<h4 class="gh-main-section-header small bn">Stripe info</h4>
<div class="gh-main-section-content grey">
<div class="gh-member-stripe">
{{#if this.isLoading}}
<div class="pa12 bg-grouped-table gh-content-box grey mt2">
<div class="flex justify-center flex-auto">
<div class="gh-loading-spinner"> </div>
</div>
{{else}}
<div class="bg-grouped-table gh-content-box grey mt2">
{{#if this.subscriptions}}
<div class="gh-member-header-stripeinfo">
<div class="flex items-center justify-between gh-btn-group w-100 ma5 mb0">
<button type="button" class="gh-btn gh-member-btn-stripe-toggle w-100 {{if (eq this.stripeDetailsType "subscription") "gh-btn-group-selected"}}" {{on "click" (fn this.changeStripeDetailsType "subscription")}}><span>Subscription</span></button>
<button type="button" class="gh-btn gh-member-btn-stripe-toggle w-100 {{if (eq this.stripeDetailsType "customer") "gh-btn-group-selected"}}" {{on "click" (fn this.changeStripeDetailsType "customer")}}><span>Customer</span></button>
</div>
</div>
{{else}}
<div class="bg-grouped-table gh-content-box grey mt2">
{{#if this.subscriptions}}
<div class="gh-member-header-stripeinfo">
<div class="flex items-center justify-between gh-btn-group w-100 ma5 mb0">
<button type="button" class="gh-btn gh-member-btn-stripe-toggle w-100 {{if (eq this.stripeDetailsType "subscription") "gh-btn-group-selected"}}" {{on "click" (fn this.changeStripeDetailsType "subscription")}}><span>Subscription</span></button>
<button type="button" class="gh-btn gh-member-btn-stripe-toggle w-100 {{if (eq this.stripeDetailsType "customer") "gh-btn-group-selected"}}" {{on "click" (fn this.changeStripeDetailsType "customer")}}><span>Customer</span></button>
</div>
{{#if (eq this.stripeDetailsType "subscription")}}
{{#if this.hasMultipleSubscriptions}}
<div class="pa2 flex flex-column flex-row-ns items-center justify-center f7 fw5 bg-whitegrey-l2 bb b--whitegrey br4 br--top">
{{svg-jar "info" class="gh-member-info-icon mr2 fill-darkgrey"}} Member has multiple Stripe subscriptions
</div>
{{/if}}
{{#each this.subscriptions as |subscription|}}
<section class="gh-member-stripe-info pa5 pb0 pt4 flex flex-column flex-row-ns items-start justify-between">
<div class="flex items-start w-100">
<div class="flex-auto">
<table class="gh-member-stripe-table">
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Stripe subscription ID</td>
<td class="gh-member-stripe-data gh-member-stripe-id">
<a href="https://dashboard.stripe.com/subscriptions/{{subscription.id}}" target="_blank" rel="noopener"
data-tooltip="View on Stripe">
{{subscription.id}}
</a>
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Plan</td>
<td class="gh-member-stripe-data">
{{subscription.plan.nickname}}
<span class="midgrey-d1">({{subscription.amount}}
<span class="ttu">{{subscription.plan.currency}}</span>/{{subscription.plan.interval}})
</span>
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Status</td>
<td class="gh-member-stripe-data">
{{#if (and subscription.cancelAtPeriodEnd (not-eq subscription.status 'canceled'))}}
<span class="gh-member-cancels-on-label">Cancels on {{subscription.validUntil}}</span>
{{else}}
<span class="gh-member-stripe-status">{{subscription.statusLabel}}</span>
{{/if}}
</td>
</tr>
{{#if subscription.cancellationReason}}
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Cancellation reason</td>
<td class="gh-member-stripe-data">
<span class="gh-member-stripe-cancellation-reason">{{subscription.cancellationReason}}</span>
</td>
</tr>
{{/if}}
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Next renewal date</td>
<td class="gh-member-stripe-data">
{{#if subscription.cancelAtPeriodEnd}}
No further renewal
{{else}}
{{subscription.validUntil}}
{{/if}}
</td>
</tr>
</table>
{{#if (eq subscription.status "active")}}
{{#if subscription.cancelAtPeriodEnd}}
<GhTaskButton
@buttonText="Continue subscription"
@successText=""
@task={{this.continueSubscription}}
@taskArgs={{subscription.id}}
@class="mt1 mb6 gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="continue-subscription"
/>
{{else}}
<GhTaskButton
@buttonText="Cancel subscription"
@successText=""
@task={{this.cancelSubscription}}
@taskArgs={{subscription.id}}
@class="mt1 mb6 gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="cancel-subscription"
/>
{{/if}}
{{/if}}
</div>
</div>
</section>
{{/each}}
{{else}}
</div>
{{#if (eq this.stripeDetailsType "subscription")}}
{{#if this.hasMultipleSubscriptions}}
<div class="pa2 flex flex-column flex-row-ns items-center justify-center f7 fw5 bg-whitegrey-l2 bb b--whitegrey br4 br--top">
{{svg-jar "info" class="gh-member-info-icon mr2 fill-darkgrey"}} Member has multiple Stripe subscriptions
</div>
{{/if}}
{{#each this.subscriptions as |subscription|}}
<section class="gh-member-stripe-info pa5 pb0 pt4 flex flex-column flex-row-ns items-start justify-between">
<div class="flex items-start w-100">
<div class="flex-auto">
<table class="gh-member-stripe-table">
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Stripe customer ID</td>
<td class="gh-member-stripe-label">Stripe subscription ID</td>
<td class="gh-member-stripe-data gh-member-stripe-id">
<a href="https://dashboard.stripe.com/customers/{{customer.id}}" target="_blank" rel="noopener" data-tooltip="View on Stripe">
{{customer.id}}
<a href="https://dashboard.stripe.com/subscriptions/{{subscription.id}}" target="_blank" rel="noopener"
data-tooltip="View on Stripe">
{{subscription.id}}
</a>
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Name</td>
<td class="gh-member-stripe-label">Plan</td>
<td class="gh-member-stripe-data">
{{#if customer.name}}
{{customer.name}}
{{else}}
<span class="midgrey-d1">No name</span>
{{/if}}
{{subscription.plan.nickname}}
<span class="midgrey-d1">({{subscription.amount}}
<span class="ttu">{{subscription.plan.currency}}</span>/{{subscription.plan.interval}})
</span>
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Email</td>
<td class="gh-member-stripe-data gh-member-stripe-email">
{{#if customer.email}}
{{customer.email}}
<td class="gh-member-stripe-label">Status</td>
<td class="gh-member-stripe-data">
{{#if (and subscription.cancelAtPeriodEnd (not-eq subscription.status 'canceled'))}}
<span class="gh-member-cancels-on-label">Cancels on {{subscription.validUntil}}</span>
{{else}}
<span class="midgrey-d1">No email</span>
<span class="gh-member-stripe-status">{{subscription.statusLabel}}</span>
{{/if}}
</td>
</tr>
{{#if subscription.cancellationReason}}
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Cancellation reason</td>
<td class="gh-member-stripe-data">
<span class="gh-member-stripe-cancellation-reason">{{subscription.cancellationReason}}</span>
</td>
</tr>
{{/if}}
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Customer since</td>
<td class="gh-member-stripe-label">Next renewal date</td>
<td class="gh-member-stripe-data">
{{#if customer.startDate}}
{{customer.startDate}}
{{#if subscription.cancelAtPeriodEnd}}
No further renewal
{{else}}
<span class="midgrey-d1">No data</span>
{{subscription.validUntil}}
{{/if}}
</td>
</tr>
</table>
{{#if (eq subscription.status "active")}}
{{#if subscription.cancelAtPeriodEnd}}
<GhTaskButton
@buttonText="Continue subscription"
@successText=""
@task={{this.continueSubscription}}
@taskArgs={{subscription.id}}
@class="mt1 mb6 gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="continue-subscription"
/>
{{else}}
<GhTaskButton
@buttonText="Cancel subscription"
@successText=""
@task={{this.cancelSubscription}}
@taskArgs={{subscription.id}}
@class="mt1 mb6 gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="cancel-subscription"
/>
{{/if}}
{{/if}}
</div>
</div>
</section>
{{/if}}
{{/each}}
{{else}}
<div class="pa20">
<p class="ma0 pa0 tc midgrey">Member doesn't have an active Stripe subscription</p>
</div>
{{/if}}
<div class="pa5 pb0 pt4 flex flex-column justify-between bt b--whitegrey">
<GhFormGroup @classNames="gh-members-comped-checkbox">
<div class="flex justify-between items-center gh-members-comped">
<div class="mr5">
<h4 class="gh-setting-title">Complimentary premium plan</h4>
<p class="gh-setting-desc">If enabled, member will be placed onto a free of charge premium subscription</p>
</div>
<div class="for-switch gh-members-comped-switch">
<label class="switch" for="comped-checkbox">
<Input @checked={{this.member.comped}} @type="checkbox" @id="comped-checkbox" @name="comped" />
<span class="input-toggle-component"></span>
</label>
<section class="gh-member-stripe-info pa5 pb0 pt4 flex flex-column flex-row-ns items-start justify-between">
<div class="flex items-start w-100">
<div class="flex-auto">
<table class="gh-member-stripe-table">
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Stripe customer ID</td>
<td class="gh-member-stripe-data gh-member-stripe-id">
<a href="https://dashboard.stripe.com/customers/{{customer.id}}" target="_blank" rel="noopener" data-tooltip="View on Stripe">
{{customer.id}}
</a>
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Name</td>
<td class="gh-member-stripe-data">
{{#if customer.name}}
{{customer.name}}
{{else}}
<span class="midgrey-d1">No name</span>
{{/if}}
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Email</td>
<td class="gh-member-stripe-data gh-member-stripe-email">
{{#if customer.email}}
{{customer.email}}
{{else}}
<span class="midgrey-d1">No email</span>
{{/if}}
</td>
</tr>
<tr class="gh-member-stripe-row">
<td class="gh-member-stripe-label">Customer since</td>
<td class="gh-member-stripe-data">
{{#if customer.startDate}}
{{customer.startDate}}
{{else}}
<span class="midgrey-d1">No data</span>
{{/if}}
</td>
</tr>
</table>
</div>
</div>
</GhFormGroup>
</section>
{{/if}}
{{else}}
<div class="pa12">
<p class="ma0 pa0 tc midgrey">Member doesn't have an active Stripe subscription</p>
</div>
{{/if}}
<div class="pa5 pb0 pt4 flex flex-column justify-between bt b--whitegrey">
<GhFormGroup @classNames="gh-members-comped-checkbox">
<div class="flex justify-between items-center gh-members-comped">
<div class="mr5">
<h4 class="gh-setting-title">Complimentary premium plan</h4>
<p class="gh-setting-desc">If enabled, member will be placed onto a free of charge premium subscription</p>
</div>
<div class="for-switch gh-members-comped-switch">
<label class="switch" for="comped-checkbox">
<Input @checked={{this.member.comped}} @type="checkbox" @id="comped-checkbox" @name="comped" />
<span class="input-toggle-component"></span>
</label>
</div>
</div>
</GhFormGroup>
</div>
{{/if}}
</div>
</div>
{{/if}}
</div>
{{/if}}
</section>
</div>
</div>
</div>
{{/if}}
</section>
</div>

View File

@ -1,72 +1,72 @@
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Basic settings</h4>
<section class="gh-main-section columns-2">
<div class="gh-main-section-block">
<div class="gh-tag-settings-multiprop">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="name" class="mr2 flex-auto">
<label for="tag-name">Name</label>
<div class="gh-main-section">
<h4 class="gh-main-section-header small bn">Basic settings</h4>
<section class="gh-main-section-block">
<div class="gh-main-section-content grey columns-2">
<div>
<div class="gh-tag-settings-multiprop">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="name" class="mr2 flex-auto">
<label for="tag-name">Name</label>
<GhTextInput
@id="tag-name"
@name="name"
@value={{this.scratchTag.name}}
@tabindex="1"
@focus-out={{action "setProperty" "name" this.scratchTag.name}}
/>
<span class="error">
<GhErrorMessage @errors={{this.tag.errors}} @property="name" />
<GhErrorMessage @errors={{this.tag.errors}} @property="accentColor" data-test-error="accentColor" />
</span>
<p class="description">
Start with # to create internal tags
<a href="https://ghost.org/help/organising-content/#private-tags" target="_blank" rel="noreferrer">Learn more</a>
</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="accentColor" class="gh-tag-settings-colorcontainer">
<label for="accent-color">Color</label>
<div class="input-color">
<GhTextInput
@name="accent-color"
@placeholder="abcdef"
@autocorrect="off"
@maxlength="6"
@focus-out={{action "validateAccentColor"}}
@value={{accentColor}}
data-test-input="accentColor"
/>
<div class="color-box" style={{this.accentColorBackgroundStyle}}></div>
</div>
</GhFormGroup>
</div>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="slug">
<label for="tag-slug">Slug</label>
<GhTextInput
@id="tag-name"
@name="name"
@value={{this.scratchTag.name}}
@tabindex="1"
@focus-out={{action "setProperty" "name" this.scratchTag.name}}
@value={{this.scratchTag.slug}}
@id="tag-slug"
@name="slug"
@tabindex="2"
@focus-out={{action "setProperty" "slug" this.scratchTag.slug}}
/>
<span class="error">
<GhErrorMessage @errors={{this.tag.errors}} @property="name" />
<GhErrorMessage @errors={{this.tag.errors}} @property="accentColor" data-test-error="accentColor" />
</span>
<p class="description">
Start with # to create internal tags
<a href="https://ghost.org/help/organising-content/#private-tags" target="_blank" rel="noreferrer">Learn more</a>
</p>
<GhUrlPreview @prefix="tag" @slug={{this.scratchTag.slug}} @tagName="p" @classNames="description" />
<GhErrorMessage @errors={{this.activeTag.errors}} @property="slug" />
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="accentColor" class="gh-tag-settings-colorcontainer">
<label for="accent-color">Color</label>
<div class="input-color">
<GhTextInput
@name="accent-color"
@placeholder="abcdef"
@autocorrect="off"
@maxlength="6"
@focus-out={{action "validateAccentColor"}}
@value={{accentColor}}
data-test-input="accentColor"
/>
<div class="color-box" style={{this.accentColorBackgroundStyle}}></div>
</div>
<GhFormGroup @class="no-margin" @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="description">
<label for="tag-description">Description</label>
<GhTextarea
@id="tag-description"
@name="description"
@class="gh-tag-details-textarea"
@tabindex="3"
@value={{this.scratchTag.description}}
@focus-out={{action "setProperty" "description" this.scratchTag.description}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="description" />
<p>Maximum: <b>500</b> characters. Youve used {{gh-count-down-characters this.scratchTag.description 500}}</p>
</GhFormGroup>
</div>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="slug">
<label for="tag-slug">Slug</label>
<GhTextInput
@value={{this.scratchTag.slug}}
@id="tag-slug"
@name="slug"
@tabindex="2"
@focus-out={{action "setProperty" "slug" this.scratchTag.slug}}
/>
<GhUrlPreview @prefix="tag" @slug={{this.scratchTag.slug}} @tagName="p" @classNames="description" />
<GhErrorMessage @errors={{this.activeTag.errors}} @property="slug" />
</GhFormGroup>
<GhFormGroup @class="no-margin" @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="description">
<label for="tag-description">Description</label>
<GhTextarea
@id="tag-description"
@name="description"
@class="gh-tag-details-textarea"
@tabindex="3"
@value={{this.scratchTag.description}}
@focus-out={{action "setProperty" "description" this.scratchTag.description}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="description" />
<p>Maximum: <b>500</b> characters. Youve used {{gh-count-down-characters this.scratchTag.description 500}}</p>
</GhFormGroup>
</div>
<div class="gh-main-section-block">
<GhFormGroup @class="no-margin" @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="featureImage">
<label for="tag-image">Tag image</label>
<GhImageUploaderWithPreview

View File

@ -464,11 +464,11 @@
display: flex;
position: relative;
align-items: center;
height: 118px;
width: 118px;
height: 117px;
width: 117px;
margin: 0;
border-radius: 3px;
border: 1px solid var(--lightgrey);
border: 1px solid var(--whitegrey);
background: var(--white);
padding: 24px;
}

View File

@ -954,11 +954,17 @@
}
/* Main sections */
/*
.gh-main-section [columns-2|columns-3]
.gh-main-section-block [columns-2|columns-3]
.gh-main-section-header [small]
.gh-main-section-content [grey]
*/
.gh-main-section {
display: grid;
grid-template-columns: 1fr;
margin-bottom: 3vw;
grid-column-gap: 40px;
grid-column-gap: 0;
}
.gh-main-section.no-heading,
@ -1000,7 +1006,9 @@
font-weight: 400;
}
.gh-main-section-description.bn { border-bottom: none; }
.gh-main-section-description.bn {
border-bottom: none;
}
.gh-main-section-header + .gh-main-section-description {
margin-top: -6px;
@ -1014,6 +1022,7 @@
.gh-main-section.columns-2 {
grid-template-columns: 1fr 1fr;
grid-column-gap: 32px;
}
.gh-main-section.columns-2 .gh-main-section-header {
@ -1022,6 +1031,7 @@
.gh-main-section.columns-3 {
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 32px;
}
.gh-main-section.columns-3 .gh-main-section-header {
@ -1029,7 +1039,11 @@
}
.gh-main-section-block {
padding: 16px 0;
padding: 0;
}
.gh-main-section-block:not(:last-of-type) {
margin-bottom: 32px;
}
.gh-main-section-block.bt { border-top: 1px solid var(--whitegrey); }
@ -1039,30 +1053,37 @@
.gh-main-section-block.p0 { padding: 0; }
.gh-main-section-modifier.grey .gh-main-section {
.gh-main-section-content {
display: grid;
grid-template-columns: 1fr;
margin-bottom: 3vw;
}
.gh-main-section-content.grey {
background: var(--main-color-content-greybg);
padding: 24px;
border-radius: 3px;
grid-column-gap: 0px;
}
.gh-main-section-modifier.grey .gh-main-section-block.bt { border-top: 1px solid color-mod(var(--whitegrey-d1) l(+1%)); }
.gh-main-section-modifier.grey .gh-main-section-block.br { border-right: 1px solid color-mod(var(--whitegrey-d1) l(+1%)); }
.gh-main-section-modifier.grey .gh-main-section-block.bb { border-bottom: 1px solid color-mod(var(--whitegrey-d1) l(+1%)); }
.gh-main-section-modifier.grey .gh-main-section-block.bl { border-left: 1px solid color-mod(var(--whitegrey-d1) l(+1%)); }
.gh-main-section-modifier.grey .gh-main-section-block.gh-setting {
padding: 18px 20px 17px;
.gh-main-section-content.columns-2 {
grid-template-columns: 1fr 1fr;
grid-column-gap: 80px;
}
.gh-main-section-modifier.grey .gh-main-section-header {
border: none;
.gh-main-section-content.columns-3 {
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 24px;
}
.gh-main-section-modifier.grey .gh-main-section-block {
padding: 16px 24px 24px;
.gh-main-section-content.grey {
background: var(--main-color-content-greybg);
}
/* Expandables */
.gh-main-section-content.padding-top-s {
padding-top: 16px;
}
/* Expandable options */
.gh-expandable {
background: var(--main-color-content-greybg);
border-radius: 3px;
@ -1109,14 +1130,12 @@
padding: 0 24px;
}
/* Inputs and buttons for grey background */
.gh-expandable-content .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red),
.gh-main-section-modifier.grey .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red) {
/* Grey background modifiers */
.gh-expandable-content .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red) {
background: var(--whitegrey-d2);
}
.gh-expandable-content .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red):hover,
.gh-main-section-modifier.grey .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red):hover {
.gh-expandable-content .gh-btn:not(.gh-btn-white):not(.gh-btn-green):not(.gh-btn-blue):not(.gh-btn-red):hover {
background: color-mod(var(--whitegrey-d2) l(-4%));
}
@ -1130,10 +1149,7 @@
.gh-expandable-content input:not(:focus),
.gh-expandable-content .gh-input:not(:focus),
.gh-expandable-content .ember-power-select-multiple-trigger,
.gh-main-section-modifier.grey input:not(:focus),
.gh-main-section-modifier.grey .gh-input:not(:focus),
.gh-main-section-modifier.grey .ember-power-select-multiple-trigger {
.gh-expandable-content .ember-power-select-multiple-trigger {
border-color: var(--whitegrey-d1);
}
@ -1142,7 +1158,6 @@
padding: 0;
}
/* Canvas */
.gh-canvas-title {
display: flex;

View File

@ -662,7 +662,6 @@ textarea.gh-member-details-textarea {
.gh-member-internal-info,
.gh-member-stripe {
float: right;
width: 29%;
}
@media (max-width: 1160px) {

View File

@ -11,10 +11,10 @@
</section>
</GhCanvasHeader>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Configuration</h4>
<section class="gh-main-section">
<div class="gh-main-section-block">
<div class="gh-main-section">
<h4 class="gh-main-section-header small bn">Configuration</h4>
<section class="gh-main-section-block">
<div class="gh-main-section-content padding-top-s grey">
<div class="flex">
<div class="flex flex-column items-start app-custom-icon-container">
<label class="mb1">Icon</label>

View File

@ -30,52 +30,54 @@
</div>
</section>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">AMP configuration</h4>
<section class="gh-main-section columns-2">
<div class="gh-main-section-block">
<div class="gh-setting">
<div class="gh-setting-content">
<div class="gh-setting-title">Enable AMP</div>
<div class="gh-setting-desc">Enable <a href="https://ampproject.org" target="_blank">Google Accelerated Mobile Pages</a> for your posts</div>
</div>
<div class="gh-setting-action">
<div class="for-checkbox">
<label for="amp" class="checkbox">
<input
type="checkbox"
checked={{this.settings.amp}}
id="amp"
name="amp"
onclick={{action "update" value="target.checked"}}
data-test-amp-checkbox
>
<span class="input-toggle-component"></span>
</label>
<div class="gh-main-section">
<h4 class="gh-main-section-header small bn">AMP configuration</h4>
<section class="gh-main-section-block">
<div class="gh-main-section-content grey padding-top-s columns-2">
<div>
<div class="gh-setting">
<div class="gh-setting-content">
<div class="gh-setting-title">Enable AMP</div>
<div class="gh-setting-desc">Enable <a href="https://ampproject.org" target="_blank">Google Accelerated Mobile Pages</a> for your posts</div>
</div>
<div class="gh-setting-action">
<div class="for-checkbox">
<label for="amp" class="checkbox">
<input
type="checkbox"
checked={{this.settings.amp}}
id="amp"
name="amp"
onclick={{action "update" value="target.checked"}}
data-test-amp-checkbox
>
<span class="input-toggle-component"></span>
</label>
</div>
</div>
</div>
</div>
{{#liquid-if this.settings.amp class=""}}
<div class="gh-setting-last gh-setting-amp-liquid">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Google Analytics Tracking ID</div>
<div class="gh-setting-desc">Tracks AMP traffic in Google Analytics, find your ID <a href="https://ghost.org/help/how-to-find-your-google-analytics-tracking-id/">here</a></div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="ampGtagId">
<GhTextInput
@placeholder="UA-XXXXXXX-X"
@name="amp_gtag_id"
@value={{this.settings.ampGtagId}}
@keyEvents={{hash
Enter=(action "save")
}}
/>
<GhErrorMessage @errors={{this.settings.errors}} @property="ampGtagId"/>
</GhFormGroup>
{{#liquid-if this.settings.amp class=""}}
<div class="gh-setting-last gh-setting-amp-liquid">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Google Analytics Tracking ID</div>
<div class="gh-setting-desc">Tracks AMP traffic in Google Analytics, find your ID <a href="https://ghost.org/help/how-to-find-your-google-analytics-tracking-id/">here</a></div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="ampGtagId">
<GhTextInput
@placeholder="UA-XXXXXXX-X"
@name="amp_gtag_id"
@value={{this.settings.ampGtagId}}
@keyEvents={{hash
Enter=(action "save")
}}
/>
<GhErrorMessage @errors={{this.settings.errors}} @property="ampGtagId"/>
</GhFormGroup>
</div>
</div>
</div>
{{/liquid-if}}
</div>
{{/liquid-if}}
</div>
</section>
</div>

View File

@ -30,52 +30,54 @@
</div>
</section>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">FirstPromoter configuration</h4>
<section class="gh-main-section columns-2">
<div class="gh-main-section-block">
<div class="gh-setting">
<div class="gh-setting-content">
<div class="gh-setting-title">Enable FirstPromoter</div>
<div class="gh-setting-desc">Enable <a href="https://firstpromoter.com/?fpr=ghost&fp_sid=admin" target="_blank">FirstPromoter</a> for tracking referrals</div>
</div>
<div class="gh-setting-action">
<div class="for-checkbox">
<label for="firstpromoter" class="checkbox">
<input
type="checkbox"
checked={{this.settings.firstpromoter}}
id="firstpromoter"
name="firstpromoter"
onclick={{action "update" value="target.checked"}}
data-test-firstpromoter-checkbox
>
<span class="input-toggle-component"></span>
</label>
<div class="gh-main-section">
<h4 class="gh-main-section-header small bn">FirstPromoter configuration</h4>
<section class="gh-main-section-block">
<div class="gh-main-section-content grey padding-top-s columns-2">
<div>
<div class="gh-setting">
<div class="gh-setting-content">
<div class="gh-setting-title">Enable FirstPromoter</div>
<div class="gh-setting-desc">Enable <a href="https://firstpromoter.com/?fpr=ghost&fp_sid=admin" target="_blank">FirstPromoter</a> for tracking referrals</div>
</div>
<div class="gh-setting-action">
<div class="for-checkbox">
<label for="firstpromoter" class="checkbox">
<input
type="checkbox"
checked={{this.settings.firstpromoter}}
id="firstpromoter"
name="firstpromoter"
onclick={{action "update" value="target.checked"}}
data-test-firstpromoter-checkbox
>
<span class="input-toggle-component"></span>
</label>
</div>
</div>
</div>
</div>
{{#liquid-if this.settings.firstpromoter class=""}}
<div class="gh-setting gh-setting-firstpromoter-liquid">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">FirstPromoter Account ID</div>
<div class="gh-setting-desc"> Affiliate and referral tracking, find your ID <a href="https://ghost.org/help/firstpromoter-id/">here</a></div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="firstpromoterId">
<GhTextInput
@placeholder="XXXXXXXX"
@name="firstpromoter_id"
@value={{this.settings.firstpromoterId}}
@keyEvents={{hash
Enter=(action "save")
}}
/>
<GhErrorMessage @errors={{this.settings.errors}} @property="firstpromoterId"/>
</GhFormGroup>
{{#liquid-if this.settings.firstpromoter class=""}}
<div class="gh-setting gh-setting-firstpromoter-liquid">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">FirstPromoter Account ID</div>
<div class="gh-setting-desc"> Affiliate and referral tracking, find your ID <a href="https://ghost.org/help/firstpromoter-id/">here</a></div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="firstpromoterId">
<GhTextInput
@placeholder="XXXXXXXX"
@name="firstpromoter_id"
@value={{this.settings.firstpromoterId}}
@keyEvents={{hash
Enter=(action "save")
}}
/>
<GhErrorMessage @errors={{this.settings.errors}} @property="firstpromoterId"/>
</GhFormGroup>
</div>
</div>
</div>
{{/liquid-if}}
</div>
{{/liquid-if}}
</div>
</section>
</div>

View File

@ -30,66 +30,68 @@
</div>
</section>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Slack configuration</h4>
<section class="gh-main-section columns-2">
<form class="app-config-form" id="slack-settings" novalidate="novalidate" {{action "save" on="submit"}}>
<section class="gh-main-section">
<h4 class="gh-main-section-header small bn">Slack configuration</h4>
<div class="gh-main-section-block">
<div class="gh-main-section-content padding-top-s grey">
<form class="app-config-form" id="slack-settings" novalidate="novalidate" {{action "save" on="submit"}}>
<div class="gh-main-section-block">
<div class="gh-setting-first">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Webhook URL</div>
<div class="gh-setting-desc">Automatically send newly published posts to a channel in Slack or any Slack-compatible service like Discord or Mattermost.</div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.slackSettings.errors}} @hasValidated={{this.slackSettings.hasValidated}} @property="url">
<GhTextInput
@placeholder="https://hooks.slack.com/services/..."
@name="slack[url]"
@value={{readonly this.slackSettings.url}}
@input={{action "updateURL" value="target.value"}}
@keyEvents={{hash
Enter=(action "save")
}}
@focus-out={{action "triggerDirtyState"}}
data-test-slack-url-input={{true}}
/>
{{#unless this.slackSettings.errors.url}}
<p>Set up a new incoming webhook <a href="https://my.slack.com/apps/new/A0F7XDUAZ-incoming-webhooks" target="_blank">here</a>, and grab the URL.</p>
{{else}}
<GhErrorMessage @errors={{this.slackSettings.errors}} @property="url" data-test-error="slack-url" />
{{/unless}}
</GhFormGroup>
<div class="gh-main-section-block">
<div class="gh-setting-first">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Webhook URL</div>
<div class="gh-setting-desc">Automatically send newly published posts to a channel in Slack or any Slack-compatible service like Discord or Mattermost.</div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.slackSettings.errors}} @hasValidated={{this.slackSettings.hasValidated}} @property="url">
<GhTextInput
@placeholder="https://hooks.slack.com/services/..."
@name="slack[url]"
@value={{readonly this.slackSettings.url}}
@input={{action "updateURL" value="target.value"}}
@keyEvents={{hash
Enter=(action "save")
}}
@focus-out={{action "triggerDirtyState"}}
data-test-slack-url-input={{true}}
/>
{{#unless this.slackSettings.errors.url}}
<p>Set up a new incoming webhook <a href="https://my.slack.com/apps/new/A0F7XDUAZ-incoming-webhooks" target="_blank">here</a>, and grab the URL.</p>
{{else}}
<GhErrorMessage @errors={{this.slackSettings.errors}} @property="url" data-test-error="slack-url" />
{{/unless}}
</GhFormGroup>
</div>
</div>
</div>
<div class="gh-setting">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Username</div>
<div class="gh-setting-desc">The username to display messages from</div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.slackSettings.errors}} @hasValidated={{this.slackSettings.hasValidated}} @property="username">
<GhTextInput
@placeholder="Ghost"
@name="slack[username]"
@value={{readonly this.slackSettings.username}}
@input={{action "updateUsername" value="target.value"}}
@keyEvents={{hash
Enter=(action "save")
}}
@focus-out={{action "triggerDirtyState"}}
data-test-slack-username-input={{true}}
/>
{{#if this.slackSettings.errors.username}}
<GhErrorMessage @errors={{this.slackSettings.errors}} @property="username" />
{{/if}}
</GhFormGroup>
</div>
<GhTaskButton @buttonText="Send test notification" @task={{this.sendTestNotification}} @successText="Sent" @class="gh-btn gh-btn-icon" @disabled={{this.testNotificationDisabled}} data-test-send-notification-button="true" />
</div>
</div>
</div>
<div class="gh-setting">
<div class="gh-setting-content gh-setting-content--no-action">
<div class="gh-setting-title">Username</div>
<div class="gh-setting-desc">The username to display messages from</div>
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.slackSettings.errors}} @hasValidated={{this.slackSettings.hasValidated}} @property="username">
<GhTextInput
@placeholder="Ghost"
@name="slack[username]"
@value={{readonly this.slackSettings.username}}
@input={{action "updateUsername" value="target.value"}}
@keyEvents={{hash
Enter=(action "save")
}}
@focus-out={{action "triggerDirtyState"}}
data-test-slack-username-input={{true}}
/>
{{#if this.slackSettings.errors.username}}
<GhErrorMessage @errors={{this.slackSettings.errors}} @property="username" />
{{/if}}
</GhFormGroup>
</div>
<GhTaskButton @buttonText="Send test notification" @task={{this.sendTestNotification}} @successText="Sent" @class="gh-btn gh-btn-icon" @disabled={{this.testNotificationDisabled}} data-test-send-notification-button="true" />
</div>
</div>
</div>
</form>
</section>
</div>
</form>
</div>
</div>
</section>
</section>
</section>

View File

@ -30,10 +30,10 @@
</div>
</section>
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Unsplash configuration</h4>
<section class="gh-main-section columns-2">
<div class="gh-main-section-block">
<section class="gh-main-section">
<h4 class="gh-main-section-header small bn">Unsplash configuration</h4>
<div class="gh-main-section-block">
<div class="gh-main-section-content grey">
<div class="gh-setting" id="unsplash-toggle">
<div class="gh-setting-content">
<div class="gh-setting-title">Enable Unsplash</div>
@ -58,7 +58,7 @@
</div>
</div>
</div>
</section>
</div>
</div>
</section>
</section>
</section>

View File

@ -17,10 +17,10 @@
@modifier="action wide" />
{{/if}}
<div class="gh-main-section-modifier grey">
<h4 class="gh-main-section-header small">Primary Navigation</h4>
<section class="gh-main-section">
<div class="gh-main-section-block">
<section class="gh-main-section">
<h4 class="gh-main-section-header small bn">Primary Navigation</h4>
<div class="gh-main-section-block">
<div class="gh-main-section-content padding-top-s grey">
<form id="settings-navigation" class="gh-blognav" novalidate="novalidate">
<SortableObjects @sortableObjectList={{this.settings.navigation}} @useSwap={{false}}>
{{#each this.settings.navigation as |navItem index|}}
@ -45,11 +45,11 @@
data-test-navitem="new" />
</form>
</div>
</section>
</div>
<h4 class="gh-main-section-header small">Secondary Navigation</h4>
<section class="gh-main-section">
<div class="gh-main-section-block">
<h4 class="gh-main-section-header small bn">Secondary Navigation</h4>
<div class="gh-main-section-block">
<div class="gh-main-section-content padding-top-s grey">
<form id="secondary-navigation" class="gh-blognav" novalidate="novalidate">
<SortableObjects @sortableObjectList={{this.settings.secondaryNavigation}} @useSwap={{false}}>
{{#each this.settings.secondaryNavigation as |navItem index|}}
@ -74,8 +74,8 @@
data-test-navitem="new" />
</form>
</div>
</section>
</div>
</div>
</section>
</section>
{{outlet}}