mirror of
https://github.com/nikdoof/pocket-id.git
synced 2025-12-14 07:12:19 +00:00
feat: add copy to clipboard option for OIDC client information
This commit is contained in:
41
frontend/src/lib/components/copy-to-clipboard.svelte
Normal file
41
frontend/src/lib/components/copy-to-clipboard.svelte
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||||
|
import { LucideCheck } from 'lucide-svelte';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
|
let { value, children }: { value: string; children: Snippet } = $props();
|
||||||
|
|
||||||
|
let open = $state(false);
|
||||||
|
let copied = $state(false);
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
open = true;
|
||||||
|
copyToClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOpenChange(state: boolean) {
|
||||||
|
open = state;
|
||||||
|
if (!state) {
|
||||||
|
copied = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipboard() {
|
||||||
|
navigator.clipboard.writeText(value);
|
||||||
|
copied = true;
|
||||||
|
setTimeout(() => onOpenChange(false), 1000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={onClick}>
|
||||||
|
<Tooltip.Root closeOnPointerDown={false} {onOpenChange} {open}>
|
||||||
|
<Tooltip.Trigger>{@render children()}</Tooltip.Trigger>
|
||||||
|
<Tooltip.Content onclick={copyToClipboard}>
|
||||||
|
{#if copied}
|
||||||
|
<span class="flex items-center"><LucideCheck class="mr-1 h-4 w-4" /> Copied</span>
|
||||||
|
{:else}
|
||||||
|
<span>Click to copy</span>
|
||||||
|
{/if}
|
||||||
|
</Tooltip.Content>
|
||||||
|
</Tooltip.Root>
|
||||||
|
</button>
|
||||||
15
frontend/src/lib/components/ui/tooltip/index.ts
Normal file
15
frontend/src/lib/components/ui/tooltip/index.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||||
|
import Content from "./tooltip-content.svelte";
|
||||||
|
|
||||||
|
const Root = TooltipPrimitive.Root;
|
||||||
|
const Trigger = TooltipPrimitive.Trigger;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Trigger,
|
||||||
|
Content,
|
||||||
|
//
|
||||||
|
Root as Tooltip,
|
||||||
|
Content as TooltipContent,
|
||||||
|
Trigger as TooltipTrigger,
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||||
|
import { cn, flyAndScale } from "$lib/utils/style.js";
|
||||||
|
|
||||||
|
type $$Props = TooltipPrimitive.ContentProps;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export let sideOffset: $$Props["sideOffset"] = 4;
|
||||||
|
export let transition: $$Props["transition"] = flyAndScale;
|
||||||
|
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||||
|
y: 8,
|
||||||
|
duration: 150,
|
||||||
|
};
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TooltipPrimitive.Content
|
||||||
|
{transition}
|
||||||
|
{transitionConfig}
|
||||||
|
{sideOffset}
|
||||||
|
class={cn(
|
||||||
|
"bg-popover text-popover-foreground z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</TooltipPrimitive.Content>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import { beforeNavigate } from '$app/navigation';
|
import { beforeNavigate } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { openConfirmDialog } from '$lib/components/confirm-dialog';
|
import { openConfirmDialog } from '$lib/components/confirm-dialog';
|
||||||
|
import CopyToClipboard from '$lib/components/copy-to-clipboard.svelte';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import Label from '$lib/components/ui/label/label.svelte';
|
import Label from '$lib/components/ui/label/label.svelte';
|
||||||
@@ -89,7 +90,9 @@
|
|||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="mb-2 flex">
|
<div class="mb-2 flex">
|
||||||
<Label class="mb-0 w-44">Client ID</Label>
|
<Label class="mb-0 w-44">Client ID</Label>
|
||||||
<span class="text-muted-foreground text-sm" data-testid="client-id"> {client.id}</span>
|
<CopyToClipboard value={client.id}>
|
||||||
|
<span class="text-muted-foreground text-sm" data-testid="client-id"> {client.id}</span>
|
||||||
|
</CopyToClipboard>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2 mt-1 flex items-center">
|
<div class="mb-2 mt-1 flex items-center">
|
||||||
<Label class="w-44">Client secret</Label>
|
<Label class="w-44">Client secret</Label>
|
||||||
@@ -111,7 +114,9 @@
|
|||||||
{#each Object.entries(setupDetails) as [key, value]}
|
{#each Object.entries(setupDetails) as [key, value]}
|
||||||
<div class="mb-5 flex">
|
<div class="mb-5 flex">
|
||||||
<Label class="mb-0 w-44">{key}</Label>
|
<Label class="mb-0 w-44">{key}</Label>
|
||||||
<span class="text-muted-foreground text-sm">{value}</span>
|
<CopyToClipboard {value}>
|
||||||
|
<span class="text-muted-foreground text-sm">{value}</span>
|
||||||
|
</CopyToClipboard>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user