add bingx api

master
TZGyn 2 years ago
parent a4d3c33512
commit 0f4630a534
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

Binary file not shown.

@ -14,4 +14,4 @@
}, },
"typescript": true, "typescript": true,
"registry": "https://next.shadcn-svelte.com/registry" "registry": "https://next.shadcn-svelte.com/registry"
} }

@ -17,7 +17,7 @@
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"bits-ui": "^1.0.0-next.34", "bits-ui": "^1.0.0-next.64",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"formsnap": "^2.0.0-next.1", "formsnap": "^2.0.0-next.1",
"lucide-svelte": "^0.454.0", "lucide-svelte": "^0.454.0",
@ -36,6 +36,7 @@
"zod": "^3.23.8" "zod": "^3.23.8"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.7",
"mode-watcher": "^0.4.1" "mode-watcher": "^0.4.1"
} }
} }

@ -0,0 +1,16 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div bind:this={ref} class={cn("p-6", className)} {...restProps}>
{@render children?.()}
</div>

@ -0,0 +1,16 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
</script>
<p bind:this={ref} class={cn("text-muted-foreground text-sm", className)} {...restProps}>
{@render children?.()}
</p>

@ -0,0 +1,16 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div bind:this={ref} class={cn("flex items-center p-6 pt-0", className)} {...restProps}>
{@render children?.()}
</div>

@ -0,0 +1,16 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div bind:this={ref} class={cn("flex flex-col space-y-1.5 p-6 pb-0", className)} {...restProps}>
{@render children?.()}
</div>

@ -0,0 +1,25 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
level = 3,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
level?: 1 | 2 | 3 | 4 | 5 | 6;
} = $props();
</script>
<div
role="heading"
aria-level={level}
bind:this={ref}
class={cn("text-2xl font-semibold leading-none tracking-tight", className)}
{...restProps}
>
{@render children?.()}
</div>

@ -0,0 +1,20 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
class={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
{...restProps}
>
{@render children?.()}
</div>

@ -0,0 +1,22 @@
import Root from "./card.svelte";
import Content from "./card-content.svelte";
import Description from "./card-description.svelte";
import Footer from "./card-footer.svelte";
import Header from "./card-header.svelte";
import Title from "./card-title.svelte";
export {
Root,
Content,
Description,
Footer,
Header,
Title,
//
Root as Card,
Content as CardContent,
Description as CardDescription,
Footer as CardFooter,
Header as CardHeader,
Title as CardTitle,
};

@ -0,0 +1,10 @@
import Scrollbar from "./scroll-area-scrollbar.svelte";
import Root from "./scroll-area.svelte";
export {
Root,
Scrollbar,
//,
Root as ScrollArea,
Scrollbar as ScrollAreaScrollbar,
};

@ -0,0 +1,29 @@
<script lang="ts">
import { ScrollArea as ScrollAreaPrimitive, type WithoutChild } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
orientation = "vertical",
children,
...restProps
}: WithoutChild<ScrollAreaPrimitive.ScrollbarProps> = $props();
</script>
<ScrollAreaPrimitive.Scrollbar
bind:ref
{orientation}
class={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-px",
orientation === "horizontal" && "h-2.5 w-full border-t border-t-transparent p-px",
className
)}
{...restProps}
>
{@render children?.()}
<ScrollAreaPrimitive.Thumb
class={cn("bg-border relative rounded-full", orientation === "vertical" && "flex-1")}
/>
</ScrollAreaPrimitive.Scrollbar>

@ -0,0 +1,32 @@
<script lang="ts">
import { ScrollArea as ScrollAreaPrimitive, type WithoutChild } from "bits-ui";
import { Scrollbar } from "./index.js";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
orientation = "vertical",
scrollbarXClasses = "",
scrollbarYClasses = "",
children,
...restProps
}: WithoutChild<ScrollAreaPrimitive.RootProps> & {
orientation?: "vertical" | "horizontal" | "both" | undefined;
scrollbarXClasses?: string | undefined;
scrollbarYClasses?: string | undefined;
} = $props();
</script>
<ScrollAreaPrimitive.Root bind:ref {...restProps} class={cn("relative overflow-hidden", className)}>
<ScrollAreaPrimitive.Viewport class="h-full w-full rounded-[inherit]">
{@render children?.()}
</ScrollAreaPrimitive.Viewport>
{#if orientation === "vertical" || orientation === "both"}
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
{/if}
{#if orientation === "horizontal" || orientation === "both"}
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
{/if}
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>

@ -0,0 +1,18 @@
import { Tabs as TabsPrimitive } from "bits-ui";
import Content from "./tabs-content.svelte";
import List from "./tabs-list.svelte";
import Trigger from "./tabs-trigger.svelte";
const Root = TabsPrimitive.Root;
export {
Root,
Content,
List,
Trigger,
//
Root as Tabs,
Content as TabsContent,
List as TabsList,
Trigger as TabsTrigger,
};

@ -0,0 +1,19 @@
<script lang="ts">
import { Tabs as TabsPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: TabsPrimitive.ContentProps = $props();
</script>
<TabsPrimitive.Content
bind:ref
class={cn(
"ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
className
)}
{...restProps}
/>

@ -0,0 +1,19 @@
<script lang="ts">
import { Tabs as TabsPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: TabsPrimitive.ListProps = $props();
</script>
<TabsPrimitive.List
bind:ref
class={cn(
"bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",
className
)}
{...restProps}
/>

@ -0,0 +1,19 @@
<script lang="ts">
import { Tabs as TabsPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: TabsPrimitive.TriggerProps = $props();
</script>
<TabsPrimitive.Trigger
bind:ref
class={cn(
"ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",
className
)}
{...restProps}
/>

@ -0,0 +1,289 @@
<script lang="ts">
import * as Form from '$lib/components/ui/form'
import * as Select from '$lib/components/ui/select'
import { Input } from '$lib/components/ui/input'
import { defaults, superForm } from 'sveltekit-superforms'
import { zod } from 'sveltekit-superforms/adapters'
import { bingxAPISchema, intervals } 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'
import axios from 'axios'
const apiEndpoint =
'https://open-api.bingx.io/openApi/swap/v3/quote/klines'
const form = superForm(
defaults(zod(bingxAPISchema), {
defaults: {
limit: 500,
symbol: 'BTC-USDT',
interval: '1h',
start: '2024-11-15',
startTime: '00:00',
end: '2024-11-15',
endTime: '00:00',
},
}),
{
resetForm: false,
SPA: true,
validators: zod(bingxAPISchema),
onUpdated: async ({ form }) => {
if (!form.valid) return
console.log(form.data)
// Form validation
const url = new URL(apiEndpoint)
url.searchParams.set('symbol', form.data.symbol)
url.searchParams.set('interval', form.data.interval)
const start = new Date(
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)
url.searchParams.set('limit', form.data.limit.toString())
url.searchParams.set(
'timestamp',
new Date().getTime().toString(),
)
const response = await fetch('/api/bingx', {
method: 'POST',
body: JSON.stringify({ url }),
})
const data = await response.json()
const list = data.data as {
open: string
close: string
high: string
low: string
volume: string
time: number
}[]
let csvContent =
'data:text/csv;charset=utf-8,' +
'openPrice,closePrice,highPrice,lowPrice,volume,startTime\n' +
list
.map((data) => {
let newData = []
newData.push(data.open)
newData.push(data.close)
newData.push(data.high)
newData.push(data.low)
newData.push(data.volume)
newData.push(
new Date(data.time)
.toLocaleString()
.replace(',', ' |'),
)
return newData
})
.map((e: any) => e.join(','))
.join('\n')
var encodedUri = encodeURI(csvContent)
var link = document.createElement('a')
link.setAttribute('href', encodedUri)
link.setAttribute('download', 'data.csv')
document.body.appendChild(link)
link.click()
},
},
)
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>
<form method="POST" use:enhance>
<Form.Field {form} name="symbol">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Symbol</Form.Label>
<Input {...props} bind:value={$formData.symbol} />
{/snippet}
</Form.Control>
<Form.Description>Symbol</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Field {form} name="limit">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Limit</Form.Label>
<Input
{...props}
bind:value={$formData.limit}
type="number" />
{/snippet}
</Form.Control>
<Form.Description>Limit</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Field {form} name="interval">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Interval</Form.Label>
<Select.Root
type="single"
bind:value={$formData.interval}
name={props.name}>
<Select.Trigger {...props}>
{$formData.interval ?? 'Select a interval'}
</Select.Trigger>
<Select.Content>
{#each intervals as interval}
<Select.Item value={interval} label={interval} />
{/each}
</Select.Content>
</Select.Root>
{/snippet}
</Form.Control>
<Form.Description>Interval</Form.Description>
<Form.FieldErrors />
</Form.Field>
<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>Start Date</Form.Description>
<Form.FieldErrors />
<input hidden value={$formData.start} name={props.name} />
{/snippet}
</Form.Control>
</Form.Field>
<Form.Field {form} name="startTime">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Start Time</Form.Label>
<Input
{...props}
bind:value={$formData.startTime}
type="time" />
{/snippet}
</Form.Control>
<Form.Description>Start Time</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>End Date</Form.Description>
<Form.FieldErrors />
<input hidden value={$formData.end} name={props.name} />
{/snippet}
</Form.Control>
</Form.Field>
<Form.Field {form} name="endTime">
<Form.Control>
{#snippet children({ props })}
<Form.Label>End Time</Form.Label>
<Input
{...props}
bind:value={$formData.endTime}
type="time" />
{/snippet}
</Form.Control>
<Form.Description>End Time</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Button>Submit</Form.Button>
</form>

@ -0,0 +1,46 @@
import { z } from 'zod'
export type Interval =
| '1m'
| '3m'
| '5m'
| '15m'
| '30m'
| '1h'
| '2h'
| '4h'
| '6h'
| '8h'
| '12h'
| '1d'
| '3d'
| '1w'
| '1M'
export const intervals: Interval[] = [
'1m',
'3m',
'5m',
'15m',
'30m',
'1h',
'2h',
'4h',
'6h',
'8h',
'12h',
'1d',
'3d',
'1w',
'1M',
]
export const bingxAPISchema = z.object({
symbol: z.string(),
interval: z.custom<Interval>(),
start: z.string().min(1),
startTime: z.string().min(1),
end: z.string().min(1),
endTime: z.string().min(1),
limit: z.number().int().min(1).max(1000).optional(),
})

@ -9,6 +9,8 @@
import { CalendarIcon } from 'lucide-svelte' import { CalendarIcon } from 'lucide-svelte'
import { Calendar } from '$lib/components/ui/calendar/index.js' import { Calendar } from '$lib/components/ui/calendar/index.js'
import * as Popover from '$lib/components/ui/popover/index.js' import * as Popover from '$lib/components/ui/popover/index.js'
import * as Card from '$lib/components/ui/card/index.js'
import * as Tabs from '$lib/components/ui/tabs/index.js'
import { import {
CalendarDate, CalendarDate,
DateFormatter, DateFormatter,
@ -19,6 +21,8 @@
} from '@internationalized/date' } from '@internationalized/date'
import { cn } from '$lib/utils.js' import { cn } from '$lib/utils.js'
import { buttonVariants } from '$lib/components/ui/button' import { buttonVariants } from '$lib/components/ui/button'
import Bingx from './(components)/bingx.svelte'
import { ScrollArea } from '$lib/components/ui/scroll-area'
let { data } = $props() let { data } = $props()
@ -100,183 +104,208 @@
let placeholder = $state<DateValue>(today(getLocalTimeZone())) let placeholder = $state<DateValue>(today(getLocalTimeZone()))
</script> </script>
<form method="POST" use:enhance> <div class="flex justify-center">
<Form.Field {form} name="symbol"> <Card.Root>
<Form.Control> <Card.Content>
{#snippet children({ props })} <Tabs.Root value="bybit" class="w-[400px]">
<Form.Label>Symbol</Form.Label> <Tabs.List>
<Input {...props} bind:value={$formData.symbol} /> <Tabs.Trigger value="bybit">ByBit</Tabs.Trigger>
{/snippet} <Tabs.Trigger value="bingx">BingX</Tabs.Trigger>
</Form.Control> </Tabs.List>
<Form.Description>Symbol</Form.Description> <Tabs.Content value="bybit">
<Form.FieldErrors /> <form method="POST" use:enhance>
</Form.Field> <Form.Field {form} name="symbol">
<Form.Field {form} name="limit"> <Form.Control>
<Form.Control> {#snippet children({ props })}
{#snippet children({ props })} <Form.Label>Symbol</Form.Label>
<Form.Label>Limit</Form.Label> <Input {...props} bind:value={$formData.symbol} />
<Input {/snippet}
{...props} </Form.Control>
bind:value={$formData.limit} <Form.Description>Symbol</Form.Description>
type="number" /> <Form.FieldErrors />
{/snippet} </Form.Field>
</Form.Control> <Form.Field {form} name="limit">
<Form.Description>Limit</Form.Description> <Form.Control>
<Form.FieldErrors /> {#snippet children({ props })}
</Form.Field> <Form.Label>Limit</Form.Label>
<Form.Field {form} name="category"> <Input
<Form.Control> {...props}
{#snippet children({ props })} bind:value={$formData.limit}
<Form.Label>Category</Form.Label> type="number" />
<Select.Root {/snippet}
type="single" </Form.Control>
bind:value={$formData.category} <Form.Description>Limit</Form.Description>
name={props.name}> <Form.FieldErrors />
<Select.Trigger {...props}> </Form.Field>
{$formData.category ?? 'Select a category'} <Form.Field {form} name="category">
</Select.Trigger> <Form.Control>
<Select.Content> {#snippet children({ props })}
{#each categories as category} <Form.Label>Category</Form.Label>
<Select.Item value={category} label={category} /> <Select.Root
{/each} type="single"
</Select.Content> bind:value={$formData.category}
</Select.Root> name={props.name}>
{/snippet} <Select.Trigger {...props}>
</Form.Control> {$formData.category ?? 'Select a category'}
<Form.Description>Category</Form.Description> </Select.Trigger>
<Form.FieldErrors /> <Select.Content>
</Form.Field> {#each categories as category}
<Form.Field {form} name="interval"> <Select.Item
<Form.Control> value={category}
{#snippet children({ props })} label={category} />
<Form.Label>Interval</Form.Label> {/each}
<Select.Root </Select.Content>
type="single" </Select.Root>
bind:value={$formData.interval} {/snippet}
name={props.name}> </Form.Control>
<Select.Trigger {...props}> <Form.Description>Category</Form.Description>
{$formData.interval ?? 'Select a interval'} <Form.FieldErrors />
</Select.Trigger> </Form.Field>
<Select.Content> <Form.Field {form} name="interval">
{#each intervals as interval} <Form.Control>
<Select.Item value={interval} label={interval} /> {#snippet children({ props })}
{/each} <Form.Label>Interval</Form.Label>
</Select.Content> <Select.Root
</Select.Root> type="single"
{/snippet} bind:value={$formData.interval}
</Form.Control> name={props.name}>
<Form.Description>Category</Form.Description> <Select.Trigger {...props}>
<Form.FieldErrors /> {$formData.interval ?? 'Select a interval'}
</Form.Field> </Select.Trigger>
<Form.Field {form} name="start" class="flex flex-col"> <Select.Content>
<Form.Control> {#each intervals as interval}
{#snippet children({ props })} <Select.Item
<Form.Label>Start Date</Form.Label> value={interval}
<Popover.Root> label={interval} />
<Popover.Trigger {/each}
{...props} </Select.Content>
class={cn( </Select.Root>
buttonVariants({ variant: 'outline' }), {/snippet}
'w-[280px] justify-start pl-4 text-left font-normal', </Form.Control>
!start && 'text-muted-foreground', <Form.Description>Interval</Form.Description>
)}> <Form.FieldErrors />
{start </Form.Field>
? df.format(start.toDate(getLocalTimeZone())) <Form.Field {form} name="start" class="flex flex-col">
: 'Pick a date'} <Form.Control>
<CalendarIcon class="ml-auto size-4 opacity-50" /> {#snippet children({ props })}
</Popover.Trigger> <Form.Label>Start Date</Form.Label>
<Popover.Content class="w-auto p-0" side="top"> <Popover.Root>
<Calendar <Popover.Trigger
type="single" {...props}
value={start as DateValue} class={cn(
bind:placeholder buttonVariants({ variant: 'outline' }),
minValue={new CalendarDate(1900, 1, 1)} 'w-[280px] justify-start pl-4 text-left font-normal',
maxValue={today(getLocalTimeZone())} !start && 'text-muted-foreground',
calendarLabel="Date of birth" )}>
onValueChange={(v) => { {start
if (v) { ? df.format(start.toDate(getLocalTimeZone()))
$formData.start = v.toString() : 'Pick a date'}
} else { <CalendarIcon
$formData.start = '' class="ml-auto size-4 opacity-50" />
} </Popover.Trigger>
}} /> <Popover.Content class="w-auto p-0" side="top">
</Popover.Content> <Calendar
</Popover.Root> type="single"
<Form.Description> value={start as DateValue}
Your date of birth is used to calculator your age bind:placeholder
</Form.Description> minValue={new CalendarDate(1900, 1, 1)}
<Form.FieldErrors /> maxValue={today(getLocalTimeZone())}
<input hidden value={$formData.start} name={props.name} /> calendarLabel="Date of birth"
{/snippet} onValueChange={(v) => {
</Form.Control> if (v) {
</Form.Field> $formData.start = v.toString()
<Form.Field {form} name="startTime"> } else {
<Form.Control> $formData.start = ''
{#snippet children({ props })} }
<Form.Label>Start Time</Form.Label> }} />
<Input </Popover.Content>
{...props} </Popover.Root>
bind:value={$formData.startTime} <Form.Description>Start Time</Form.Description>
type="time" /> <Form.FieldErrors />
{/snippet} <input
</Form.Control> hidden
<Form.Description>Limit</Form.Description> value={$formData.start}
<Form.FieldErrors /> name={props.name} />
</Form.Field> {/snippet}
<Form.Field {form} name="end" class="flex flex-col"> </Form.Control>
<Form.Control> </Form.Field>
{#snippet children({ props })} <Form.Field {form} name="startTime">
<Form.Label>End Date</Form.Label> <Form.Control>
<Popover.Root> {#snippet children({ props })}
<Popover.Trigger <Form.Label>Start Time</Form.Label>
{...props} <Input
class={cn( {...props}
buttonVariants({ variant: 'outline' }), bind:value={$formData.startTime}
'w-[280px] justify-start pl-4 text-left font-normal', type="time" />
!end && 'text-muted-foreground', {/snippet}
)}> </Form.Control>
{end <Form.Description>Start Time</Form.Description>
? df.format(end.toDate(getLocalTimeZone())) <Form.FieldErrors />
: 'Pick a date'} </Form.Field>
<CalendarIcon class="ml-auto size-4 opacity-50" /> <Form.Field {form} name="end" class="flex flex-col">
</Popover.Trigger> <Form.Control>
<Popover.Content class="w-auto p-0" side="top"> {#snippet children({ props })}
<Calendar <Form.Label>End Date</Form.Label>
type="single" <Popover.Root>
value={end as DateValue} <Popover.Trigger
bind:placeholder {...props}
minValue={new CalendarDate(1900, 1, 1)} class={cn(
maxValue={today(getLocalTimeZone())} buttonVariants({ variant: 'outline' }),
calendarLabel="Date of birth" 'w-[280px] justify-start pl-4 text-left font-normal',
onValueChange={(v) => { !end && 'text-muted-foreground',
if (v) { )}>
$formData.end = v.toString() {end
} else { ? df.format(end.toDate(getLocalTimeZone()))
$formData.end = '' : 'Pick a date'}
} <CalendarIcon
}} /> class="ml-auto size-4 opacity-50" />
</Popover.Content> </Popover.Trigger>
</Popover.Root> <Popover.Content class="w-auto p-0" side="top">
<Form.Description> <Calendar
Your date of birth is used to calculator your age type="single"
</Form.Description> value={end as DateValue}
<Form.FieldErrors /> bind:placeholder
<input hidden value={$formData.end} name={props.name} /> minValue={new CalendarDate(1900, 1, 1)}
{/snippet} maxValue={today(getLocalTimeZone())}
</Form.Control> calendarLabel="Date of birth"
</Form.Field> onValueChange={(v) => {
<Form.Field {form} name="endTime"> if (v) {
<Form.Control> $formData.end = v.toString()
{#snippet children({ props })} } else {
<Form.Label>End Time</Form.Label> $formData.end = ''
<Input }
{...props} }} />
bind:value={$formData.endTime} </Popover.Content>
type="time" /> </Popover.Root>
{/snippet} <Form.Description>End Date</Form.Description>
</Form.Control> <Form.FieldErrors />
<Form.Description>Limit</Form.Description> <input
<Form.FieldErrors /> hidden
</Form.Field> value={$formData.end}
<Form.Button>Submit</Form.Button> name={props.name} />
</form> {/snippet}
</Form.Control>
</Form.Field>
<Form.Field {form} name="endTime">
<Form.Control>
{#snippet children({ props })}
<Form.Label>End Time</Form.Label>
<Input
{...props}
bind:value={$formData.endTime}
type="time" />
{/snippet}
</Form.Control>
<Form.Description>End Time</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Button>Submit</Form.Button>
</form>
</Tabs.Content>
<Tabs.Content value="bingx">
<Bingx />
</Tabs.Content>
</Tabs.Root>
</Card.Content>
</Card.Root>
</div>

@ -0,0 +1,10 @@
import { json } from '@sveltejs/kit'
import type { RequestHandler } from '../$types'
export const POST: RequestHandler = async ({ request }) => {
const body = await request.json()
const response = await fetch(body.url)
return json(await response.json())
}
Loading…
Cancel
Save