Skip to content

Commit 47ba549

Browse files
Merge pull request #1038 from appwrite/feat-gradient-alert-banner
feat: gradient alert banner
2 parents 231b8ce + 481443f commit 47ba549

15 files changed

+788
-636
lines changed

package-lock.json

+640-626
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
},
2121
"dependencies": {
2222
"@appwrite.io/console": "^0.6.2",
23-
"@appwrite.io/pink": "0.23.0",
24-
"@appwrite.io/pink-icons": "0.23.0",
23+
"@appwrite.io/pink": "0.25.0",
24+
"@appwrite.io/pink-icons": "0.25.0",
2525
"@popperjs/core": "^2.11.8",
2626
"@sentry/svelte": "^7.66.0",
2727
"@sentry/tracing": "^7.66.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script lang="ts">
2+
import { base } from '$app/paths';
3+
import { page } from '$app/stores';
4+
import { trackEvent } from '$lib/actions/analytics';
5+
import { BillingPlan } from '$lib/constants';
6+
import { Button } from '$lib/elements/forms';
7+
import { organization } from '$lib/stores/organization';
8+
import { activeHeaderAlert } from '$routes/console/store';
9+
import GradientBanner from '../gradientBanner.svelte';
10+
11+
let show = true;
12+
13+
function handleClose() {
14+
show = false;
15+
const now = new Date().getTime();
16+
localStorage.setItem($activeHeaderAlert.id, now.toString());
17+
trackEvent('close_upgrade_banner', {
18+
source: 'cloud_credits_banner',
19+
campaign: 'WelcomeManual'
20+
});
21+
}
22+
</script>
23+
24+
{#if show && $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && !$page.url.pathname.includes('/console/account')}
25+
<GradientBanner on:close={handleClose}>
26+
<div class="u-flex u-gap-24 u-main-center u-cross-center u-flex-vertical-mobile">
27+
<span class="body-text-1">Get $50 Cloud credits for Appwrite Pro.</span>
28+
<Button
29+
secondary
30+
fullWidthMobile
31+
class="u-line-height-1"
32+
href={`${base}/console/apply-credit?code=appw50&org=${$organization.$id}`}
33+
on:click={() => {
34+
trackEvent('click_credits_redeem', {
35+
from: 'button',
36+
source: 'cloud_credits_banner',
37+
campaign: 'WelcomeManual'
38+
});
39+
}}>
40+
Claim credits
41+
</Button>
42+
</div>
43+
</GradientBanner>
44+
{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
4+
const dispatch = createEventDispatcher();
5+
</script>
6+
7+
<div class="top-banner">
8+
<div class="top-banner-bg">
9+
<div class="top-banner-bg-1">
10+
<img src="/images/top-banner/bg-pink-desktop.svg" width="1283" height="1278" alt="" />
11+
</div>
12+
<div class="top-banner-bg-2">
13+
<img src="/images/top-banner/bg-mint-desktop.svg" width="1051" height="1271" alt="" />
14+
</div>
15+
</div>
16+
<div class="top-banner-content u-color-text-primary">
17+
<slot />
18+
</div>
19+
<button
20+
on:click|preventDefault={() => dispatch('close')}
21+
type="button"
22+
class="top-banner-button"
23+
aria-label="close upgrade message">
24+
<span class="icon-x" aria-hidden="true"></span>
25+
</button>
26+
</div>

src/lib/components/collapsibleItem.svelte

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@
5858
// TODO: remove once pink is updated
5959
.collapsible-item {
6060
.collapsible-wrapper.is-disabled {
61+
cursor: not-allowed;
62+
6163
&[open] .icon-cheveron-down {
6264
rotate: unset;
6365
}
64-
65-
cursor: not-allowed;
6666
* {
6767
cursor: not-allowed;
6868
}

src/lib/components/permissions/row.svelte

+5-5
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,6 @@
121121
--p-drop-bg-color: var(--color-neutral-105);
122122
--p-drop-border-color: var(--color-neutral-85);
123123
124-
body.theme-light & {
125-
--p-drop-bg-color: var(--color-neutral-0);
126-
--p-drop-border-color: var(--color-neutral-10);
127-
}
128-
129124
inset-inline-start: -0.625rem;
130125
inset-block-end: calc(100% + 0.625rem);
131126
background-color: hsl(var(--p-drop-bg-color));
@@ -138,6 +133,11 @@
138133
margin-inline: auto;
139134
line-height: 1.5;
140135
136+
body.theme-light & {
137+
--p-drop-bg-color: var(--color-neutral-0);
138+
--p-drop-border-color: var(--color-neutral-10);
139+
}
140+
141141
.tippy-content {
142142
padding: 1rem;
143143
}

src/lib/stores/billing.ts

+27
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ import PaymentMandate from '$lib/components/billing/alerts/paymentMandate.svelte
2727
import MissingPaymentMethod from '$lib/components/billing/alerts/missingPaymentMethod.svelte';
2828
import LimitReached from '$lib/components/billing/alerts/limitReached.svelte';
2929
import { trackEvent } from '$lib/actions/analytics';
30+
import newDevUpgradePro from '$lib/components/billing/alerts/newDevUpgradePro.svelte';
3031
import { last } from '$lib/helpers/array';
3132
import { sizeToBytes, type Size } from '$lib/helpers/sizeConvertion';
33+
import { user } from './user';
34+
import { browser } from '$app/environment';
3235

3336
export type Tier = 'tier-0' | 'tier-1' | 'tier-2';
3437

@@ -388,6 +391,30 @@ export async function checkForMissingPaymentMethod() {
388391
}
389392
}
390393

394+
// Display upgrade banner for new users after 1 week for 30 days
395+
export async function checkForNewDevUpgradePro(org: Organization) {
396+
if (org?.billingPlan !== BillingPlan.FREE || !browser) return;
397+
398+
const orgs = await sdk.forConsole.billing.listOrganization([
399+
Query.notEqual('billingPlan', BillingPlan.FREE)
400+
]);
401+
if (orgs?.total) return;
402+
403+
const now = new Date().getTime();
404+
const account = get(user);
405+
const accountCreated = new Date(account.$createdAt).getTime();
406+
if (now - accountCreated < 1000 * 60 * 60 * 24 * 7) return;
407+
const isDismissed = !!localStorage.getItem('newDevUpgradePro');
408+
if (isDismissed) return;
409+
if (now - accountCreated < 1000 * 60 * 60 * 24 * 37) {
410+
headerAlert.add({
411+
id: 'newDevUpgradePro',
412+
component: newDevUpgradePro,
413+
show: true,
414+
importance: 1
415+
});
416+
}
417+
}
391418
export const upgradeURL = derived(
392419
page,
393420
($page) => `${base}/console/organization-${$page.data?.organization?.$id}/change-plan`

src/routes/console/+layout.svelte

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
checkForMarkedForDeletion,
2323
checkForMandate,
2424
checkForMissingPaymentMethod,
25+
checkForNewDevUpgradePro,
2526
plansInfo
2627
} from '$lib/stores/billing';
2728
import { goto } from '$app/navigation';
@@ -266,10 +267,13 @@
266267
if (isCloud) {
267268
await checkForUsageLimit(org);
268269
checkForMarkedForDeletion(org);
270+
await checkForNewDevUpgradePro(org);
271+
269272
if (org?.billingPlan !== BillingPlan.FREE) {
270273
await paymentExpired(org);
271274
await checkPaymentAuthorizationRequired(org);
272275
await checkForMandate(org);
276+
273277
if ($plansInfo.get(org.billingPlan)?.trialDays) {
274278
calculateTrialDay(org);
275279
}

src/routes/console/apply-credit/+page.svelte

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/i;
3333
let previousPage: string = `${base}/console`;
3434
let showExitModal = false;
35+
let canSelectOrg = true;
3536
3637
afterNavigate(({ from }) => {
3738
if (from?.url?.pathname) {
@@ -75,6 +76,10 @@
7576
if (!$organizationList?.total || campaign?.onlyNewOrgs) {
7677
selectedOrgId = newOrgId;
7778
}
79+
if ($page.url.searchParams.has('org')) {
80+
selectedOrgId = $page.url.searchParams.get('org');
81+
canSelectOrg = false;
82+
}
7883
});
7984
8085
async function loadPaymentMethods() {
@@ -197,7 +202,7 @@
197202
<WizardSecondaryContent>
198203
<Form bind:this={formComponent} onSubmit={handleSubmit} bind:isSubmitting>
199204
<FormList>
200-
{#if $organizationList?.total && !campaign?.onlyNewOrgs}
205+
{#if $organizationList?.total && !campaign?.onlyNewOrgs && canSelectOrg}
201206
<InputSelect
202207
bind:value={selectedOrgId}
203208
label="Select organization"
988 KB
Loading
Loading
45.5 KB
Loading
858 KB
Loading
Loading
35.4 KB
Loading

0 commit comments

Comments
 (0)