diff --git a/src/lib/components/billing/creditsApplied.svelte b/src/lib/components/billing/creditsApplied.svelte index 6cf231e57..1010f0f5e 100644 --- a/src/lib/components/billing/creditsApplied.svelte +++ b/src/lib/components/billing/creditsApplied.svelte @@ -42,9 +42,7 @@ {/if} {#if couponData.credits >= 100} -

- Credits applied -

+

Credits applied

{:else} -{formatCurrency(couponData.credits)} {/if} diff --git a/src/lib/components/billing/estimatedTotalBox.svelte b/src/lib/components/billing/estimatedTotalBox.svelte index 52ac4faba..3ff31041c 100644 --- a/src/lib/components/billing/estimatedTotalBox.svelte +++ b/src/lib/components/billing/estimatedTotalBox.svelte @@ -32,9 +32,10 @@
+

{currentPlan.name} plan

{formatCurrency(currentPlan.price)}

diff --git a/src/lib/elements/forms/inputText.svelte b/src/lib/elements/forms/inputText.svelte index ac354e3f2..0da7f7b38 100644 --- a/src/lib/elements/forms/inputText.svelte +++ b/src/lib/elements/forms/inputText.svelte @@ -108,7 +108,7 @@
- import { Heading } from '$lib/components'; + import { Avatar, AvatarInitials, Card, Heading } from '$lib/components'; import AppwriteLogoDark from '$lib/images/appwrite-logo-dark.svg'; import AppwriteLogoLight from '$lib/images/appwrite-logo-light.svg'; import LoginDark from '$lib/images/login/login-dark-mode.png'; import LoginLight from '$lib/images/login/login-light-mode.png'; import type { Coupon } from '$lib/sdk/billing'; import { app } from '$lib/stores/app'; - import { campaigns } from '$lib/stores/campaigns'; + import { campaigns, type CampaignData } from '$lib/stores/campaigns'; import { user } from '$lib/stores/user'; export const imgLight = LoginLight; @@ -15,8 +15,13 @@ export let campaign: string = null; export let coupon: Coupon = null; - $: variation = coupon?.campaign ?? campaign ? 'card' : 'default'; $: selectedCampaign = campaigns.get(coupon?.campaign ?? campaign); + $: variation = (coupon?.campaign ?? campaign ? selectedCampaign?.template : 'default') as + | 'default' + | CampaignData['template']; + + let currentReviewNumber = 0; + $: currentReview = selectedCampaign?.data?.reviews?.[currentReviewNumber]; function generateTitle() { if (coupon?.credits) { @@ -37,17 +42,17 @@
- {#if variation === 'card'} + {#if variation !== 'default'}
+ {:else if variation === 'review'} +
+
+
+ + {generateTitle()} + +
+
+ + {generateTitle()} + +
+
+ +

{generateDesc()}

+
+ +

+ {currentReview.review} +

+
+ {#if currentReview?.img} + + {:else} + + {/if} +
+

{currentReview.name}

+

{currentReview.desc}

+
+
+
+
+
{/if}
@@ -116,7 +170,7 @@

+ class:u-padding-block-start-24={variation !== 'default'}>

@@ -303,6 +357,9 @@ .auth-container { max-inline-size: 27.5rem; } + .review-container { + max-inline-size: 30rem; + } .logo-variation { padding-block-start: 2rem; diff --git a/src/lib/layout/wizardSecondaryContent.svelte b/src/lib/layout/wizardSecondaryContent.svelte index 6b69d488a..908995692 100644 --- a/src/lib/layout/wizardSecondaryContent.svelte +++ b/src/lib/layout/wizardSecondaryContent.svelte @@ -4,8 +4,6 @@
-
- -
+
diff --git a/src/lib/stores/campaigns.ts b/src/lib/stores/campaigns.ts index cf381f16d..33f31133d 100644 --- a/src/lib/stores/campaigns.ts +++ b/src/lib/stores/campaigns.ts @@ -1,40 +1,69 @@ //campaign welcome and startup -type CampaignData = { +export type CampaignData = { title: string; description: string; + template: 'card' | 'review'; + data?: Record; + onlyNewOrgs?: boolean; }; export const campaigns: Map = new Map(); campaigns .set('welcome', { + template: 'card', title: "You've received $VALUE in credits", description: 'Get $VALUE in credits when you upgrade or create an organization with a Pro plan.' }) .set('startup', { + template: 'card', title: 'Welcome to the Startups program!', description: "We're excited to have you on board. Add the coupon code to your Appwrite Pro account to join." }) .set('RenderATL2024', { + template: 'card', title: 'Claim your $100 RenderATL credits', description: 'Get $100 in Cloud credits when you upgrade or create an organization with a Pro plan.' }) .set('dealsfordevs', { + template: 'card', title: 'Claim your $50 Deals For Devs credits', description: 'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan.' }) .set('WelcomeManual', { + template: 'card', title: 'Here is your $VALUE welcome credit!', description: 'Upgrade to Appwrite Pro and add the credits to enjoy the full capabilities of Cloud.' }) .set('InactiveAccounts', { + template: 'card', title: 'Get everything out of Cloud. Claim your $VALUE credits.', description: 'Get $VALUE in Cloud credits when you upgrade or create an organization with a Pro plan.' + }) + .set('StartupsProgram', { + template: 'review', + title: 'Welcome to the Startups program', + description: + "We're excited to have you on board. Add your credit code to your Appwrite Pro account to join.", + onlyNewOrgs: true, + data: { + cta: 'Get everything out of Cloud with Pro', + claimed: 'Your credits will be valid for 12 months.', + unclaimed: 'Apply your code to join the Startups program.', + reviews: [ + { + name: 'David Foster', + img: '1.jpeg', + desc: 'Managing director', + review: 'We really loved working with Appwrite for launching our bootstrapped "Open Mind" App. It was saving us a lot of money in comparison to Firebase since the amount of users grew quite fast and we needed a quick switch.' + } + ] + } }); diff --git a/src/routes/console/apply-credit/+page.svelte b/src/routes/console/apply-credit/+page.svelte index 4395538f1..d1dd1ce47 100644 --- a/src/routes/console/apply-credit/+page.svelte +++ b/src/routes/console/apply-credit/+page.svelte @@ -67,10 +67,11 @@ let name: string; let coupon: string; let couponData = data?.couponData; + let campaign = campaigns.get(data?.couponData?.campaign ?? data?.campaign); onMount(async () => { await loadPaymentMethods(); - if (!$organizationList?.total) { + if (!$organizationList?.total || campaign?.onlyNewOrgs) { selectedOrgId = newOrgId; } }); @@ -183,7 +184,6 @@ $: isButtonDisabled = checkButtonDisabled(selectedOrgId, name, paymentMethodId) || couponData?.status !== 'active'; - $: campaign = campaigns.get(data?.couponData?.campaign ?? data?.campaign); function checkButtonDisabled(id: string | null, name: string | null, method: string | null) { if (id === newOrgId) { @@ -207,7 +207,7 @@
- {#if $organizationList?.total} + {#if $organizationList?.total && !campaign?.onlyNewOrgs} -
-
-
- promo -

- {#if couponData?.credits} - {campaign.title.replace('VALUE', couponData.credits.toString())} - {:else} - {campaign.title} - {/if} -

+ {#if campaign?.template === 'card'} +
+
+
+ promo +

+ {#if couponData?.credits} + {campaign.title.replace('VALUE', couponData.credits.toString())} + {:else} + {campaign.title} + {/if} +

+
-
+ {/if} {#if selectedOrg?.billingPlan === BillingPlan.PRO}
{:else if selectedOrgId} - +
+ + {#if campaign?.template === 'review' && (campaign?.data?.cta || campaign?.data?.claimed || campaign?.data?.unclaimed)} +
+

{campaign?.data?.cta}

+

+ {#if couponData?.code && couponData?.status === 'active' && campaign?.data?.claimed} + {campaign?.data?.claimed} + {:else if campaign?.data?.unclaimed} + {campaign?.data?.unclaimed} + {/if} +

+
+ {/if} +
+
{/if} diff --git a/static/images/campaigns/StartupsProgram/reviewers/1.jpeg b/static/images/campaigns/StartupsProgram/reviewers/1.jpeg new file mode 100644 index 000000000..db56c928c Binary files /dev/null and b/static/images/campaigns/StartupsProgram/reviewers/1.jpeg differ