mirror of
https://github.com/nikdoof/pocket-id.git
synced 2025-12-13 23:02:17 +00:00
feat: add warning if passkeys missing
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/style.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn("text-sm [&_p]:leading-relaxed", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
||||
21
frontend/src/lib/components/ui/alert/alert-title.svelte
Normal file
21
frontend/src/lib/components/ui/alert/alert-title.svelte
Normal file
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import type { HeadingLevel } from "./index.js";
|
||||
import { cn } from "$lib/utils/style.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
|
||||
level?: HeadingLevel;
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let level: $$Props["level"] = "h5";
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={level}
|
||||
class={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
17
frontend/src/lib/components/ui/alert/alert.svelte
Normal file
17
frontend/src/lib/components/ui/alert/alert.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { type Variant, alertVariants } from "./index.js";
|
||||
import { cn } from "$lib/utils/style.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement> & {
|
||||
variant?: Variant;
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let variant: $$Props["variant"] = "default";
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn(alertVariants({ variant }), className)} {...$$restProps} role="alert">
|
||||
<slot />
|
||||
</div>
|
||||
35
frontend/src/lib/components/ui/alert/index.ts
Normal file
35
frontend/src/lib/components/ui/alert/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { type VariantProps, tv } from 'tailwind-variants';
|
||||
|
||||
import Description from './alert-description.svelte';
|
||||
import Title from './alert-title.svelte';
|
||||
import Root from './alert.svelte';
|
||||
|
||||
export const alertVariants = tv({
|
||||
base: '[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4',
|
||||
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-background text-foreground',
|
||||
destructive:
|
||||
'border-destructive/50 text-destructive text-destructive dark:border-destructive [&>svg]:text-destructive',
|
||||
warning:
|
||||
'bg-amber-100 text-amber-900 dark:bg-amber-900 dark:text-amber-100 [&>svg]:text-amber-900 dark:[&>svg]:text-amber-100'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default'
|
||||
}
|
||||
});
|
||||
|
||||
export type Variant = VariantProps<typeof alertVariants>['variant'];
|
||||
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
||||
|
||||
export {
|
||||
//
|
||||
Root as Alert,
|
||||
Description as AlertDescription,
|
||||
Title as AlertTitle,
|
||||
Description,
|
||||
Root,
|
||||
Title
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import * as Alert from '$lib/components/ui/alert';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import UserService from '$lib/services/user-service';
|
||||
@@ -8,6 +9,7 @@
|
||||
import type { UserCreate } from '$lib/types/user.type';
|
||||
import { axiosErrorToast, getWebauthnErrorMessage } from '$lib/utils/error-util';
|
||||
import { startRegistration } from '@simplewebauthn/browser';
|
||||
import { LucideAlertTriangle } from 'lucide-svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import AccountForm from './account-form.svelte';
|
||||
import PasskeyList from './passkey-list.svelte';
|
||||
@@ -52,6 +54,16 @@
|
||||
<title>Account Settings</title>
|
||||
</svelte:head>
|
||||
|
||||
{#if passkeys.length == 0}
|
||||
<Alert.Root variant="warning">
|
||||
<LucideAlertTriangle class="size-4" />
|
||||
<Alert.Title>Passkey missing</Alert.Title>
|
||||
<Alert.Description
|
||||
>Please add a passkey to prevent losing access to your account.</Alert.Description
|
||||
>
|
||||
</Alert.Root>
|
||||
{/if}
|
||||
|
||||
{#if $appConfigStore.allowOwnAccountEdit}
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
@@ -77,7 +89,7 @@
|
||||
</Card.Header>
|
||||
{#if passkeys.length != 0}
|
||||
<Card.Content>
|
||||
<PasskeyList {passkeys} />
|
||||
<PasskeyList bind:passkeys />
|
||||
</Card.Content>
|
||||
{/if}
|
||||
</Card.Root>
|
||||
|
||||
@@ -9,15 +9,10 @@
|
||||
import { toast } from 'svelte-sonner';
|
||||
import RenamePasskeyModal from './rename-passkey-modal.svelte';
|
||||
|
||||
let { passkeys: initialsPasskeys }: { passkeys: Passkey[] } = $props();
|
||||
let passkeys = $state<Passkey[]>(initialsPasskeys);
|
||||
let { passkeys = $bindable() }: { passkeys: Passkey[] } = $props();
|
||||
|
||||
const webauthnService = new WebauthnService();
|
||||
|
||||
$effect(() => {
|
||||
passkeys = initialsPasskeys;
|
||||
});
|
||||
|
||||
let passkeyToRename: Passkey | null = $state(null);
|
||||
|
||||
async function deletePasskey(passkey: Passkey) {
|
||||
|
||||
Reference in New Issue
Block a user