-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
166 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,171 @@ | ||
import React from 'react' | ||
"use client" | ||
|
||
import { zodResolver } from "@hookform/resolvers/zod" | ||
import { useForm } from "react-hook-form" | ||
import { z } from "zod" | ||
|
||
import { Button } from "@/components/ui/button" | ||
import { | ||
Form, | ||
FormControl, | ||
FormDescription, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage, | ||
} from "@/components/ui/form" | ||
import { Input } from "@/components/ui/input" | ||
import { Label } from "@/components/ui/label" | ||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" | ||
import { useState } from "react" | ||
import { Textarea } from "@/components/ui/textarea" | ||
import GeneratePodcast from "@/components/GeneratePodcast" | ||
import GenerateThumbnail from "@/components/GenerateThumbnail" | ||
import { Loader } from "lucide-react" | ||
import { Id } from "@/convex/_generated/dataModel" | ||
import { cn } from "@/lib/utils" | ||
|
||
const voiceCategories = ['alloy', 'shimmer', 'nova', 'echo', 'fable', 'onyx']; | ||
|
||
const formSchema = z.object({ | ||
podcastTitle: z.string().min(3, { | ||
message: "Title must be at least 3 characters.", | ||
}), | ||
podcastDescription: z.string().min(3, { | ||
message: "Description must be at least 3 characters.", | ||
}), | ||
}) | ||
|
||
const CreatPodcast = () => { | ||
const [imagePrompt, setImagePrompt] = useState(''); | ||
const [imageStorageId, setImageStorageId] = useState<Id<"_storage"> | null>(null) | ||
const [imageUrl, setImageUrl] = useState(''); | ||
|
||
const [audioUrl, setAudioUrl] = useState(''); | ||
const [audioStorageId, setAudioStorageId] = useState<Id<"_storage"> | null>(null) | ||
const [audioDuration, setAudioDuration] = useState(0); | ||
|
||
const [voiceType, setVoiceType] = useState<string | null>(null); | ||
const [voicePrompt, setVoicePrompt] = useState(''); | ||
|
||
const [isSubmitting, setIsSubmitting] = useState(false); | ||
|
||
//define form | ||
const form = useForm<z.infer<typeof formSchema>>({ | ||
resolver: zodResolver(formSchema), | ||
defaultValues: { | ||
podcastTitle: "", | ||
podcastDescription: "", | ||
}, | ||
}) | ||
|
||
//define submit handler | ||
function onSubmit(values: z.infer<typeof formSchema>) { | ||
console.log(values) | ||
} | ||
|
||
const CreatePodcast = () => { | ||
return ( | ||
<div> | ||
<section className='flex flex-col gap-5'> | ||
<h1 className='font-bold text-20 text-white-1'>Create Podcast</h1> | ||
</section> | ||
</div> | ||
<> | ||
<section className="flex flex-col mt-10"> | ||
<h1 className='font-bold text-20 text-white-1'>Create Podcast</h1> | ||
</section> | ||
|
||
<Form {...form}> | ||
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col mt-12 w-full"> | ||
<div className="flex flex-col gap-[30px] border-b border-black-5 pb-10"> | ||
<FormField | ||
control={form.control} | ||
name="podcastTitle" | ||
render={({ field }) => ( | ||
<FormItem className="flex flex-col gap-2.5"> | ||
<FormLabel className="text-16 font-bold text-white-1">Title</FormLabel> | ||
<FormControl> | ||
<Input className="input-class focus-visible:ring-offset-orange-1" placeholder="Title of your spechful podcast" {...field} /> | ||
</FormControl> | ||
<FormMessage className="text-white-1" /> | ||
</FormItem> | ||
)} | ||
/> | ||
|
||
<div className="flex flex-col gap-2.5"> | ||
<Label className="text-16 font-bold text-white-1"> | ||
Select AI Voice | ||
</Label> | ||
|
||
<Select onValueChange={(value) => setVoiceType(value)}> | ||
<SelectTrigger className={cn('text-16 w-full border-none bg-black-1 text-gray-1 focus-visible:ring-offset-orange-1')}> | ||
<SelectValue placeholder="Select AI Voice" className="placeholder:text-gray-1 " /> | ||
</SelectTrigger> | ||
<SelectContent className="text-16 border-none bg-black-1 font-bold text-white-1 focus:ring-orange-1"> | ||
{voiceCategories.map((category) => ( | ||
<SelectItem key={category} value={category} className="capitalize focus:bg-orange-1"> | ||
{category} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
{voiceType && ( | ||
<audio | ||
src={`/${voiceType}.mp3`} | ||
autoPlay | ||
className="hidden" | ||
/> | ||
)} | ||
</Select> | ||
</div> | ||
|
||
<FormField | ||
control={form.control} | ||
name="podcastDescription" | ||
render={({ field }) => ( | ||
<FormItem className="flex flex-col gap-2.5"> | ||
<FormLabel className="text-16 font-bold text-white-1">Description</FormLabel> | ||
<FormControl> | ||
<Textarea className="input-class focus-visible:ring-offset-orange-1" placeholder="Short description of your speechful podcast" {...field} /> | ||
</FormControl> | ||
<FormMessage className="text-white-1" /> | ||
</FormItem> | ||
)} | ||
/> | ||
</div> | ||
<div className="flex flex-col pt-10"> | ||
<GeneratePodcast | ||
setAudioStorageId={setAudioStorageId} | ||
setAudio={setAudioUrl} | ||
voiceType={voiceType!} | ||
audio={audioUrl} | ||
voicePrompt={voicePrompt} | ||
setVoicePrompt={setVoicePrompt} | ||
setAudioDuration={setAudioDuration} | ||
/> | ||
|
||
{/** | ||
<GenerateThumbnail | ||
setImage={setImageUrl} | ||
setImageStorageId={setImageStorageId} | ||
image={imageUrl} | ||
imagePrompt={imagePrompt} | ||
setImagePrompt={setImagePrompt} | ||
/> | ||
*/} | ||
<div className="mt-10 w-full"> | ||
<Button type="submit" className="text-16 w-full bg-orange-1 py-4 font-extrabold text-white-1 transition-all duration-500 hover:bg-black-1"> | ||
{isSubmitting ? ( | ||
<> | ||
Submitting | ||
<Loader size={20} className="animate-spin ml-2" /> | ||
</> | ||
) : ( | ||
'Publish Podcast' | ||
)} | ||
</Button> | ||
</div> | ||
</div> | ||
</form> | ||
</Form> | ||
|
||
|
||
</> | ||
) | ||
} | ||
|
||
export default CreatePodcast | ||
export default CreatPodcast; |