Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
63 changes: 63 additions & 0 deletions src/lib/components/alerts/emailVerificationBanner.svelte
Comment thread
HarshMN2345 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts">
import { base } from '$app/paths';
import { goto } from '$app/navigation';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
import { Typography } from '@appwrite.io/pink-svelte';
import { hideNotification, shouldShowNotification } from '$lib/helpers/notifications';
import { user } from '$lib/stores/user';
import { wizard } from '$lib/stores/wizard';
import { page } from '$app/state';

const { emailBannerClosed, onEmailBannerClose } = $props<{
emailBannerClosed: boolean;
onEmailBannerClose: (closed: boolean) => void;
}>();

const isOnOnboarding = $derived(() => page.route?.id?.includes('/(console)/onboarding'));

const hasUser = $derived(!!$user);
const needsEmailVerification = $derived(hasUser && !$user.emailVerification);
const shouldShowNotificationBanner = $derived.by(() =>
shouldShowNotification('email-verification-banner')
);
const wizardNotActive = $derived(!$wizard.show && !$wizard.cover);
const bannerNotClosed = $derived(!emailBannerClosed);
const notOnOnboarding = $derived(!isOnOnboarding);

const shouldShowEmailBanner = $derived(
hasUser &&
needsEmailVerification &&
shouldShowNotificationBanner &&
wizardNotActive &&
bannerNotClosed &&
notOnOnboarding
);

function navigateToAccount() {
goto(`${base}/account`);
}

function handleDismiss() {
onEmailBannerClose(true);
hideNotification('email-verification-banner', { coolOffPeriod: 24 * 365 * 100 });
}
</script>

{#if shouldShowEmailBanner}
<HeaderAlert
type="warning"
title="Your email address needs to be verified"
Comment thread
Meldiron marked this conversation as resolved.
Comment thread
HarshMN2345 marked this conversation as resolved.
dismissible
on:dismiss={handleDismiss}>
<svelte:fragment>
To avoid losing access to your projects, make sure <Typography.Text
Comment thread
HarshMN2345 marked this conversation as resolved.
variant="m-500"
style="display:inline">{$user.email}</Typography.Text> is valid and up to date. Email
verification will be required soon.
</svelte:fragment>
<svelte:fragment slot="buttons">
<Button secondary size="s" on:click={navigateToAccount}>Update email address</Button>
</svelte:fragment>
</HeaderAlert>
{/if}
1 change: 1 addition & 0 deletions src/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,5 @@ export { default as UsageCard } from './usageCard.svelte';
export { default as ViewToggle } from './viewToggle.svelte';
export { default as RegionEndpoint } from './regionEndpoint.svelte';
export { default as ExpirationInput } from './expirationInput.svelte';
export { default as EmailVerificationBanner } from './alerts/emailVerificationBanner.svelte';
export { default as SortButton, type SortDirection } from './sortButton.svelte';
13 changes: 12 additions & 1 deletion src/lib/layout/headerAlert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { isTabletViewport } from '$lib/stores/viewport';
import { createEventDispatcher } from 'svelte';
import { Button } from '$lib/elements/forms';
import { Icon } from '@appwrite.io/pink-svelte';
import { IconX } from '@appwrite.io/pink-icons-svelte';

export let title: string;
export let type: 'info' | 'success' | 'warning' | 'error' | 'default' = 'info';
export let dismissible = false;

let container: HTMLElement | null = null;
const dispatch = createEventDispatcher();

function setNavigationHeight() {
const alertHeight = container ? container.getBoundingClientRect().height : 0;
Expand Down Expand Up @@ -75,9 +81,14 @@
<slot />
</p>
</div>
{#if $$slots.buttons}
{#if $$slots.buttons || dismissible}
<div class="alert-buttons u-flex u-gap-16 u-cross-child-center">
<slot name="buttons" />
{#if dismissible}
<Button text icon size="s" on:click={() => dispatch('dismiss')}>
<Icon icon={IconX} slot="start" size="s" />
</Button>
{/if}
</div>
{/if}
</div>
Expand Down
11 changes: 9 additions & 2 deletions src/routes/(console)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { BillingPlan, INTERVAL } from '$lib/constants';
import Footer from '$lib/layout/footer.svelte';
import Shell from '$lib/layout/shell.svelte';

import { app } from '$lib/stores/app';
import { database, checkForDatabaseBackupPolicies } from '$lib/stores/database';
import { newOrgModal, organization, type Organization } from '$lib/stores/organization';
Expand Down Expand Up @@ -39,11 +40,12 @@
import MobileSupportModal from './wizard/support/mobileSupportModal.svelte';
import { showSupportModal } from './wizard/support/store';
import { activeHeaderAlert, consoleVariables } from './store';

import { base } from '$app/paths';
import { headerAlert } from '$lib/stores/headerAlert';
import { UsageRates } from '$lib/components/billing';
import { base } from '$app/paths';
import { canSeeProjects } from '$lib/stores/roles';
import { BottomModalAlert } from '$lib/components';
import { BottomModalAlert, EmailVerificationBanner } from '$lib/components';
import {
IconAnnotation,
IconBookOpen,
Expand All @@ -57,6 +59,7 @@
import type { LayoutData } from './$types';

export let data: LayoutData;
let emailBannerClosed = false;

function kebabToSentenceCase(str: string) {
return str
Expand Down Expand Up @@ -344,6 +347,10 @@
<Footer slot="footer" />
</Shell>

<EmailVerificationBanner
{emailBannerClosed}
onEmailBannerClose={(closed) => (emailBannerClosed = closed)} />

{#if $wizard.show && $wizard.component}
<svelte:component this={$wizard.component} {...$wizard.props} />
{:else if $wizard.cover}
Expand Down