mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-23 01:11:49 +03:00
feat: api key authentication (#291)
Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
53
frontend/src/lib/components/form/date-picker.svelte
Normal file
53
frontend/src/lib/components/form/date-picker.svelte
Normal file
@@ -0,0 +1,53 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Calendar } from '$lib/components/ui/calendar';
|
||||
import * as Popover from '$lib/components/ui/popover';
|
||||
import { cn } from '$lib/utils/style';
|
||||
import {
|
||||
CalendarDate,
|
||||
DateFormatter,
|
||||
getLocalTimeZone,
|
||||
type DateValue
|
||||
} from '@internationalized/date';
|
||||
import CalendarIcon from 'lucide-svelte/icons/calendar';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
let { value = $bindable(), ...restProps }: HTMLAttributes<HTMLButtonElement> & { value: Date } =
|
||||
$props();
|
||||
|
||||
let date: CalendarDate = $state(dateToCalendarDate(value));
|
||||
let open = $state(false);
|
||||
|
||||
function dateToCalendarDate(date: Date) {
|
||||
return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
||||
}
|
||||
|
||||
function onValueChange(newDate?: DateValue) {
|
||||
if (!newDate) return;
|
||||
|
||||
value = newDate.toDate(getLocalTimeZone());
|
||||
date = newDate as CalendarDate;
|
||||
open = false;
|
||||
}
|
||||
|
||||
const df = new DateFormatter('en-US', {
|
||||
dateStyle: 'long'
|
||||
});
|
||||
</script>
|
||||
|
||||
<Popover.Root openFocus {open} onOpenChange={(o) => (open = o)}>
|
||||
<Popover.Trigger asChild let:builder>
|
||||
<Button
|
||||
{...restProps}
|
||||
variant="outline"
|
||||
class={cn('w-full justify-start text-left font-normal', !value && 'text-muted-foreground')}
|
||||
builders={[builder]}
|
||||
>
|
||||
<CalendarIcon class="mr-2 h-4 w-4" />
|
||||
{date ? df.format(date.toDate(getLocalTimeZone())) : 'Select a date'}
|
||||
</Button>
|
||||
</Popover.Trigger>
|
||||
<Popover.Content class="w-auto p-0" align="start">
|
||||
<Calendar bind:value={date} initialFocus {onValueChange} />
|
||||
</Popover.Content>
|
||||
</Popover.Root>
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import DatePicker from '$lib/components/form/date-picker.svelte';
|
||||
import { Input, type FormInputEvent } from '$lib/components/ui/input';
|
||||
import { Label } from '$lib/components/ui/label';
|
||||
import type { FormInput } from '$lib/utils/form-util';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { Input, type FormInputEvent } from '$lib/components/ui/input';
|
||||
|
||||
let {
|
||||
input = $bindable(),
|
||||
@@ -16,12 +17,12 @@
|
||||
onInput,
|
||||
...restProps
|
||||
}: HTMLAttributes<HTMLDivElement> & {
|
||||
input?: FormInput<string | boolean | number>;
|
||||
input?: FormInput<string | boolean | number | Date>;
|
||||
label?: string;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox';
|
||||
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox' | 'date';
|
||||
onInput?: (e: FormInputEvent) => void;
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
@@ -34,20 +35,24 @@
|
||||
<Label class="mb-0" for={id}>{label}</Label>
|
||||
{/if}
|
||||
{#if description}
|
||||
<p class="mt-1 text-xs text-muted-foreground">{description}</p>
|
||||
<p class="text-muted-foreground mt-1 text-xs">{description}</p>
|
||||
{/if}
|
||||
<div class={label || description ? 'mt-2' : ''}>
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{:else if input}
|
||||
<Input
|
||||
{id}
|
||||
{placeholder}
|
||||
{type}
|
||||
bind:value={input.value}
|
||||
{disabled}
|
||||
on:input={(e) => onInput?.(e)}
|
||||
/>
|
||||
{#if type === 'date'}
|
||||
<DatePicker {id} bind:value={input.value as Date} />
|
||||
{:else}
|
||||
<Input
|
||||
{id}
|
||||
{placeholder}
|
||||
{type}
|
||||
bind:value={input.value}
|
||||
{disabled}
|
||||
on:input={(e) => onInput?.(e)}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if input?.error}
|
||||
<p class="mt-1 text-sm text-red-500">{input.error}</p>
|
||||
|
||||
Reference in New Issue
Block a user