Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: org creation new flow #1080

Merged
merged 43 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5a2d85f
feat: new org creation
ArmanNik Apr 24, 2024
61dcfb4
Merge branch 'main' of github.com:appwrite/console into refactor-org-…
ArmanNik May 3, 2024
4ac90c3
chore: remove imports
ArmanNik May 3, 2024
74bbcad
feat: more work on the creation flow
ArmanNik May 3, 2024
4550a77
chore: Update import paths for payment methods and payment modal comp…
ArmanNik May 6, 2024
76b2ba4
chore: Add end slot to inputSelectSearch and update import paths for …
ArmanNik May 6, 2024
5894eb8
feat: create org wizard ✨
ArmanNik May 7, 2024
3be52e3
feat: replace creation wizard in console, add search param logic
ArmanNik May 7, 2024
9ba9758
feat: add routing
ArmanNik May 7, 2024
c9f0ca8
chore: remove old code and move usageRates
ArmanNik May 7, 2024
07db6cd
feat: add comparison box
ArmanNik May 8, 2024
580d654
chore: remove console log
ArmanNik May 8, 2024
72a57fb
initial commit
ArmanNik May 8, 2024
9a305cb
fix: make address optional
ArmanNik May 9, 2024
8982abf
Merge branch 'main' of github.com:appwrite/console into refactor-org-…
ArmanNik May 9, 2024
92e7989
Merge branch 'refactor-org-creation' of github.com:appwrite/console i…
ArmanNik May 9, 2024
f00a197
Merge branch 'main' of github.com:appwrite/console into refactor-org-…
ArmanNik May 9, 2024
ba74ffe
feat: change tier functrion
ArmanNik May 9, 2024
34103f9
more fixes
ArmanNik May 13, 2024
6227998
empty commit
ArmanNik May 13, 2024
9ff105a
feat: design fixes, upgrade flow
ArmanNik May 13, 2024
6470cc0
fix: error
ArmanNik May 14, 2024
e130543
fix: hide fields when current plan selected
ArmanNik May 14, 2024
2c7abb3
feat: add missing alerts
ArmanNik May 14, 2024
8985bdc
Merge branch 'main' of github.com:appwrite/console into refactor-org-…
ArmanNik May 14, 2024
c92c637
Merge branch 'refactor-org-creation' of github.com:appwrite/console i…
ArmanNik May 14, 2024
d8c8027
bump: stripe
ArmanNik May 15, 2024
f3f9169
Merge pull request #1085 from appwrite/refactor-org-plan-change
TorstenDittmann May 15, 2024
66dad86
feat: add new wizard to buttons
ArmanNik May 15, 2024
760c15e
feat: centralize url
ArmanNik May 15, 2024
dba4bf5
chore: delete old wizard, small fixes
ArmanNik May 15, 2024
fbfab72
chore: finish removing old wizard
ArmanNik May 15, 2024
fcc8fde
fix: code review
ArmanNik May 21, 2024
1d9bd6e
Merge branch 'refactor-org-creation' of github.com:appwrite/console i…
ArmanNik May 21, 2024
4f3ec5c
fix: design and bugs
ArmanNik May 22, 2024
021db90
refactor: alert buttons
ArmanNik May 22, 2024
241b9aa
Merge branch 'main' of github.com:appwrite/console into feat-e2e-new-…
ArmanNik May 22, 2024
ea5ccb8
fix: old upgrade wizard
ArmanNik May 22, 2024
04fe869
feat: upgrade e2e test for new flow
ArmanNik May 22, 2024
55f794d
Merge pull request #1096 from appwrite/refactor-alert-buttons
TorstenDittmann May 22, 2024
db5200e
Merge pull request #1095 from appwrite/fix-new-org-flows-design-bugs
TorstenDittmann May 22, 2024
f820242
Merge pull request #1097 from appwrite/feat-e2e-new-flows
TorstenDittmann May 22, 2024
c138cd3
Merge pull request #1089 from appwrite/fix-upgrade-buttons-logic
TorstenDittmann May 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@popperjs/core": "^2.11.8",
"@sentry/svelte": "^7.66.0",
"@sentry/tracing": "^7.66.0",
"@stripe/stripe-js": "^2.2.0",
"@stripe/stripe-js": "^3.4.0",
"ai": "^2.2.11",
"analytics": "^0.8.9",
"dayjs": "^1.11.9",
Expand Down
18 changes: 10 additions & 8 deletions src/lib/components/alert.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import type { Buttons } from '../stores/notifications';
import { createEventDispatcher, type ComponentProps } from 'svelte';
import { Button } from '$lib/elements/forms';

export let dismissible = false;
export let type: 'info' | 'success' | 'warning' | 'error' | 'default' = 'info';
export let buttons: Buttons[] = [];
export let buttons: (ComponentProps<Button> & {
slot: string;
onClick?: (e: MouseEvent) => void;
})[] = [];
export let isAction = false;
export let isStandalone = false;
let classes = '';
Expand Down Expand Up @@ -53,8 +55,8 @@
<div class="alert-buttons u-flex">
<slot name="buttons">
{#each buttons as button}
<Button text on:click={button.method}>
<span class="text">{button.name}</span>
<Button text {...button} on:click={button.onClick}>
<span class="text">{button.slot}</span>
</Button>
{/each}
</slot>
Expand All @@ -66,9 +68,9 @@
<div class="alert-buttons u-flex u-gap-16 u-cross-child-center">
<slot name="buttons">
{#each buttons as button}
<button type="button" class="button is-text" on:click={button.method}>
<span class="text">{button.name}</span>
</button>
<Button text {...button} on:click={button.onClick}>
+ <span class="text">{button.slot}</span>
</Button>
{/each}
</slot>
</div>
Expand Down
10 changes: 4 additions & 6 deletions src/lib/components/billing/alerts/limitReached.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
import { readOnly, tierToPlan } from '$lib/stores/billing';
import { hideBillingHeaderRoutes, readOnly, tierToPlan, upgradeURL } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
import { wizard } from '$lib/stores/wizard';
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
</script>

{#if $organization?.$id && $organization?.billingPlan === BillingPlan.STARTER && $readOnly && !$page.url.pathname.includes('/console/account')}
{#if $organization?.$id && $organization?.billingPlan === BillingPlan.STARTER && $readOnly && !hideBillingHeaderRoutes.includes($page.url.pathname)}
<HeaderAlert
type="error"
title={`${$organization.name} usage has reached the ${tierToPlan($organization.billingPlan).name} plan limit`}>
Expand All @@ -21,14 +19,14 @@
</svelte:fragment>
<svelte:fragment slot="buttons">
<Button
href={`${base}/console/organization-${$organization?.$id}/usage`}
href={`${base}/console/organization-${$organization.$id}/usage`}
text
fullWidthMobile>
<span class="text">View usage</span>
</Button>
<Button
href={$upgradeURL}
on:click={() => {
wizard.start(ChangeOrganizationTierCloud);
trackEvent('click_organization_upgrade', {
from: 'button',
source: 'limit_reached_banner'
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/billing/alerts/markedForDeletion.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script lang="ts">
import { page } from '$app/stores';
import { HeaderAlert } from '$lib/layout';
import { hideBillingHeaderRoutes } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
</script>

{#if $organization?.markedForDeletion && !$page.url.pathname.includes('/console/account')}
{#if $organization?.markedForDeletion && !hideBillingHeaderRoutes.includes($page.url.pathname)}
<HeaderAlert title="Organization flagged for deletion">
<svelte:fragment>
All existing projects in the {$organization.name} organization have been paused. This organization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
import { hideBillingHeaderRoutes } from '$lib/stores/billing';
import { orgMissingPaymentMethod } from '$routes/console/store';
</script>

{#if ($orgMissingPaymentMethod.billingPlan === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlan === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !$page.url.pathname.includes('/console/account')}
{#if ($orgMissingPaymentMethod.billingPlan === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlan === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !hideBillingHeaderRoutes.includes($page.url.pathname)}
<HeaderAlert
type="error"
title={`Payment method required for ${$orgMissingPaymentMethod.name}`}>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/billing/alerts/paymentAuthRequired.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import { page } from '$app/stores';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
import { actionRequiredInvoices } from '$lib/stores/billing';
import { actionRequiredInvoices, hideBillingHeaderRoutes } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
import { VARS } from '$lib/system';

const endpoint = VARS.APPWRITE_ENDPOINT ?? `${$page.url.origin}/v1`;
</script>

{#if $actionRequiredInvoices && $actionRequiredInvoices?.invoices?.length && !$page.url.pathname.includes('/console/account')}
{#if $actionRequiredInvoices && $actionRequiredInvoices?.invoices?.length && !hideBillingHeaderRoutes.includes($page.url.pathname)}
<HeaderAlert title="Authorization required" type="error">
Please authorize your upcoming payment for {$organization.name}. Your bank requires this
security measure to proceed with payment.
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/billing/alerts/paymentMandate.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
import { paymentMissingMandate } from '$lib/stores/billing';
import { hideBillingHeaderRoutes, paymentMissingMandate } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
import { confirmSetup } from '$lib/stores/stripe';
Expand All @@ -16,7 +16,7 @@
}
</script>

{#if $paymentMissingMandate && $paymentMissingMandate.country === 'in' && $paymentMissingMandate.mandateId === null && !$page.url.pathname.includes('/console/account')}
{#if $paymentMissingMandate && $paymentMissingMandate.country === 'in' && $paymentMissingMandate.mandateId === null && !hideBillingHeaderRoutes.includes($page.url.pathname)}
<HeaderAlert title="Authorization required" type="info">
The payment method for {$organization.name} needs to be verified.
<svelte:fragment slot="buttons">
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/billing/alerts/projectsAtRisk.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import { Button } from '$lib/elements/forms';
import { diffDays, toLocaleDate } from '$lib/helpers/date';
import { HeaderAlert } from '$lib/layout';
import { failedInvoice } from '$lib/stores/billing';
import { failedInvoice, hideBillingHeaderRoutes } from '$lib/stores/billing';
</script>

{#if $failedInvoice && !$page.url.pathname.includes('/console/account')}
{#if $failedInvoice && !hideBillingHeaderRoutes.includes($page.url.pathname)}
{@const daysPassed = diffDays(new Date($failedInvoice.dueAt), new Date())}
<HeaderAlert title="Your projects are at risk">
<svelte:fragment>
Expand Down
6 changes: 2 additions & 4 deletions src/lib/components/billing/emptyCardCloud.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import { trackEvent } from '$lib/actions/analytics';
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { tierToPlan } from '$lib/stores/billing';
import { wizard } from '$lib/stores/wizard';
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
import { tierToPlan, upgradeURL } from '$lib/stores/billing';
import { Card } from '..';

export let service: string;
Expand All @@ -23,12 +21,12 @@
class="u-margin-block-start-16"
secondary
fullWidthMobile
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
from: 'button',
source: eventSource
});
wizard.start(ChangeOrganizationTierCloud);
}}>
Upgrade
</Button>
Expand Down
113 changes: 113 additions & 0 deletions src/lib/components/billing/estimatedTotalBox.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<script lang="ts">
import { tooltip } from '$lib/actions/tooltip';
import { FormList, InputChoice, InputNumber } from '$lib/elements/forms';
import { toLocaleDate } from '$lib/helpers/date';
import { formatCurrency } from '$lib/helpers/numbers';
import type { Coupon } from '$lib/sdk/billing';
import { plansInfo, type Tier } from '$lib/stores/billing';

export let billingPlan: Tier;
export let collaborators: string[];
export let couponData: Partial<Coupon>;
export let billingBudget: number;

const today = new Date();
const billingPayDate = new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000);

let budgetEnabled = false;

$: currentPlan = $plansInfo.get(billingPlan);
$: extraSeatsCost = (collaborators?.length ?? 0) * (currentPlan?.addons?.member?.price ?? 0);
$: grossCost = currentPlan.price + extraSeatsCost;
$: estimatedTotal =
couponData?.status === 'active'
? grossCost - couponData.credits >= 0
? grossCost - couponData.credits
: 0
: grossCost;
$: trialEndDate = new Date(
billingPayDate.getTime() + currentPlan.trialDays * 24 * 60 * 60 * 1000
);
</script>

<section class="card u-margin-block-start-32 u-flex u-flex-vertical u-gap-8">
<span class="u-flex u-main-space-between">
<p class="text">{currentPlan.name} plan</p>
<p class="text">{formatCurrency(currentPlan.price)}</p>
</span>
<span class="u-flex u-main-space-between">
<p class="text">Additional seats ({collaborators?.length})</p>
<p class="text">
{formatCurrency(extraSeatsCost)}
</p>
</span>
{#if couponData?.status === 'active'}
<span class="u-flex u-main-space-between">
<div class="u-flex u-cross-center u-gap-4">
<p class="text">
<span class="icon-tag u-color-text-success" aria-hidden="true" />
{#if couponData.credits > 100}
{couponData.code.toUpperCase()}
{:else}
<span use:tooltip={{ content: couponData.code.toUpperCase() }}
>Credits applied</span>
{/if}
</p>
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close"
title="Close"
on:click={() =>
(couponData = {
code: null,
status: null,
credits: null
})}>
<span class="icon-x" aria-hidden="true" />
</button>
</div>
{#if couponData.credits > 100}
<p class="inline-tag" use:tooltip={{ content: formatCurrency(couponData.credits) }}>
Credits applied
</p>
{:else}
<span class="u-color-text-success">-{formatCurrency(couponData.credits)}</span>
{/if}
</span>
{/if}
<div class="u-sep-block-start" />
<span class="u-flex u-main-space-between">
<p class="text">Estimated total</p>
<p class="text">
{formatCurrency(estimatedTotal)}
</p>
</span>

<p class="text u-margin-block-start-16">
Your payment method will be charged this amount plus usage fees every 30 days {!currentPlan.trialDays
? `starting ${toLocaleDate(billingPayDate.toString())}`
: ` after your trial period ends on ${toLocaleDate(trialEndDate.toString())}`}.
</p>
<FormList class="u-margin-block-start-24">
<InputChoice
type="switchbox"
id="budget"
label="Enable budget cap"
tooltip="If enabled, you will be notified when your spending reaches 75% of the set cap. Update cap alerts in your organization settings."
fullWidth
bind:value={budgetEnabled}>
{#if budgetEnabled}
<div class="u-margin-block-start-16">
<InputNumber
id="budget"
label="Budget cap (USD)"
placeholder="0"
min={0}
bind:value={billingBudget} />
</div>
{/if}
</InputChoice>
</FormList>
</section>
4 changes: 4 additions & 0 deletions src/lib/components/billing/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export { default as PaymentBoxes } from './paymentBoxes.svelte';
export { default as CouponInput } from './couponInput.svelte';
export { default as SelectPaymentMethod } from './selectPaymentMethod.svelte';
export { default as UsageRates } from './usageRates.svelte';
export { default as EstimatedTotalBox } from './estimatedTotalBox.svelte';
export { default as PlanComparisonBox } from './planComparisonBox.svelte';
export { default as EmptyCardCloud } from './emptyCardCloud.svelte';
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,14 @@
}
</script>

<FakeModal bind:show title="Add payment method" bind:error onSubmit={handleSubmit}>
<FakeModal
bind:show
title="Add payment method"
bind:error
onSubmit={handleSubmit}
headerDivider={false}>
<FormList gap={16}>
<slot />
<InputText
id="name"
label="Cardholder name"
Expand All @@ -86,10 +92,11 @@
<!-- Stripe will create form elements here -->
</div>
</div>
<slot name="end"></slot>
</FormList>
<svelte:fragment slot="footer">
<Button secondary on:click={() => (show = false)}>Cancel</Button>
<Button submit disabled={!name}>Save</Button>
<Button submit disabled={!name}>Add</Button>
</svelte:fragment>
</FakeModal>

Expand Down
Loading
Loading