Ghost/ghost/admin/app/components/gh-member-settings-form.hbs
Sanne de Vries 1306921cac 🎨 Updated Member page layout (#2271)
No issue

- Changed the Member details page to be more scalable and flexible, depending on whether creators are using subscriptions, emails, and stats.

* Hidden email stats on member detail page when subscriptions are off
* Hid subscription box on member details page when Stripe is not connected
* Updated copy and layout of member details page
* Updated old activity feed styles on member page
* Fixed padding issue for empty activity feed
* Fixed current and new activity feed
* Added Last seen to member details page behind feature flag
* Updated lint todo file
* Fixed spacing issue in member details
2022-03-01 15:57:57 +01:00

302 lines
20 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="gh-member-settings" ...attributes {{did-insert this.setup}}>
<section class="gh-main-section columns-3">
<GhMemberDetails @member={{@member}} />
<div class="gh-main-section-block span-2 mt6">
<div class="gh-main-section-content grey">
<div>
<div class="gh-cp-member-email-name">
<GhFormGroup @errors={{this.member.errors}} @hasValidated={{this.member.hasValidated}} @property="name" @classNames="max-width">
<label for="member-name">Name</label>
<GhTextInput @id="member-name" @name="name" @value={{this.scratchMember.name}} @tabindex="1" @shouldFocus="{{if this.member.isNew true}}"
@focus-out={{action "setProperty" "name" this.scratchMember.name}} data-test-input="member-name" />
<GhErrorMessage @errors={{this.member.errors}} @property="name" />
</GhFormGroup>
<GhFormGroup @errors={{this.member.errors}} @hasValidated={{this.member.hasValidated}} @property="email" @classNames="max-width">
<label for="member-email">Email</label>
<GhTextInput @value={{this.scratchMember.email}} @id="member-email" @name="email" @tabindex="2"
@autocapitalize="off" @autocorrect="off" @autocomplete="off"
@focus-out={{action "setProperty" "email" this.scratchMember.email}} data-test-input="member-email"/>
<GhErrorMessage @errors={{this.member.errors}} @property="email" />
</GhFormGroup>
</div>
<GhFormGroup @classNames="gh-member-labels">
<label for="label-input">Labels</label>
<GhMemberLabelInput
@onChange={{action "setLabels"}}
@allowEdit={{true}}
@onLabelEdit={{@onLabelEdit}}
@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-d1 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>
{{#if (not-eq this.settings.editorDefaultEmailRecipients "disabled")}}
<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>
{{/if}}
</div>
</div>
{{#if this.isStripeConnected}}
<h4 class="gh-main-section-header small bn">Subscriptions</h4>
{{#unless this.products}}
<div class="gh-main-section-content grey">
<div class="gh-cp-memberproduct-noproduct">
{{#unless this.isCreatingComplimentary}}
<div class="gh-members-no-data gh-members-no-subs">
<span class="lightgrey">{{svg-jar "no-data-subscription"}}</span>
<h4>No subscriptions</h4>
</div>
{{/unless}}
{{#unless this.member.isNew}}
{{#if this.isAddComplimentaryAllowed}}
{{#if this.isCreatingComplimentary}}
<GhLoadingSpinner />
{{else}}
{{#if (feature "multipleProducts")}}
{{!-- {{if has multiple products!}} --}}
<button type="button" class="gh-btn gh-btn-text green gh-btn-icon gh-btn-addproduct" {{action (toggle "showMemberProductModal" this)}}>
<span>{{svg-jar "add"}} Add complimentary subscription</span>
</button>
{{!-- {{/if}} --}}
{{else}}
<button type="button" class="gh-btn gh-btn-text green gh-btn-icon gh-btn-addproduct" {{action "addCompedSubscription"}}>
<span>{{svg-jar "add"}} Add complimentary subscription</span>
</button>
{{/if}}
{{/if}}
{{/if}}
{{/unless}}
</div>
</div>
{{/unless}}
{{#each this.products as |product|}}
<div class="gh-main-section-content grey gh-member-product-container">
<div class="gh-main-content-card gh-cp-memberproduct {{if (gt product.subscriptions.length 1) "multiple-subs" ""}}">
<h3 class="gh-memberproduct-name">
{{product.name}}
{{#if (gt product.subscriptions.length 1)}}
<span class="gh-memberproduct-subcount">{{product.subscriptions.length}} subscriptions</span>
{{/if}}
</h3>
{{#each product.subscriptions as |sub|}}
<div class="gh-memberproduct-subscription">
<div>
<div>
<span class="gh-cp-memberproduct-pricelabel">{{sub.price.nickname}}</span>
&ndash;
{{#if sub.cancel_at_period_end}}
<span class="gh-cp-memberproduct-renewal">Has access until {{sub.validUntil}}</span>
<span class="gh-badge archived">Cancelled</span>
{{else}}
<span class="gh-cp-memberproduct-renewal">Renews {{sub.validUntil}}</span>
<span class="gh-badge active">Active</span>
{{/if}}
</div>
{{#if sub.cancellationReason}}
<div class="gh-memberproduct-cancelreason"><span class="fw6">Cancellation reason:</span> {{sub.cancellationReason}}</div>
{{/if}}
{{#if sub.offer}}
<div>
<span class="gh-cp-memberproduct-pricelabel"> {{sub.offer.name}} </span>
offer
{{#if (eq sub.offer.type 'fixed')}}
({{currency-symbol sub.offer.currency}}{{gh-price-amount sub.offer.amount}} off)
{{else}}
({{sub.offer.amount}}% off)
{{/if}}
applied to subscription
</div>
{{/if}}
<div class="gh-memberproduct-created">
Created on {{sub.startDate}}
</div>
</div>
<div class="gh-memberproduct-price-container">
<div class="gh-product-card-price">
<div class="flex items-start">
<span class="currency-symbol">{{sub.price.currencySymbol}}</span>
<span class="amount">{{sub.price.nonDecimalAmount}}</span>
</div>
<div class="period">{{if (eq sub.price.interval "year") "yearly" "monthly"}}</div>
</div>
{{#if sub.isComplimentary}}
<span class="action-menu">
<GhDropdownButton @dropdownName="subscription-menu-complimentary" @classNames="gh-btn gh-btn-outline gh-btn-icon gh-btn-subscription-action icon-only" @title="Actions">
<span>
{{svg-jar "dotdotdot"}}
<span class="hidden">Subscription menu</span>
</span>
</GhDropdownButton>
<GhDropdown @name="subscription-menu-complimentary" @tagName="ul" @classNames="product-actions-menu dropdown-menu dropdown-align-right">
<li>
<button type="button" {{action "removeComplimentary" product.id}}>
<span class="red">Remove complimentary subscription</span>
</button>
</li>
</GhDropdown>
</span>
{{else}}
<span class="action-menu">
<GhDropdownButton @dropdownName="subscription-menu-{{sub.id}}" @classNames="gh-btn gh-btn-outline gh-btn-icon gh-btn-subscription-action icon-only" @title="Actions">
<span>
{{svg-jar "dotdotdot"}}
<span class="hidden">Subscription menu</span>
</span>
</GhDropdownButton>
<GhDropdown @name="subscription-menu-{{sub.id}}" @tagName="ul" @classNames="product-actions-menu dropdown-menu dropdown-align-right">
<li>
<a href="https://dashboard.stripe.com/customers/{{sub.customer.id}}" target="_blank" rel="noopener noreferrer">
View Stripe customer
</a>
</li>
<li class="divider"></li>
<li>
<a href="https://dashboard.stripe.com/subscriptions/{{sub.id}}" target="_blank" rel="noopener noreferrer">
View Stripe subscription
</a>
</li>
<li>
{{#if sub.cancel_at_period_end}}
<button type="button" {{action "continueSubscription" sub.id}}>
<span>Continue subscription</span>
</button>
{{else}}
<button type="button" {{action "cancelSubscription" sub.id}}>
<span class="red">Cancel subscription</span>
</button>
{{/if}}
</li>
</GhDropdown>
</span>
{{/if}}
</div>
</div>
{{/each}}
{{#if (and (feature "multipleProducts") (eq product.subscriptions.length 0))}}
<div class="gh-memberproduct-subscription">
<div>
<div>
<span class="gh-cp-memberproduct-pricelabel">Complimentary</span>
<span class="gh-badge active">Active</span>
</div>
<div class="gh-memberproduct-created">Created on</div>
</div>
<div class="flex items-center">
<div class="gh-product-card-price">
<div class="flex items-start">
<span class="currency-symbol">$</span>
<span class="amount">0</span>
</div>
<div class="period">yearly</div>
</div>
<span class="action-menu">
<GhDropdownButton @dropdownName="subscription-menu-complimentary" @classNames="gh-btn gh-btn-outline gh-btn-icon gh-btn-subscription-action icon-only" @title="Actions">
<span>
{{svg-jar "dotdotdot"}}
<span class="hidden">Subscription menu</span>
</span>
</GhDropdownButton>
<GhDropdown @name="subscription-menu-complimentary" @tagName="ul" @classNames="product-actions-menu dropdown-menu dropdown-align-right">
<li>
<button type="button" {{action "removeComplimentary" product.id}}>
<span class="red">Remove complimentary subscription</span>
</button>
</li>
</GhDropdown>
</span>
</div>
</div>
{{/if}}
{{#if (not (feature "multipleProducts"))}}
{{#if this.isAddComplimentaryAllowed}}
<div class="gh-memberproduct-list-footer bt b--whitegrey pt2 {{if this.isCreatingComplimentary "min-height" ""}}">
{{#if this.isCreatingComplimentary}}
<GhLoadingSpinner />
{{else}}
<button type="button" class="gh-btn gh-btn-text green gh-btn-icon gh-btn-addproduct" {{action "addCompedSubscription"}}>
<span>{{svg-jar "add"}} Add complimentary subscription</span>
</button>
{{/if}}
</div>
{{/if}}
{{/if}}
</div>
</div>
{{/each}}
{{#if (feature "multipleProducts")}}
{{#if (and this.products this.isAddComplimentaryAllowed)}}
<div class="gh-memberproduct-list-footer {{if this.isCreatingComplimentary "min-height" ""}}">
{{#if this.isCreatingComplimentary}}
<GhLoadingSpinner />
{{else}}
<button
type="button"
class="gh-btn gh-btn-text green gh-btn-icon gh-btn-addproduct"
{{action (toggle "showMemberProductModal" this)}}
>
<span>{{svg-jar "add"}} Add complimentary subscription</span>
</button>
{{/if}}
</div>
{{/if}}
{{/if}}
{{/if}}
{{#if (feature "membersActivityFeed")}}
<Member::ActivityFeed @member={{this.member}} />
{{else}}
<GhMemberActivityFeed
@member={{this.member}}
@emailRecipients={{this.member.emailRecipients}}
/>
{{/if}}
</div>
</section>
</div>
{{#if this.showMemberProductModal}}
<GhFullscreenModal @modifier="action wide member-product">
<ModalMemberProduct
@model={{this.member}}
@confirm={{this.addProduct}}
@closeModal={{this.closeMemberProductModal}} />
</GhFullscreenModal>
{{/if}}