mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #2237 from appwrite/feat-SER-165-Show-Banner-if-Unverified
feat: added dismissible prop to header alert and email verification b…
This commit is contained in:
@@ -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"
|
||||
dismissible
|
||||
on:dismiss={handleDismiss}>
|
||||
<svelte:fragment>
|
||||
To avoid losing access to your projects, make sure <Typography.Text
|
||||
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}
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
|
||||
@@ -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';
|
||||
@@ -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,
|
||||
@@ -57,6 +59,7 @@
|
||||
import type { LayoutData } from './$types';
|
||||
|
||||
export let data: LayoutData;
|
||||
let emailBannerClosed = false;
|
||||
|
||||
function kebabToSentenceCase(str: string) {
|
||||
return str
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user