new captions system
This commit is contained in:
parent
6e826aad91
commit
b0587de3ba
51
src/lib/components/molecules/CustomDropdown.svelte
Normal file
51
src/lib/components/molecules/CustomDropdown.svelte
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<script>
|
||||||
|
/** @type {{value: string, name: string}[]} */
|
||||||
|
export let options;
|
||||||
|
/** @type {string} */
|
||||||
|
let value = '';
|
||||||
|
let open = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="w-full max-w-sm">
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
|
type="text"
|
||||||
|
id="combobox"
|
||||||
|
bind:value
|
||||||
|
on:focus={() => (open = true)}
|
||||||
|
on:blur={() => (open = false)}
|
||||||
|
/>
|
||||||
|
<button type="button" class="absolute inset-y-0 right-0 flex items-center pr-2">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-5 w-5 text-gray-400"
|
||||||
|
>
|
||||||
|
<path d="m6 9 6 6 6-6"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
{#if open}
|
||||||
|
<div
|
||||||
|
class="absolute z-50 min-w-[8rem] wßfull overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none"
|
||||||
|
>
|
||||||
|
{#each options as option}
|
||||||
|
<div
|
||||||
|
class="relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50"
|
||||||
|
>
|
||||||
|
<button on:click={() => (value = option.value)}>
|
||||||
|
{option.name}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,16 +1,19 @@
|
|||||||
<script>
|
<script>
|
||||||
import ProBadge from '$lib/components/molecules/probadge.svelte';
|
import ProBadge from '$lib/components/molecules/probadge.svelte';
|
||||||
|
import CustomDropdown from '$lib/components/molecules/CustomDropdown.svelte';
|
||||||
import { Button, buttonVariants } from '$lib/components/ui/button';
|
import { Button, buttonVariants } from '$lib/components/ui/button';
|
||||||
import * as Dialog from '$lib/components/ui/dialog';
|
import * as Dialog from '$lib/components/ui/dialog';
|
||||||
import * as Form from '$lib/components/ui/form';
|
import * as Form from '$lib/components/ui/form';
|
||||||
import * as Select from '$lib/components/ui/select';
|
import * as Select from '$lib/components/ui/select';
|
||||||
import { Switch } from '$lib/components/ui/switch';
|
import { Switch } from '$lib/components/ui/switch';
|
||||||
|
import { Input } from '$lib/components/ui/input';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { superForm } from 'sveltekit-superforms';
|
import { superForm } from 'sveltekit-superforms';
|
||||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||||
import { createFormSchema } from './schema';
|
import { createFormSchema } from './schema';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { Field } from 'formsnap';
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
export let videos;
|
export let videos;
|
||||||
export let tier;
|
export let tier;
|
||||||
@ -45,6 +48,9 @@
|
|||||||
// toast.error(msg);
|
// toast.error(msg);
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
$: {
|
||||||
|
console.log($formData.video_id);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Dialog.Root bind:open>
|
<Dialog.Root bind:open>
|
||||||
@ -65,39 +71,68 @@
|
|||||||
>
|
>
|
||||||
<Form.Field {form} name="video_id">
|
<Form.Field {form} name="video_id">
|
||||||
<Form.Control let:attrs>
|
<Form.Control let:attrs>
|
||||||
<div class="grid gap-4 mb-4">
|
<div class="mb-4 grid gap-4" style="margin-bottom: 0.5rem !important">
|
||||||
<div class="grid grid-cols-4 items-center gap-4">
|
<div class="grid grid-cols-4 items-center gap-4">
|
||||||
<Form.Label class="text-right">Youtube video*</Form.Label>
|
<Form.Label class="text-right">Youtube video link*</Form.Label>
|
||||||
<!-- <Input
|
<!-- <Input
|
||||||
id="youtube_url"
|
id="youtube_url"
|
||||||
placeholder="www.youtube.com/watch?v=..."
|
placeholder="www.youtube.com/watch?v=..."
|
||||||
class="col-span-3"
|
class="col-span-3"
|
||||||
/> -->
|
/> -->
|
||||||
<Select.Root>
|
<Select.Root>
|
||||||
<Select.Trigger class="w-[300px]">
|
<SelectPrimitive.Trigger
|
||||||
<Select.Value />
|
class={cn(
|
||||||
</Select.Trigger>
|
'col-span-2 flex h-10 w-[300px] items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1'
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
let:builder
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
asChild={true}
|
||||||
|
>
|
||||||
|
<!-- <div {...builder}>
|
||||||
|
<Input class="border-0 bg-transparent" />
|
||||||
|
</div> -->
|
||||||
|
<div {...builder} use:builder.action class="col-span-2 w-[300px]">
|
||||||
|
<SelectPrimitive.Value asChild={true}>
|
||||||
|
<Input
|
||||||
|
placeholder="Paste a video link or select a video"
|
||||||
|
class="col-span-2 w-[300px]"
|
||||||
|
bind:value={$formData.video_id}
|
||||||
|
{...attrs}
|
||||||
|
/>
|
||||||
|
</SelectPrimitive.Value>
|
||||||
|
</div>
|
||||||
|
</SelectPrimitive.Trigger>
|
||||||
|
|
||||||
<Select.Content>
|
<Select.Content>
|
||||||
<Select.Group>
|
<Select.Group>
|
||||||
{#each videos as video}
|
{#each videos as video}
|
||||||
<Select.Item
|
<Select.Item
|
||||||
|
on:click={() =>
|
||||||
|
($formData.video_id = 'https://youtu.be/' + video.snippet.resourceId.videoId)}
|
||||||
value={video.snippet.resourceId.videoId}
|
value={video.snippet.resourceId.videoId}
|
||||||
label={video.snippet.title}>{video.snippet.title}</Select.Item
|
label={video.snippet.title}
|
||||||
>
|
>{video.snippet.title}
|
||||||
|
</Select.Item>
|
||||||
{/each}
|
{/each}
|
||||||
</Select.Group>
|
</Select.Group>
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
<Select.Input bind:value={$formData.video_id} {...attrs} />
|
<Select.Input bind:value={$formData.video_id} {...attrs} />
|
||||||
</Select.Root>
|
</Select.Root>
|
||||||
|
<!-- <CustomDropdown options={videos.map((/** @type {any} */ x) => ({name: x.snippet.title,value: x.snippet.resourceId.videoId}))}/> -->
|
||||||
|
<!-- <CustomDropdown options={[{name: "my youtube video", value: "my"}]}/> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
<Form.Description />
|
<div class="grid grid-cols-4 items-center gap-4 mb" style="margin-top: 0.5rem !important">
|
||||||
<Form.FieldErrors />
|
<Form.FieldErrors class="col-start-2 mb-2" />
|
||||||
|
</div>
|
||||||
|
<!-- <Form.Description /> -->
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field {form} name="length">
|
<Form.Field {form} name="length">
|
||||||
<Form.Control let:attrs>
|
<Form.Control let:attrs>
|
||||||
<div class="grid gap-4 mb-4">
|
<div class="mb-4 grid gap-4">
|
||||||
<div class="grid grid-cols-4 items-center gap-4">
|
<div class="grid grid-cols-4 items-center gap-4">
|
||||||
<Form.Label class="text-right">Article length</Form.Label>
|
<Form.Label class="text-right">Article length</Form.Label>
|
||||||
<Select.Root portal={null} name="length">
|
<Select.Root portal={null} name="length">
|
||||||
@ -109,20 +144,15 @@
|
|||||||
<Select.Item value="700" label="Short (~700 words)"
|
<Select.Item value="700" label="Short (~700 words)"
|
||||||
>Short (~700 words)</Select.Item
|
>Short (~700 words)</Select.Item
|
||||||
>
|
>
|
||||||
<Select.Item
|
<Select.Item value="1500" label="Medium (~1500 words)"
|
||||||
value="1500"
|
|
||||||
label="Medium (~1500 words)"
|
|
||||||
>Medium (~1500 words)
|
>Medium (~1500 words)
|
||||||
<!-- <ProBadge /> -->
|
<!-- <ProBadge /> -->
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
<!-- disabled={['free', 'basic'].includes(tier)} -->
|
<!-- disabled={['free', 'basic'].includes(tier)} -->
|
||||||
<Select.Item
|
<Select.Item value="2500" label="Long (~2500 words)"
|
||||||
value="2500"
|
|
||||||
label="Long (~2500 words)"
|
|
||||||
>Long (~2500 words)
|
>Long (~2500 words)
|
||||||
<!-- <ProBadge /> -->
|
<!-- <ProBadge /> -->
|
||||||
</Select.Item
|
</Select.Item>
|
||||||
>
|
|
||||||
</Select.Group>
|
</Select.Group>
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
<Select.Input {...attrs} />
|
<Select.Input {...attrs} />
|
||||||
@ -133,7 +163,7 @@
|
|||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field {form} name="format">
|
<Form.Field {form} name="format">
|
||||||
<Form.Control let:attrs>
|
<Form.Control let:attrs>
|
||||||
<div class="grid gap-4 mb-4">
|
<div class="mb-4 grid gap-4">
|
||||||
<div class="grid grid-cols-4 items-center gap-4">
|
<div class="grid grid-cols-4 items-center gap-4">
|
||||||
<Form.Label class="text-right">Format</Form.Label>
|
<Form.Label class="text-right">Format</Form.Label>
|
||||||
<Select.Root portal={null} name="format">
|
<Select.Root portal={null} name="format">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const createFormSchema = z.object({
|
export const createFormSchema = z.object({
|
||||||
video_id: z.string(),
|
video_id: z.string().regex(/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/, "Invalid Youtube URL"),
|
||||||
// length: z.number().optional(),
|
// length: z.number().optional(),
|
||||||
// format: z.enum(["summary", "listicle", "product review", "news report", "tutorial"]).optional(),
|
// format: z.enum(["summary", "listicle", "product review", "news report", "tutorial"]).optional(),
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user