tweak refresh/notifications
This commit is contained in:
parent
3998180830
commit
81b36d0c8c
BIN
prisma/dev.db
BIN
prisma/dev.db
Binary file not shown.
|
@ -33,7 +33,7 @@ export default function RootLayout({
|
||||||
>
|
>
|
||||||
<div id="layout-container" className="md:p-4 w-screen h-screen mt-2 md:mt-6 flex justify-center">
|
<div id="layout-container" className="md:p-4 w-screen h-screen mt-2 md:mt-6 flex justify-center">
|
||||||
<div className="w-full md:w-5/6 flex flex-col md:flex-row">
|
<div className="w-full md:w-5/6 flex flex-col md:flex-row">
|
||||||
<div id="sidebar" className=" flex flex-row md:flex-col w-full justify-between"> <header className="">
|
<div id="sidebar" className=" flex flex-row md:flex-col justify-between"> <header className="">
|
||||||
<h1 className="font-black text-4xl text-primary-foreground bg-primary antialiased w-full p-2 rounded-tl-3xl pl-6 pr-4 hidden md:block">SubMan</h1>
|
<h1 className="font-black text-4xl text-primary-foreground bg-primary antialiased w-full p-2 rounded-tl-3xl pl-6 pr-4 hidden md:block">SubMan</h1>
|
||||||
<p className="mt-2 mx-1 text-sm antialiased w-40 hidden md:block">The self-hosted literary submission tracker.</p>
|
<p className="mt-2 mx-1 text-sm antialiased w-40 hidden md:block">The self-hosted literary submission tracker.</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -7,26 +7,16 @@ import { z } from "zod"
|
||||||
import { storySchema } from "app/ui/forms/schemas"
|
import { storySchema } from "app/ui/forms/schemas"
|
||||||
import { pubSchema } from "app/ui/forms/schemas"
|
import { pubSchema } from "app/ui/forms/schemas"
|
||||||
import { subSchema } from "app/ui/forms/schemas"
|
import { subSchema } from "app/ui/forms/schemas"
|
||||||
|
import { prepGenreData, prepStoryData } from "./validate"
|
||||||
|
|
||||||
//TODO - data validation, error handling, unauthorized access handling
|
//TODO - data validation, error handling, unauthorized access handling
|
||||||
|
|
||||||
export async function createStory(data: Story & { genres: number[] }): Promise<Story | undefined> {
|
export async function createStory(data: Story & { genres: number[] }): Promise<Story | boolean | undefined> {
|
||||||
// will return undefined if middleware authorization fails
|
// will return undefined if middleware authorization fails
|
||||||
"use server"
|
"use server"
|
||||||
//Prepare data
|
|
||||||
const genresArray = data.genres.map((e) => { return { id: e } })
|
|
||||||
const storyData = {
|
|
||||||
title: data.title,
|
|
||||||
word_count: data.word_count,
|
|
||||||
}
|
|
||||||
//prepare schemas
|
|
||||||
const schema = storySchema.omit({ id: true, genres: true })
|
|
||||||
const genreSchema = z.object({ id: z.number() })
|
|
||||||
const genresSchema = z.array(genreSchema)
|
|
||||||
try {
|
try {
|
||||||
//validate
|
const storyData = await prepStoryData(data)
|
||||||
schema.safeParse(storyData)
|
const genresArray = await prepGenreData(data.genres)
|
||||||
genresSchema.safeParse(genresArray)
|
|
||||||
|
|
||||||
//submit
|
//submit
|
||||||
const res = await prisma.story.create({ data: storyData })
|
const res = await prisma.story.create({ data: storyData })
|
||||||
|
@ -40,12 +30,13 @@ export async function createStory(data: Story & { genres: number[] }): Promise<S
|
||||||
return res
|
return res
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
return undefined
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function createPub(data: Pub & { genres: number[] }): Promise<Pub | undefined> {
|
export async function createPub(data: Pub & { genres: number[] }): Promise<Pub | boolean | undefined> {
|
||||||
"use server"
|
"use server"
|
||||||
//prepare data
|
//prepare data
|
||||||
const pubData = {
|
const pubData = {
|
||||||
|
@ -79,7 +70,7 @@ export async function createPub(data: Pub & { genres: number[] }): Promise<Pub |
|
||||||
return genresRes
|
return genresRes
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
return undefined
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,24 +10,33 @@ const tableMap = {
|
||||||
"/submission": "sub"
|
"/submission": "sub"
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteRecord(id: number, pathname: Pathname) {
|
export async function deleteRecord(id: number, pathname: Pathname): Promise<undefined | boolean> {
|
||||||
const table = tableMap[pathname]
|
const table = tableMap[pathname]
|
||||||
const res = await prisma[table].delete({ where: { id } })
|
try {
|
||||||
console.log(`deleted from ${table}: ${res.id}`)
|
const res = await prisma[table].delete({ where: { id } })
|
||||||
console.log("revalidating: " + pathname)
|
|
||||||
revalidatePath(pathname)
|
|
||||||
redirect(pathname)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteRecords(ids: number[], pathname: "/story" | "/publication" | "/submission") {
|
|
||||||
const table = tableMap[pathname]
|
|
||||||
ids.forEach(async (id) => {
|
|
||||||
const res = await prisma[table].delete({
|
|
||||||
where: { id }
|
|
||||||
})
|
|
||||||
console.log(`deleted from ${table}: ${res.id}`)
|
console.log(`deleted from ${table}: ${res.id}`)
|
||||||
})
|
revalidatePath(pathname)
|
||||||
revalidatePath(pathname)
|
return true
|
||||||
redirect(pathname)
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteRecords(ids: number[], pathname: "/story" | "/publication" | "/submission"): Promise<boolean | undefined> {
|
||||||
|
try {
|
||||||
|
const table = tableMap[pathname]
|
||||||
|
ids.forEach(async (id) => {
|
||||||
|
const res = await prisma[table].delete({
|
||||||
|
where: { id }
|
||||||
|
})
|
||||||
|
console.log(`deleted from ${table}: ${res.id}`)
|
||||||
|
})
|
||||||
|
revalidatePath(pathname)
|
||||||
|
return true
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
"use server"
|
"use server"
|
||||||
import { Genre, Sub } from "@prisma/client"
|
import { Genre, Story, Sub } from "@prisma/client"
|
||||||
import prisma from "./db"
|
import prisma from "./db"
|
||||||
import { revalidatePath } from "next/cache"
|
import { revalidatePath } from "next/cache"
|
||||||
import { redirect } from "next/navigation"
|
import { redirect } from "next/navigation"
|
||||||
import { subSchema } from "app/ui/forms/schemas"
|
import { storySchema, subSchema } from "app/ui/forms/schemas"
|
||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
|
||||||
export async function updateField({ datum, table, column, id, pathname }: { datum?: string | number | Genre[], table: string, column: string, id: number, pathname: string }) {
|
export async function updateField({ datum, table, column, id, pathname }: { datum?: string | number | Genre[], table: string, column: string, id: number, pathname: string }) {
|
||||||
|
@ -56,7 +57,28 @@ export async function updateSub(data: Sub): Promise<Sub | undefined> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function updateStory(data: Story & { genres: number[] }): Promise<Story | undefined> {
|
||||||
|
"use server"
|
||||||
|
//prepare data
|
||||||
|
const genresArray = data.genres.map((e) => { return { id: e } })
|
||||||
|
const storyData = {
|
||||||
|
title: data.title,
|
||||||
|
word_count: data.word_count,
|
||||||
|
}
|
||||||
|
//prepare schemas
|
||||||
|
const schema = storySchema.omit({ id: true, genres: true })
|
||||||
|
const genreSchema = z.object({ id: z.number() })
|
||||||
|
const genresSchema = z.array(genreSchema)
|
||||||
|
try {
|
||||||
|
//validate
|
||||||
|
schema.safeParse(storyData)
|
||||||
|
genresSchema.safeParse(genresArray)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import { storySchema } from "app/ui/forms/schemas";
|
||||||
|
import { Story } from "@prisma/client";
|
||||||
|
|
||||||
|
//schemas
|
||||||
|
|
||||||
|
const schema = storySchema.omit({ id: true, genres: true })
|
||||||
|
const genreSchema = z.object({ id: z.number() })
|
||||||
|
const genresSchema = z.array(genreSchema)
|
||||||
|
|
||||||
|
export async function prepStoryData(data: Story & { genres: number[] }): Promise<{ title: string, word_count: number }> {
|
||||||
|
const storyData = {
|
||||||
|
title: data.title,
|
||||||
|
word_count: data.word_count,
|
||||||
|
}
|
||||||
|
//prepare schemas
|
||||||
|
|
||||||
|
//throw an error if validation fails
|
||||||
|
schema.safeParse(storyData)
|
||||||
|
|
||||||
|
return storyData
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function prepGenreData(data: number[]): Promise<{ id: number }[]> {
|
||||||
|
"use server"
|
||||||
|
|
||||||
|
//prepare data
|
||||||
|
const genresArray = data.map((e) => { return { id: e } })
|
||||||
|
|
||||||
|
//prepare schemas
|
||||||
|
|
||||||
|
//throws error if validation fails
|
||||||
|
genresSchema.safeParse(genresArray)
|
||||||
|
return genresArray
|
||||||
|
|
||||||
|
}
|
|
@ -25,7 +25,9 @@ export default function CreatePubDialog({ genres }: ComponentProps<"div"> & { ge
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<PubForm createPub={createPub} genres={genres} />
|
<PubForm createPub={createPub} genres={genres} />
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button form="pubform">Submit</Button>
|
<DialogClose >
|
||||||
|
<Button form="pubform">Submit</Button>
|
||||||
|
</DialogClose>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { createStory } from "app/lib/create"
|
import { createStory } from "app/lib/create"
|
||||||
import { Dialog, DialogHeader, DialogTrigger, DialogContent, DialogClose, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
|
import { Dialog, DialogHeader, DialogTrigger, DialogContent, DialogClose, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ComponentProps } from "react";
|
import { ComponentProps, useState } from "react";
|
||||||
import { Genre } from "@prisma/client";
|
import { Genre } from "@prisma/client";
|
||||||
import StoryForm from "app/ui/forms/story";
|
import StoryForm from "app/ui/forms/story";
|
||||||
import { Plus } from "lucide-react";
|
import { Plus } from "lucide-react";
|
||||||
|
@ -10,8 +10,10 @@ import { Plus } from "lucide-react";
|
||||||
|
|
||||||
export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & { genres: Genre[] }) {
|
export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & { genres: Genre[] }) {
|
||||||
|
|
||||||
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<div>
|
<div>
|
||||||
<Button className="hidden md:block">Create new story</Button>
|
<Button className="hidden md:block">Create new story</Button>
|
||||||
|
@ -23,9 +25,12 @@ export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & {
|
||||||
<DialogTitle>New story</DialogTitle>
|
<DialogTitle>New story</DialogTitle>
|
||||||
<DialogDescription>Create an entry for a new story i.e. a thing you intend to submit for publication.</DialogDescription>
|
<DialogDescription>Create an entry for a new story i.e. a thing you intend to submit for publication.</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<StoryForm createStory={createStory} genres={genres} existingData={null} />
|
<StoryForm createStory={createStory} genres={genres} className="" />
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button form="storyform">Submit</Button>
|
<DialogClose>
|
||||||
|
{/* TODO: pass setIsOpen to form as prop, to be handled post-verification */}
|
||||||
|
<Button form="storyform">Submit</Button>
|
||||||
|
</DialogClose>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
|
@ -35,6 +35,7 @@ import { useState } from "react"
|
||||||
import { createSub } from "app/lib/create"
|
import { createSub } from "app/lib/create"
|
||||||
import { subSchema } from "./schemas"
|
import { subSchema } from "./schemas"
|
||||||
import { updateSub } from "app/lib/update"
|
import { updateSub } from "app/lib/update"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
export type SubForm = z.infer<typeof subSchema>
|
export type SubForm = z.infer<typeof subSchema>
|
||||||
|
|
||||||
|
@ -67,13 +68,14 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
// 2. Define a submit handler.
|
const router = useRouter()
|
||||||
|
|
||||||
async function onSubmit(values: z.infer<typeof subSchema>) {
|
async function onSubmit(values: z.infer<typeof subSchema>) {
|
||||||
try {
|
try {
|
||||||
const res = await updateSub(values)
|
const res = await updateSub(values)
|
||||||
if (res === undefined) throw new Error("something went wrong")
|
if (res === undefined) throw new Error("something went wrong")
|
||||||
toast({ title: "Successfully created new submission!" })
|
toast({ title: "Successfully created new submission!" })
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({
|
toast({
|
||||||
title: "UH-OH",
|
title: "UH-OH",
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { ComponentProps } from "react"
|
||||||
import { Genre } from "@prisma/client"
|
import { Genre } from "@prisma/client"
|
||||||
import GenrePicker from "./genrePicker"
|
import GenrePicker from "./genrePicker"
|
||||||
import { pubSchema } from "./schemas"
|
import { pubSchema } from "./schemas"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
export default function PubForm({ genres, createPub, className }: ComponentProps<"div"> & { genres: Array<Genre>, createPub: (data: any) => void }) {
|
export default function PubForm({ genres, createPub, className }: ComponentProps<"div"> & { genres: Array<Genre>, createPub: (data: any) => void }) {
|
||||||
const form = useForm<z.infer<typeof pubSchema>>({
|
const form = useForm<z.infer<typeof pubSchema>>({
|
||||||
|
@ -32,21 +33,20 @@ export default function PubForm({ genres, createPub, className }: ComponentProps
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
async function onSubmit(values: z.infer<typeof pubSchema>) {
|
async function onSubmit(values: z.infer<typeof pubSchema>) {
|
||||||
try {
|
try {
|
||||||
const res = await createPub(values)
|
const res = await createPub(values)
|
||||||
if (res === undefined) throw new Error("something went wrong")
|
if (!res) throw new Error("something went wrong")
|
||||||
toast({
|
toast({ title: "Successfully submitted:", description: values.title })
|
||||||
title: "Successfuly submitted:",
|
router.refresh()
|
||||||
description: values.title
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({
|
toast({
|
||||||
title: "UH-OH",
|
title: "Oh dear... ",
|
||||||
description: error.message
|
description: error.message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
window.location.reload()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onErrors(errors) {
|
function onErrors(errors) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { ComponentProps } from "react"
|
||||||
import { Genre, Story } from "@prisma/client"
|
import { Genre, Story } from "@prisma/client"
|
||||||
import { randomStoryTitle } from "app/lib/shortStoryTitleGenerator"
|
import { randomStoryTitle } from "app/lib/shortStoryTitleGenerator"
|
||||||
import GenrePicker from "./genrePicker"
|
import GenrePicker from "./genrePicker"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
export const formSchema = z.object({
|
export const formSchema = z.object({
|
||||||
id: z.number().optional(),
|
id: z.number().optional(),
|
||||||
|
@ -27,35 +28,30 @@ export const formSchema = z.object({
|
||||||
genres: z.array(z.number())
|
genres: z.array(z.number())
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function StoryForm({ genres, createStory, className, existingData }: ComponentProps<"div"> & { genres: Array<Genre>, createStory: (data: any) => void, existingData: Story & { genres: number[] } | null }) {
|
export default function StoryForm({ genres, createStory, className }: ComponentProps<"div"> & { genres: Array<Genre>, createStory: (data: any) => void, className: string }) {
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
id: existingData?.id,
|
word_count: 500,
|
||||||
title: existingData?.title ?? "",
|
genres: []
|
||||||
word_count: existingData?.word_count ?? 500,
|
|
||||||
genres: existingData?.genres ?? []
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||||
try {
|
try {
|
||||||
const res = await createStory(values)
|
const res = await createStory(values)
|
||||||
//server actions return undefined if middleware authentication fails
|
//server actions return undefined if middleware authentication fails
|
||||||
if (res === undefined) throw new Error("something went wrong")
|
if (!res) throw new Error("something went wrong")
|
||||||
toast({
|
toast({ title: "Sucessfully submitted:", description: values.title })
|
||||||
title: "Successfully submitted:",
|
router.refresh()
|
||||||
description: values.title,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({
|
toast({
|
||||||
title: "UH-OH",
|
title: "Oh dear... ",
|
||||||
description: error.message
|
description: error.message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
window.location.reload()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ import {
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import { createSub } from "app/lib/create"
|
import { createSub } from "app/lib/create"
|
||||||
import { subSchema } from "./schemas"
|
import { subSchema } from "./schemas"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
export type SubForm = z.infer<typeof subSchema>
|
export type SubForm = z.infer<typeof subSchema>
|
||||||
|
|
||||||
|
@ -65,8 +66,8 @@ export default function SubmissionForm({ stories, pubs, responses, defaults }) {
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))
|
))
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
// 2. Define a submit handler.
|
|
||||||
async function onSubmit(values: z.infer<typeof subSchema>) {
|
async function onSubmit(values: z.infer<typeof subSchema>) {
|
||||||
try {
|
try {
|
||||||
const res = await createSub(values)
|
const res = await createSub(values)
|
||||||
|
@ -78,7 +79,7 @@ export default function SubmissionForm({ stories, pubs, responses, defaults }) {
|
||||||
description: error.message
|
description: error.message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onErrors(errors) {
|
function onErrors(errors) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ import {
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table"
|
} from "@/components/ui/table"
|
||||||
import { EyeIcon, Trash2 } from "lucide-react"
|
import { EyeIcon, Trash2 } from "lucide-react"
|
||||||
import { usePathname } from "next/navigation"
|
import { usePathname, useSearchParams } from "next/navigation"
|
||||||
import FormContextMenu from "./contextMenu"
|
import FormContextMenu from "./contextMenu"
|
||||||
import { deleteRecord, deleteRecords } from "app/lib/del"
|
import { deleteRecord, deleteRecords } from "app/lib/del"
|
||||||
import { Pathname } from "app/types"
|
import { Pathname } from "app/types"
|
||||||
|
@ -50,6 +50,8 @@ import { tableNameToItemName } from "app/lib/nameMaps"
|
||||||
import { Genre, Pub, Response, Story } from "@prisma/client"
|
import { Genre, Pub, Response, Story } from "@prisma/client"
|
||||||
import EditSubmissionDialog from "app/submission/edit"
|
import EditSubmissionDialog from "app/submission/edit"
|
||||||
import { DialogTitle } from "@radix-ui/react-dialog"
|
import { DialogTitle } from "@radix-ui/react-dialog"
|
||||||
|
import { toast } from "@/components/ui/use-toast"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
export interface DataTableProps<TData, TValue> {
|
export interface DataTableProps<TData, TValue> {
|
||||||
columns: ColumnDef<TData, TValue>[]
|
columns: ColumnDef<TData, TValue>[]
|
||||||
|
@ -119,6 +121,9 @@ export function DataTable<TData, TValue>({
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const [filterBy, setFilterBy] = useState(table.getAllColumns()[0])
|
const [filterBy, setFilterBy] = useState(table.getAllColumns()[0])
|
||||||
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false)
|
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false)
|
||||||
return (<>
|
return (<>
|
||||||
|
@ -181,8 +186,11 @@ export function DataTable<TData, TValue>({
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button variant="destructive"
|
<Button variant="destructive"
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
deleteRecord(dialogRow.original.id, pathname)
|
const res = await deleteRecord(dialogRow.original.id, pathname)
|
||||||
|
if (!res) toast({ title: "Oh dear...", description: "Failed to delete." })
|
||||||
|
if (res) toast({ title: "Successfully deleted record of id:", description: dialogRow.original.id })
|
||||||
|
router.refresh()
|
||||||
}}>Yes, delete it!
|
}}>Yes, delete it!
|
||||||
</Button>
|
</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
|
@ -206,11 +214,14 @@ export function DataTable<TData, TValue>({
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button variant="destructive"
|
<Button variant="destructive"
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
const selectedRows = table.getState().rowSelection
|
const selectedRows = table.getState().rowSelection
|
||||||
const rowIds = Object.keys(selectedRows)
|
const rowIds = Object.keys(selectedRows)
|
||||||
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
||||||
deleteRecords(recordIds, pathname)
|
const res = await deleteRecords(recordIds, pathname)
|
||||||
|
if (!res) toast({ title: "Oh dear...", description: "Failed to delete." })
|
||||||
|
if (res) toast({ title: "Sucessfully deleted records of id:", description: JSON.stringify(recordIds) })
|
||||||
|
router.refresh()
|
||||||
}}>
|
}}>
|
||||||
Yes, delete them!</Button>
|
Yes, delete them!</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { toast } from "@/components/ui/use-toast"
|
||||||
import GenreBadges from "app/ui/genreBadges"
|
import GenreBadges from "app/ui/genreBadges"
|
||||||
import { updateField, updateGenres } from "app/lib/update"
|
import { updateField, updateGenres } from "app/lib/update"
|
||||||
import { Genre } from "@prisma/client"
|
import { Genre } from "@prisma/client"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
export default function GenrePickerInputCell(props: CellContext<any, any>) {
|
export default function GenrePickerInputCell(props: CellContext<any, any>) {
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ export default function GenrePickerInputCell(props: CellContext<any, any>) {
|
||||||
const value = props.cell.getValue()
|
const value = props.cell.getValue()
|
||||||
const genres = props.table.options.meta.genres
|
const genres = props.table.options.meta.genres
|
||||||
const [isActive, setIsActive] = useState(false)
|
const [isActive, setIsActive] = useState(false)
|
||||||
|
const router = useRouter()
|
||||||
async function onSubmit({ genres }: { genres: number[] }, event: Event) {
|
async function onSubmit({ genres }: { genres: number[] }, event: Event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
try {
|
try {
|
||||||
|
@ -36,7 +37,7 @@ export default function GenrePickerInputCell(props: CellContext<any, any>) {
|
||||||
})
|
})
|
||||||
if (res === undefined) throw new Error("Something went wrong.")
|
if (res === undefined) throw new Error("Something went wrong.")
|
||||||
toast({ title: "Field updated successfully." })
|
toast({ title: "Field updated successfully." })
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
toast({ title: "Something went wrong." })
|
toast({ title: "Something went wrong." })
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { toast } from "@/components/ui/use-toast";
|
import { toast } from "@/components/ui/use-toast";
|
||||||
import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form";
|
import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form";
|
||||||
import TitleContainer from "app/ui/titleContainer";
|
import TitleContainer from "app/ui/titleContainer";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
export function TextInputCell({ cellContext, className }: { className: string, cellContext: CellContext<any, any> }) {
|
export function TextInputCell({ cellContext, className }: { className: string, cellContext: CellContext<any, any> }) {
|
||||||
const [isActive, setIsActive] = useState(false)
|
const [isActive, setIsActive] = useState(false)
|
||||||
|
@ -29,7 +30,7 @@ export function TextInputCell({ cellContext, className }: { className: string, c
|
||||||
[column]: cellContext.cell.getValue()
|
[column]: cellContext.cell.getValue()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
const router = useRouter()
|
||||||
async function onSubmit(value: z.infer<typeof formSchema>) {
|
async function onSubmit(value: z.infer<typeof formSchema>) {
|
||||||
try {
|
try {
|
||||||
const res = await updateField({
|
const res = await updateField({
|
||||||
|
@ -41,7 +42,7 @@ export function TextInputCell({ cellContext, className }: { className: string, c
|
||||||
})
|
})
|
||||||
if (res === undefined) throw new Error("something went wrong")
|
if (res === undefined) throw new Error("something went wrong")
|
||||||
toast({ title: "Field updated successfully." })
|
toast({ title: "Field updated successfully." })
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
toast({ title: "Something went wrong." })
|
toast({ title: "Something went wrong." })
|
||||||
|
|
Loading…
Reference in New Issue