From d33aa0a874893d4246e61291674ac02f851752d0 Mon Sep 17 00:00:00 2001 From: Hemant Date: Mon, 31 Jul 2023 17:59:33 +0530 Subject: [PATCH] Added video generation successfully also --- app/(dashboard)/(routes)/video/constants.ts | 7 ++ app/(dashboard)/(routes)/video/page.tsx | 113 ++++++++++++++++++++ app/api/video/route.ts | 51 +++++++++ 3 files changed, 171 insertions(+) create mode 100644 app/(dashboard)/(routes)/video/constants.ts create mode 100644 app/(dashboard)/(routes)/video/page.tsx create mode 100644 app/api/video/route.ts diff --git a/app/(dashboard)/(routes)/video/constants.ts b/app/(dashboard)/(routes)/video/constants.ts new file mode 100644 index 0000000..d037863 --- /dev/null +++ b/app/(dashboard)/(routes)/video/constants.ts @@ -0,0 +1,7 @@ +import * as z from "zod"; + +export const formSchema = z.object({ + prompt: z.string().min(1, { + message: "Prompt is required." + }), +}); diff --git a/app/(dashboard)/(routes)/video/page.tsx b/app/(dashboard)/(routes)/video/page.tsx new file mode 100644 index 0000000..2729fa2 --- /dev/null +++ b/app/(dashboard)/(routes)/video/page.tsx @@ -0,0 +1,113 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import axios from "axios"; +import { VideoIcon } from "lucide-react"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "react-hot-toast"; +import * as z from "zod"; + +import { Heading } from "@/components/heading"; +import { Loader } from "@/components/loader"; +import { Button } from "@/components/ui/button"; +import { Empty } from "@/components/ui/empty"; +import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +// import { useProModal } from "@/hooks/use-pro-modal"; + +import { formSchema } from "./constants"; + +const VideoPage = () => { + const router = useRouter(); + // const proModal = useProModal(); + const [video, setVideo] = useState(); + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + prompt: "", + } + }); + + const isLoading = form.formState.isSubmitting; + + const onSubmit = async (values: z.infer) => { + try { + setVideo(undefined); + + const response = await axios.post('/api/video', values); + + setVideo(response.data[0]); + form.reset(); + } catch (error: any) { + if (error?.response?.status === 403) { + // proModal.onOpen(); + } else { + toast.error("Something went wrong."); + } + } finally { + router.refresh(); + } + } + + return ( +
+ + +
+
+ + ( + + + + + + )} + /> + + + + + {isLoading && ( +
+ +
+ )} + + {!video && !isLoading && ( + + )} + + {video && ( + + )} + +
+
+ ); +} + +export default VideoPage; diff --git a/app/api/video/route.ts b/app/api/video/route.ts new file mode 100644 index 0000000..dec2120 --- /dev/null +++ b/app/api/video/route.ts @@ -0,0 +1,51 @@ +import Replicate from "replicate"; +import { auth } from "@clerk/nextjs"; +import { NextResponse } from "next/server"; + +// import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit"; +// import { checkSubscription } from "@/lib/subscription"; + +const replicate = new Replicate({ + auth: process.env.REPLICATE_API_TOKEN!, +}); + +export async function POST(req: Request) { + try { + const { userId } = auth(); + const body = await req.json(); + const { prompt } = body; + + if (!userId) { + return new NextResponse("Unauthorized", { status: 401 }); + } + + if (!prompt) { + return new NextResponse("Prompt is required", { status: 400 }); + } + + // const freeTrial = await checkApiLimit(); + // const isPro = await checkSubscription(); + + // if (!freeTrial && !isPro) { + // return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 }); + // } + + const response = await replicate.run( + "anotherjesse/zeroscope-v2-xl:71996d331e8ede8ef7bd76eba9fae076d31792e4ddf4ad057779b443d6aea62f", + { + input: { + prompt, + } + } + ); + + // if (!isPro) { + // await incrementApiLimit(); + // } + + return NextResponse.json(response); + } catch (error) { + console.log('[VIDEO_ERROR]', error); + return new NextResponse("Internal Error", { status: 500 }); + } +};