In my Image generation page the generated image is not rendering inside the card , i have provided the ss of what exactly it is showing enter image description here The error in the console says missing src property but in my code src is initiated at 166 here is the code for page.tsx
"use client";
import * as z from "zod";
import { Heading } from "@/components/heading";
import { ImageIcon, Download } from 'lucide-react';
import { useForm } from "react-hook-form";
import { amountOptions, formSchema, resolutionOptions } from "./constants";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import axios from "axios";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { Empty } from "@/components/empty";
import { Loader } from "@/components/loader";
import { Select, SelectItem, SelectValue } from "@/components/ui/select";
import { SelectTrigger, SelectContent } from '@radix-ui/react-select';
import { Card, CardFooter } from '@/components/ui/card';
import Image from "next/image";
const ImagePage = () => {
const router = useRouter();
const [images, setImages] = useState<string[]>([]);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
prompt: "",
amount: "1",
resolution: "512x512"
}
});
const isLoading = form.formState.isSubmitting;
const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
setImages([]);
const response = await axios.post("/api/image", values );
const urls = response.data.map((image: {url: string }) => image.url)
setImages(urls);
form.reset();
} catch (error: any) {
console.log(error)
}
finally {
router.refresh();
}
};
return (
<div>
<Heading
title="Image Generation AI"
description="G.O.A.T AI can turn your prompt into Images"
icon={ImageIcon}
iconColor="text-pink-500"
bgColor="bg-pink-500/10"
/>
<div className="px-4 lg:px-8">
<div>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="rounded-lg border w-full p-4 px-3 md:px-6 focus-within:shadow-sm grid grid-cols-12 gap-2"
>
<FormField
name="prompt"
render={({ field }) => (
<FormItem className="col-span-12 lg:col-span-6">
<FormControl className="m-0 p-0">
<Input
className="border-0 outline-none focus-visible:ring-0 focus-visible:ring-transparent"
disabled={isLoading}
placeholder="A panda eating bamboo"
{...field}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="amount"
render={({ field }) => (
<FormItem className="col-span-12 lg:col-span-2">
<Select
disabled={isLoading}
onValueChange={field.onChange}
value={field.value}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue defaultValue={field.value}/>
</SelectTrigger>
</FormControl>
<SelectContent>
{amountOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
<FormField
control={form.control}
name="resolution"
render={({ field }) => (
<FormItem className="col-span-12 lg:col-span-2">
<Select
disabled={isLoading}
onValueChange={field.onChange}
value={field.value}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue defaultValue={field.value}/>
</SelectTrigger>
</FormControl>
<SelectContent>
{resolutionOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
<Button className="col-span-12 lg:col-span-2 w-full" disabled={isLoading}>
{isLoading ? "Generating..." : "Generate"}
</Button>
</form>
</Form>
</div>
<div className="space-y-4 mt-4">
{isLoading && (
<div className="p-20">
<Loader />
</div>
)}
{images.length === 0 && !isLoading && (
<Empty label="No images started"/>
)}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 mt-8">
{images.map((src) => (
<Card key={src} className="rounded-lg overflow-hidden">
<div className="relative aspect-square">
<Image alt="image" fill src={src}/>
</div>
<CardFooter className="p-2">
<Button
onClick={() => window.open(src)}
variant="secondary"
className="w-full">
<Download h-4 w-4 mr-2/>
Download
</Button>
</CardFooter>
</Card>
))}
</div>
</div>
</div>
</div>
);
};
export default ImagePage;
and this is the code for route.ts
import { NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import Replicate from "replicate";
const replicate = new Replicate ({
auth : process.env.REPLICATE_API_TOKEN
})
export async function POST(request: Request) {
try {
const { userId } = auth();
const body = await request.json();
const { prompt, amount = 1, resolution = "512x512" } = body;
if (!userId) {
return new NextResponse("Unauthorized", { status: 401 });
}
if (!amount) {
return new NextResponse("amount is required", { status: 401 });
}
if (!resolution) {
return new NextResponse("resolution is required", { status: 401 });
}
if (!prompt) {
return new NextResponse("Prompt is required", { status: 400 });
}
const input = {
prompt: prompt
};
const response = await replicate.run("bytedance/sdxl-lightning-4step:5f24084160c9089501c1b3545d9be3c27883ae2239b6f412990e82d4a6210f8f", { input });
return NextResponse.json(response);
} catch (error) {
console.log("[IMAGE_ERROR]", error);
return new NextResponse("Internal Error", { status: 500 });
}
}
I have tried chatGPT and many ai tools but was unable to solve the problem .