update form to use date picker and time input for start and end date time

master
TZGyn 1 year ago
parent b060007290
commit a4d3c33512
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -6,6 +6,19 @@
import { zod } from 'sveltekit-superforms/adapters' import { zod } from 'sveltekit-superforms/adapters'
import { formSchema, intervals } from './schema' import { formSchema, intervals } from './schema'
import { categories } from './schema' import { categories } from './schema'
import { CalendarIcon } from 'lucide-svelte'
import { Calendar } from '$lib/components/ui/calendar/index.js'
import * as Popover from '$lib/components/ui/popover/index.js'
import {
CalendarDate,
DateFormatter,
type DateValue,
getLocalTimeZone,
parseDate,
today,
} from '@internationalized/date'
import { cn } from '$lib/utils.js'
import { buttonVariants } from '$lib/components/ui/button'
let { data } = $props() let { data } = $props()
@ -14,16 +27,25 @@
resetForm: false, resetForm: false,
SPA: true, SPA: true,
validators: zod(formSchema), validators: zod(formSchema),
onUpdate: async ({ form }) => { onUpdated: async ({ form }) => {
if (!form.valid) return
console.log(form.data)
// Form validation // Form validation
const url = new URL(apiEndpoint) const url = new URL(apiEndpoint)
url.searchParams.set('symbol', form.data.symbol) url.searchParams.set('symbol', form.data.symbol)
url.searchParams.set('interval', form.data.interval) url.searchParams.set('interval', form.data.interval)
if (form.data.start)
url.searchParams.set('start', form.data.start.toString())
if (form.data.end) const start = new Date(
url.searchParams.set('end', form.data.end.toString()) form.data.start + ' ' + form.data.startTime + ':00',
)
url.searchParams.set('start', start.getTime().toString())
const end = new Date(
form.data.end + ' ' + form.data.endTime + ':00',
)
url.searchParams.set('end', end.getTime().toString())
if (form.data.limit) if (form.data.limit)
url.searchParams.set('limit', form.data.limit.toString()) url.searchParams.set('limit', form.data.limit.toString())
@ -36,10 +58,20 @@
const data = await response.json() const data = await response.json()
console.log(data.result.list) console.log(data.result.list)
let csvContent = let csvContent =
'data:text/csv;charset=utf-8,' + 'data:text/csv;charset=utf-8,' +
'startTime,openPrice,highPrice,lowPrice,closePrice,volume,turnover\n' + 'startTime,openPrice,highPrice,lowPrice,closePrice,volume,turnover\n' +
data.result.list.map((e: any) => e.join(',')).join('\n') data.result.list
.map((data: string[]) => {
let newData = data
newData[0] = new Date(parseInt(newData[0]))
.toLocaleString()
.replace(',', ' |')
return newData
})
.map((e: any) => e.join(','))
.join('\n')
var encodedUri = encodeURI(csvContent) var encodedUri = encodeURI(csvContent)
var link = document.createElement('a') var link = document.createElement('a')
@ -52,6 +84,20 @@
}) })
const { form: formData, enhance } = form const { form: formData, enhance } = form
const df = new DateFormatter('en-US', {
dateStyle: 'long',
})
let start = $state<DateValue | undefined>()
let end = $state<DateValue | undefined>()
$effect(() => {
start = $formData.start ? parseDate($formData.start) : undefined
end = $formData.end ? parseDate($formData.end) : undefined
})
let placeholder = $state<DateValue>(today(getLocalTimeZone()))
</script> </script>
<form method="POST" use:enhance> <form method="POST" use:enhance>
@ -122,27 +168,114 @@
<Form.Description>Category</Form.Description> <Form.Description>Category</Form.Description>
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Field {form} name="start"> <Form.Field {form} name="start" class="flex flex-col">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Start Date</Form.Label>
<Popover.Root>
<Popover.Trigger
{...props}
class={cn(
buttonVariants({ variant: 'outline' }),
'w-[280px] justify-start pl-4 text-left font-normal',
!start && 'text-muted-foreground',
)}>
{start
? df.format(start.toDate(getLocalTimeZone()))
: 'Pick a date'}
<CalendarIcon class="ml-auto size-4 opacity-50" />
</Popover.Trigger>
<Popover.Content class="w-auto p-0" side="top">
<Calendar
type="single"
value={start as DateValue}
bind:placeholder
minValue={new CalendarDate(1900, 1, 1)}
maxValue={today(getLocalTimeZone())}
calendarLabel="Date of birth"
onValueChange={(v) => {
if (v) {
$formData.start = v.toString()
} else {
$formData.start = ''
}
}} />
</Popover.Content>
</Popover.Root>
<Form.Description>
Your date of birth is used to calculator your age
</Form.Description>
<Form.FieldErrors />
<input hidden value={$formData.start} name={props.name} />
{/snippet}
</Form.Control>
</Form.Field>
<Form.Field {form} name="startTime">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label>Start</Form.Label> <Form.Label>Start Time</Form.Label>
<Input <Input
{...props} {...props}
bind:value={$formData.start} bind:value={$formData.startTime}
type="number" /> type="time" />
{/snippet} {/snippet}
</Form.Control> </Form.Control>
<Form.Description>Start</Form.Description> <Form.Description>Limit</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Field {form} name="end" class="flex flex-col">
<Form.Control>
{#snippet children({ props })}
<Form.Label>End Date</Form.Label>
<Popover.Root>
<Popover.Trigger
{...props}
class={cn(
buttonVariants({ variant: 'outline' }),
'w-[280px] justify-start pl-4 text-left font-normal',
!end && 'text-muted-foreground',
)}>
{end
? df.format(end.toDate(getLocalTimeZone()))
: 'Pick a date'}
<CalendarIcon class="ml-auto size-4 opacity-50" />
</Popover.Trigger>
<Popover.Content class="w-auto p-0" side="top">
<Calendar
type="single"
value={end as DateValue}
bind:placeholder
minValue={new CalendarDate(1900, 1, 1)}
maxValue={today(getLocalTimeZone())}
calendarLabel="Date of birth"
onValueChange={(v) => {
if (v) {
$formData.end = v.toString()
} else {
$formData.end = ''
}
}} />
</Popover.Content>
</Popover.Root>
<Form.Description>
Your date of birth is used to calculator your age
</Form.Description>
<Form.FieldErrors /> <Form.FieldErrors />
<input hidden value={$formData.end} name={props.name} />
{/snippet}
</Form.Control>
</Form.Field> </Form.Field>
<Form.Field {form} name="end"> <Form.Field {form} name="endTime">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label>End</Form.Label> <Form.Label>End Time</Form.Label>
<Input {...props} bind:value={$formData.end} type="number" /> <Input
{...props}
bind:value={$formData.endTime}
type="time" />
{/snippet} {/snippet}
</Form.Control> </Form.Control>
<Form.Description>End</Form.Description> <Form.Description>Limit</Form.Description>
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Button>Submit</Form.Button> <Form.Button>Submit</Form.Button>

@ -1,4 +1,3 @@
import type { DateValue } from '@internationalized/date'
import { z } from 'zod' import { z } from 'zod'
export type Category = 'spot' | 'linear' | 'inverse' export type Category = 'spot' | 'linear' | 'inverse'
@ -40,8 +39,10 @@ export const formSchema = z.object({
category: z.custom<Category>(), category: z.custom<Category>(),
symbol: z.string(), symbol: z.string(),
interval: z.custom<Interval>(), interval: z.custom<Interval>(),
start: z.number().min(0).optional(), start: z.string().min(1),
end: z.number().min(0).optional(), startTime: z.string().min(1),
end: z.string().min(1),
endTime: z.string().min(1),
limit: z.number().int().min(1).max(1000).optional(), limit: z.number().int().min(1).max(1000).optional(),
}) })

Loading…
Cancel
Save