Epic Next JS 15 Tutorial Part 6: Create Video Summary with Next.js and Open AI
In this tutorial, we will continue building our Next.js app by adding a summary details page and handling update and delete operations for summaries. We will also discuss how to add policies in Strapi to ensure that users can only modify their content. First, let's create the SummaryDetails component inside the components/custom folder. This component will display the summary title, video URL, and summary text. It will also include a form for updating or deleting the summary. ```javascript import { useFormStatus } from "react-dom"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { TrashIcon, PencilIcon } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle, Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/card"; import ReactMarkdown from "react-markdown"; interface SummaryDetailsProps { item: any; } export function SummaryDetails({ item }: Readonly<SummaryDetailsProps>) { const status = useFormStatus(); return ( <Card className={cn("mb-8 relative h-auto")}> <CardHeader> <CardTitle>{item.title}</CardTitle> </CardHeader> <CardContent> <div> <form> <Input id="title" name="title" placeholder="Update your title" required className="mb-4" defaultValue={item.title} /> <Textarea name="summary" className="markdown-preview relative w-full h-[600px] overflow-auto scroll-smooth p-4 px-3 py-2 text-sm bg-white dark:bg-gray-800 bg-transparent border border-gray-300 dark:border-gray-700 rounded-md shadow-sm mb-4 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:bg-gray-50 focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" defaultValue={item.summary} /> </form> <input type="hidden" name="id" value={item.documentId} /> <SubmitButton text="Update Summary" loadingText="Updating Summary" /> </div> <form> <DeleteButton className="absolute right-4 top-4 bg-red-700 hover:bg-red-600"> <TrashIcon className="w-4 h-4" /> </DeleteButton> <UpdateButton className="absolute right-12 top-4 bg-blue-700 hover:bg-blue-600"> <PencilIcon className="w-4 h-4" /> </UpdateButton> </form> </CardContent> </Card> ); } ``` Next, let's create the UpdateSummaryForm component inside the components/custom folder. This component will handle updating summary data and display a success message after the update is successful. ```javascript import { useFormStatus } from "react-dom"; import { cn } from "@/lib/utils"; import { Input, Textarea } from "@/components/ui/input"; import { Card, CardContent, CardFooter, CardHeader, CardTitle, Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/card"; import ReactMarkdown from "react-markdown"; import { SubmitButton } from "@/components/custom/submit-button"; import { DeleteButton } from "@/components/custom/delete-button"; interface UpdateSummaryFormProps { item: any; } export function UpdateSummaryForm({ item }: Readonly<UpdateSummaryFormProps>) { const status = useFormStatus(); return ( <Card className={cn("mb-8 relative h-auto")}> <CardHeader> <CardTitle>Video Summary</CardTitle> </CardHeader> <CardContent> <div> <form> <Input id="title" name="title" placeholder="Update your title" required className="mb-4" defaultValue={item.title} /> <Textarea name="summary" className="markdown-preview relative w-full h-[600px] overflow-auto scroll-smooth p-4 px-3 py-2 text-sm bg-white dark:bg-gray-800 bg-transparent border border-gray-300 dark:border-gray-700 rounded-md shadow-sm mb-4 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:bg-gray-50 focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" defaultValue={item.summary} /> </form> <input type="hidden" name="id" value={item.documentId} /> <SubmitButton text="Update Summary" loadingText="Updating Summary" /> </div> </CardContent> </Card> ); } ``` Now, let's update our page.tsx file with the following code. This component will display the summary details and include a form for updating or deleting the summary. ```javascript import { getSummaryById } from "@/data/loaders"; import { SummaryDetails } from "@/components/custom/summary-details"; import { UpdateSummaryForm } from "@/components/custom/update-summary-form"; import { DeleteButton } from "@/components/custom/delete-button"; interface ParamsProps { params: { videoId: string; }; } export default async function SummaryPageRoute(props: Readonly<ParamsProps>) { const params = await props?.params; const { videoId } = params; const data = await getSummaryById(videoId); return ( <div className="flex flex-col"> <h1>Summary Page</h1> <hr /> <SummaryDetails item={data.data} /> <UpdateSummaryForm item={data.data} /> <DeleteButton className="absolute right-4 top-4 bg-red-700 hover:bg-red-600"> <TrashIcon className="w-4 h-4" /> </DeleteButton> </div> ); } ``` In this tutorial, we have created a summary details page and added forms for updating or deleting summaries. We also discussed how to add policies in Strapi to ensure that users can only modify their content. In the next post, we will explore adding authentication and user profiles to our Next.js app.
Company
Strapi
Date published
April 10, 2024
Author(s)
Paul Bratslavsky
Word count
7730
Language
English
Hacker News points
None found.