FEATURE: Better UX for anonymous users (#25)

Improves the subscription flow for anonymous users by making the routes available, and showing a login button. Clicking login from this page will save a `destination_url` cookie so that when logging in they're redirected back to the subscription page they were at.
This commit is contained in:
Justin DiRose 2020-10-28 13:30:26 -05:00 committed by GitHub
parent 8ffe769ca9
commit 1ad5b17640
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 55 additions and 33 deletions

View File

@ -5,7 +5,7 @@ module DiscourseSubscriptions
include DiscourseSubscriptions::Stripe include DiscourseSubscriptions::Stripe
include DiscourseSubscriptions::Group include DiscourseSubscriptions::Group
before_action :set_api_key before_action :set_api_key
requires_login requires_login except: [:index, :show]
def index def index
begin begin

View File

@ -0,0 +1,17 @@
import Component from "@ember/component";
import cookie from "discourse/lib/cookie";
import DiscourseURL from "discourse/lib/url";
import { default as getURL } from "discourse-common/lib/get-url";
export default Component.extend({
classNames: ["login-required", "subscriptions"],
actions: {
createAccount() {
const destinationUrl = window.location.href;
const cookiePath = getURL("/");
cookie("destination_url", destinationUrl, { path: cookiePath });
DiscourseURL.redirectTo("/login");
},
},
});

View File

@ -1,17 +1,12 @@
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import User from "discourse/models/user";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import Component from "@ember/component"; import Component from "@ember/component";
export default Component.extend({ export default Component.extend({
classNames: ["product-list"], classNames: ["product-list"],
@discourseComputed("products") @discourseComputed("products")
emptyProducts(products) { emptyProducts(products) {
return isEmpty(products); return isEmpty(products);
}, },
@discourseComputed()
isLoggedIn() {
return User.current();
},
}); });

View File

@ -1,3 +1,10 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators";
import User from "discourse/models/user";
export default Controller.extend({}); export default Controller.extend({
@discourseComputed()
isLoggedIn() {
return User.current();
},
});

View File

@ -5,6 +5,7 @@ import I18n from "I18n";
export default Controller.extend({ export default Controller.extend({
selectedPlan: null, selectedPlan: null,
isAnonymous: Ember.computed.not("currentUser"),
init() { init() {
this._super(...arguments); this._super(...arguments);

View File

@ -0,0 +1,2 @@
<h3>{{i18n 'discourse_subscriptions.subscribe.unauthenticated'}}</h3>
{{d-button label="log_in" action="createAccount" icon="user" class="btn btn-primary"}}

View File

@ -13,7 +13,7 @@
<div class="product-purchase"> <div class="product-purchase">
{{#if product.subscribed}} {{#if product.subscribed}}
<span class="purchased">&#x2713; {{i18n 'discourse_subscriptions.subscribe.purchased'}}</span> <span class="purchased">&#x2713; {{i18n 'discourse_subscriptions.subscribe.purchased'}}</span>
<a class="billing-link" href="/my/billing">{{I18n 'discourse_subscriptions.subscribe.go_to_billing'}}</a> <a class="billing-link" href="/my/billing">{{I18n 'discourse_subscriptions.subscribe.go_to_billing'}}</a>
{{else}} {{else}}
{{#link-to "s.show" product.id disabled=product.subscribed class="btn btn-primary"}} {{#link-to "s.show" product.id disabled=product.subscribed class="btn btn-primary"}}
{{i18n 'discourse_subscriptions.subscribe.title'}} {{i18n 'discourse_subscriptions.subscribe.title'}}
@ -24,9 +24,4 @@
</div> </div>
{{/each}} {{/each}}
{{#unless isLoggedIn}}
<p>
{{i18n 'discourse_subscriptions.subscribe.unauthenticated'}}
</p>
{{/unless}}
{{/if}} {{/if}}

View File

@ -1 +1,4 @@
{{product-list products=model}} {{#unless isLoggedIn}}
{{login-required}}
{{/unless}}
{{product-list products=model isLoggedIn=isLoggedIn}}

View File

@ -26,11 +26,13 @@
<hr> <hr>
{{subscribe-card cardElement=cardElement}}
{{#if loading}} {{#if loading}}
{{loading-spinner}} {{loading-spinner}}
{{else if isAnonymous}}
{{login-required}}
{{else}} {{else}}
{{subscribe-card cardElement=cardElement}}
{{d-button {{d-button
disabled=loading disabled=loading
action="stripePaymentHandler" action="stripePaymentHandler"

View File

@ -63,7 +63,7 @@ en:
subscribe: subscribe:
title: Subscribe title: Subscribe
no_products: There are currently no products available. no_products: There are currently no products available.
unauthenticated: You need to create an account to subscribe. unauthenticated: Log in or create an account to subscribe.
card: card:
title: Payment title: Payment
customer: customer:

View File

@ -1,41 +1,41 @@
export default function(helpers) { export default function (helpers) {
const { response } = helpers; const { response } = helpers;
this.get("/s/products", () => { this.get("/s", () => {
const products = [ const products = [
{ {
id: "prod_23o8I7tU4g56", id: "prod_23o8I7tU4g56",
name: "Awesome Product", name: "Awesome Product",
description: description:
"Subscribe to our awesome product. For only $230.10 per month, you can get access. This is a test site. No real credit card transactions." "Subscribe to our awesome product. For only $230.10 per month, you can get access. This is a test site. No real credit card transactions.",
}, },
{ {
id: "prod_B23dc9I7tU4eCy", id: "prod_B23dc9I7tU4eCy",
name: "Special Product", name: "Special Product",
description: description:
"This is another subscription product. You can have more than one. From $12 per month." "This is another subscription product. You can have more than one. From $12 per month.",
} },
]; ];
return response(products); return response(products);
}); });
this.get("/s/products/:id", () => { this.get("/s/:id", () => {
const product = {}; const product = {
id: "prod_23o8I7tU4g56",
return response(product); name: "Awesome Product",
}); description:
"Subscribe to our awesome product. For only $230.10 per month, you can get access. This is a test site. No real credit card transactions.",
this.get("/s/plans", () => { };
const plans = [ const plans = [
{ {
id: "plan_GHGHSHS8654G", id: "plan_GHGHSHS8654G",
amount: 200, amount: 200,
currency: "usd", currency: "usd",
interval: "month" interval: "month",
} },
]; ];
return response(plans); return response({ product, plans });
}); });
} }