Compare commits

...

3 Commits

Author SHA1 Message Date
andrzej 45af32d091 extrapolate genre picker 2024-06-26 18:21:06 +02:00
andrzej 0c39838f6a add createStoryDialog 2024-06-26 18:19:09 +02:00
andrzej 788051fa10 extrapolate create function 2024-06-26 18:18:44 +02:00
7 changed files with 137 additions and 48 deletions

29
src/app/lib/create.ts Normal file
View File

@ -0,0 +1,29 @@
"use server"
import { Genre } from "@prisma/client"
import prisma from "./db"
import { revalidatePath } from "next/cache"
import { redirect } from "next/navigation"
export async function createStory(data) {
"use server"
const genresArray = data.genres.map((e: Genre) => { return { id: e } })
const res = await prisma.story.create({
data: {
title: data.title,
word_count: data.word_count,
}
})
console.log(res)
const genresRes = await prisma.story.update({
where: { id: res.id },
data: {
genres: { set: genresArray }
}
})
console.log(genresRes)
revalidatePath("/story")
redirect("/story")
}

30
src/app/story/create.tsx Normal file
View File

@ -0,0 +1,30 @@
"use client"
import { createStory } from "app/lib/create"
import { Dialog, DialogHeader, DialogTrigger, DialogContent, DialogClose, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { ComponentProps } from "react";
import { Genre } from "@prisma/client";
import StoryForm from "app/ui/forms/story";
export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & { genres: Array<Genre> }) {
console.log(genres)
return (
<Dialog>
<DialogTrigger asChild>
<Button>Create new Story</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>New story</DialogTitle>
<DialogDescription>Create an entry for a new story i.e. a thing you intend to submit for publication.</DialogDescription>
</DialogHeader>
<StoryForm createStory={createStory} genres={genres} />
</DialogContent>
</Dialog>
)
}

View File

@ -1,16 +1,29 @@
import { Story } from "@prisma/client";
import { DataTable } from "app/ui/tables/data-table";
import { columns } from "./columns";
import { getStoriesWithGenres } from "app/lib/get";
import { getGenres, getStoriesWithGenres, getPubsWithGenres } from "app/lib/get";
import { Genre } from "@prisma/client";
import CreateStoryDialog from "./create";
export type StoryWithGenres = Story & { genres: Array<Genre> }
export default async function Page() {
const stories: Array<StoryWithGenres> = await getStoriesWithGenres()
const genres = await getGenres()
const storiesWithGenres: Array<StoryWithGenres> = await getStoriesWithGenres()
const pubsWithGenres = await getPubsWithGenres()
return (
<div className="container mx-auto">
<DataTable columns={columns} data={stories} type="story" />
<DataTable columns={columns} data={storiesWithGenres} type="story">
<CreateStoryDialog genres={genres} />
</DataTable>
</div>
)
}

View File

@ -1,17 +0,0 @@
import { getGenres } from "app/lib/get"
import React from "react"
import { letterCase } from "app/lib/functions"
export default async function GenreCheckboxes() {
const genres = await getGenres()
const genreCheckboxes = genres.map(e => {
const label = letterCase(e.name)
return (<React.Fragment key={`fragment${e.name}`}>
<input type="checkbox" id={e.name} key={`genreCheckboxInput${e.id}`} />
<label htmlFor={e.name} key={`genreCheckboxLabel${e.id}`}>{label}</label>
</React.Fragment>
)
})
return <>{genreCheckboxes}</>
}

View File

@ -1 +0,0 @@

View File

@ -0,0 +1,62 @@
import { FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { cn } from "@/lib/utils"
import GenreCheckbox from "./genreCheckbox"
export default function GenrePicker({ genres, form }) {
return (
<FormField
control={form.control}
name="genres"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel className="h-5">Genres</FormLabel>
<Popover modal={true}>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"min-w-fit max-w-full w-fit pl-3 text-left font-normal flex-wrap gap-y-1 h-fit min-h-10",
!field.value && "text-muted-foreground"
)}
>
{field.value.length !== 0 ? (
field.value.map((e, i) => (<Badge>{genres.find(f => e === f.id).name}</Badge>))
) : (
<p>Select</p>
)}
</Button>
</PopoverTrigger>
<PopoverContent align="start">
{genres.map((item) => (
<FormField
key={item.id}
control={form.control}
name="genres"
render={({ field }) => {
return (
<GenreCheckbox field={field} item={item} />
)
}}
/>
))}
<Button variant="link" className="p-0" onClick={() => form.setValue("genres", [])}>Clear</Button>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
)
}

View File

@ -1,27 +0,0 @@
import { FormField, FormItem, FormLabel, FormControl } from "@/components/ui/form"
import { Popover, PopoverContent, PopoverTrigger } from "@radix-ui/react-popover"
import { Checkbox } from "@radix-ui/react-checkbox"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
export default function GenresTrigger({ value, genres }) {
return (
<>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"min-w-fit max-w-full w-fit pl-3 text-left font-normal flex-wrap gap-y-1 h-fit min-h-10",
!value && "text-muted-foreground"
)}
>
{value.length !== 0 ? (
value.map((e, i) => (<Badge>{genres.find(f => e === f.id).name}</Badge>))
) : (
<p>Select</p>
)}
</Button>
</PopoverTrigger>
</>
)
}