diff --git a/internal/config/config.go b/internal/config/config.go index ea657cef..8013622e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -87,10 +87,24 @@ func InitConfig(logger *otelzap.Logger) Config { viper.SetDefault("config.require_teams", false) viper.SetDefault("config.subscriptions_enabled", false) - viper.SetDefault("subscription.checkout_link", "") - viper.SetDefault("subscription.manage_link", "") viper.SetDefault("subscription.account_secret", "") viper.SetDefault("subscription.webhook_secret", "") + viper.SetDefault("subscription.manage_link", "https://billing.stripe.com/p/login/5kA5lKeb7eU9bp6cMM") + viper.SetDefault("subscription.individual.enabled", true) + viper.SetDefault("subscription.individual.month_price", "5") + viper.SetDefault("subscription.individual.year_price", "50") + viper.SetDefault("subscription.individual.month_checkout_link", "https://buy.stripe.com/7sIcP8gdhc3nc6YeUU") + viper.SetDefault("subscription.individual.year_checkout_link", "https://buy.stripe.com/14kcP8e590kFb2UdQR") + viper.SetDefault("subscription.team.enabled", false) + viper.SetDefault("subscription.team.month_price", "20") + viper.SetDefault("subscription.team.year_price", "200") + viper.SetDefault("subscription.team.month_checkout_link", "https://buy.stripe.com/28o6qK5yD4AV3As5ks") + viper.SetDefault("subscription.team.year_checkout_link", "https://buy.stripe.com/aEUg1kaSX4AV7QI14d") + viper.SetDefault("subscription.organization.enabled", false) + viper.SetDefault("subscription.organization.month_price", "50") + viper.SetDefault("subscription.organization.year_price", "500") + viper.SetDefault("subscription.organization.month_checkout_link", "https://buy.stripe.com/8wM6qK2mr0kF5IA8wC") + viper.SetDefault("subscription.organization.year_checkout_link", "https://buy.stripe.com/eVa02m2mr7N74EwcMT") viper.SetDefault("admin.email", "") diff --git a/internal/config/types.go b/internal/config/types.go index 65939570..295a5cc3 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -1,5 +1,7 @@ package config +import "github.com/StevenWeathers/thunderdome-planning-poker/thunderdome" + type Config struct { Http Analytics @@ -10,7 +12,7 @@ type Config struct { Config AppConfig Feature Auth - Subscription + Subscription thunderdome.SubscriptionConfig } type Http struct { @@ -124,10 +126,3 @@ type AuthLdap struct { MailAttr string `mapstructure:"mail_attr"` CnAttr string `mapstructure:"cn_attr"` } - -type Subscription struct { - CheckoutLink string `mapstructure:"checkout_link"` - ManageLink string `mapstructure:"manage_link"` - AccountSecret string `mapstructure:"account_secret"` - WebhookSecret string `mapstructure:"webhook_secret"` -} diff --git a/main.go b/main.go index c5b94b85..3a35ad0f 100644 --- a/main.go +++ b/main.go @@ -231,8 +231,7 @@ func main() { FeatureStoryboard: c.Feature.Storyboard, RequireTeams: c.Config.RequireTeams, SubscriptionsEnabled: c.Config.SubscriptionsEnabled, - SubscriptionCheckoutLink: c.Subscription.CheckoutLink, - SubscriptionManageLink: c.Subscription.ManageLink, + Subscription: c.Subscription, RepoURL: repoURL, }, }, diff --git a/thunderdome/app.go b/thunderdome/app.go index 24b7890b..0e96c3e2 100644 --- a/thunderdome/app.go +++ b/thunderdome/app.go @@ -1,5 +1,22 @@ package thunderdome +type SubscriptionPlanConfig struct { + Enabled bool `mapstructure:"enabled"` + MonthPrice string `mapstructure:"month_price"` + YearPrice string `mapstructure:"year_price"` + MonthCheckoutLink string `mapstructure:"month_checkout_link"` + YearCheckoutLink string `mapstructure:"year_checkout_link"` +} + +type SubscriptionConfig struct { + ManageLink string `mapstructure:"manage_link"` + AccountSecret string `mapstructure:"account_secret" json:"-"` + WebhookSecret string `mapstructure:"webhook_secret" json:"-"` + Individual SubscriptionPlanConfig `mapstructure:"individual"` + Team SubscriptionPlanConfig `mapstructure:"team"` + Organization SubscriptionPlanConfig `mapstructure:"organization"` +} + type AppConfig struct { AllowedPointValues []string DefaultPointValues []string @@ -29,10 +46,9 @@ type AppConfig struct { FeatureRetro bool FeatureStoryboard bool RequireTeams bool - SubscriptionsEnabled bool - SubscriptionCheckoutLink string - SubscriptionManageLink string RepoURL string + SubscriptionsEnabled bool + Subscription SubscriptionConfig } type UIConfig struct { diff --git a/ui/src/components/icons/ArrowRight.svelte b/ui/src/components/icons/ArrowRight.svelte new file mode 100644 index 00000000..f202515a --- /dev/null +++ b/ui/src/components/icons/ArrowRight.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/ui/src/components/pricing/Checkmark.svelte b/ui/src/components/pricing/Checkmark.svelte new file mode 100644 index 00000000..fb92ab26 --- /dev/null +++ b/ui/src/components/pricing/Checkmark.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/ui/src/components/pricing/Crossmark.svelte b/ui/src/components/pricing/Crossmark.svelte new file mode 100644 index 00000000..8d52a693 --- /dev/null +++ b/ui/src/components/pricing/Crossmark.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/ui/src/components/pricing/PayPeriodToggle.svelte b/ui/src/components/pricing/PayPeriodToggle.svelte new file mode 100644 index 00000000..79f9f777 --- /dev/null +++ b/ui/src/components/pricing/PayPeriodToggle.svelte @@ -0,0 +1,60 @@ + + + + +
+ + +
diff --git a/ui/src/components/pricing/SubscribeButton.svelte b/ui/src/components/pricing/SubscribeButton.svelte new file mode 100644 index 00000000..6686eaf0 --- /dev/null +++ b/ui/src/components/pricing/SubscribeButton.svelte @@ -0,0 +1,43 @@ + + +
+ {#if planEnabled} + {#if !$user.name || !$user.rank || $user.rank === 'GUEST'} +

+ Login + or + Register to subscribe +

+ {:else if $user.subscribed} +

+ Already subscribed, thank you! +

+ {:else} + + Subscribe Today + + +

+ Payments processed by Stripe. +

+ {/if} + {:else} +

+ Coming soon! +

+ {/if} +
diff --git a/ui/src/config.ts b/ui/src/config.ts index fb548a3a..dc383269 100644 --- a/ui/src/config.ts +++ b/ui/src/config.ts @@ -22,6 +22,7 @@ const AppConfig = : { PathPrefix: '', DefaultLocale: 'en', + Subscription: {}, }; const { PathPrefix, diff --git a/ui/src/pages/subscription/Pricing.svelte b/ui/src/pages/subscription/Pricing.svelte index 1761261d..4da5939e 100644 --- a/ui/src/pages/subscription/Pricing.svelte +++ b/ui/src/pages/subscription/Pricing.svelte @@ -1,201 +1,478 @@
-
-

Starter

-

- All the primary features at no cost. -

-
- Free -
-
    -
  • - - - - Agile Poker Planning -
  • -
  • - - - - Poker planning import stories from Jira XML or CSV files -
  • -
  • - - - - Agile Sprint Retrospective -
  • -
  • - - - - Team Check-ins or asynchronous stand ups -
  • -
  • - - - - Agile Story Mapping (Storyboards) -
  • -
  • - - - - Team organization -
  • -
-
+

+ Simple pricing, + no commitment. +

+

+ Everything you need, nothing you don't. Pick a plan that best suits your + needs. +

+
-
-

Premium

-

- Primary features plus enhanced ones. -

-
- $5 - /monthPlans + +
+ +
+ +
+
+ - -
    -
  • - - - - Poker planning import stories from Jira Cloud using JQL search -
  • -
-
    -
  • - + {#each Plans as plan, pidx} +
    - - - Future premium features -
  • -
-
    -
  • - - - - Supporting the developer and hosting costs -
  • -
- {#if !$user.name || !$user.rank || $user.rank === 'GUEST'} -

- Must register - or - login to subscribe -

- {:else if $user.subscribed} -

- Already subscribed, thank you! -

- {:else} - - Subscribe today - - {/if} + {#if plan.Popular} + Popular + {/if} +
+

{plan.Name}

+

+ {#if plan.Price.Free} + Free + {:else} + {#if selectedPaymentPeriod === 'month'}${plan.Price + .Month}{:else} + ${plan.Price.Year}{/if} + {#if selectedPaymentPeriod === 'month'}/mo{:else}/yr{/if} + {/if} +

+ {plan.Price.Subtext} +
+
+ {#each plan.Features as feature, idx} +

+ {#if feature.Header} + {feature.Name} + {:else} + {#if feature.Included} + + {:else} + + {/if} + {feature.Name} + {/if} +

+ {/each} +
+
+ {#if plan.Price.Free} + {#if $user.rank && $user.rank !== 'GUEST'} +

+ Already registered. +

+ {:else} + Register + + + {/if} + {:else} + + {/if} +
+
+ {/each} +
- +
diff --git a/ui/src/pages/user/UserProfile.svelte b/ui/src/pages/user/UserProfile.svelte index e5994989..a3cd93ca 100644 --- a/ui/src/pages/user/UserProfile.svelte +++ b/ui/src/pages/user/UserProfile.svelte @@ -32,7 +32,7 @@ LdapEnabled, HeaderAuthEnabled, SubscriptionsEnabled, - SubscriptionManageLink, + Subscription, } = AppConfig; function toggleUpdatePassword() { @@ -339,7 +339,7 @@ {#if $user.subscribed} Manage subscription