Skip to content

Commit

Permalink
generate podcast feature
Browse files Browse the repository at this point in the history
  • Loading branch information
bahiensed committed Jul 25, 2024
1 parent ab25e30 commit 87793d3
Showing 1 changed file with 166 additions and 8 deletions.
174 changes: 166 additions & 8 deletions app/(root)/create-podcast/page.tsx
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;

0 comments on commit 87793d3

Please sign in to comment.