fix build errors
This commit is contained in:
		
							parent
							
								
									a0808ea804
								
							
						
					
					
						commit
						bb601d3c82
					
				| 
						 | 
				
			
			@ -9,7 +9,7 @@ export async function getJWTSecretKey<Uint8Array>() {
 | 
			
		|||
	const secret = process.env.JWT_SECRET
 | 
			
		||||
	if (!secret) throw new Error("There is no JWT secret key")
 | 
			
		||||
	try {
 | 
			
		||||
		const enc: Uint8Array = new TextEncoder().encode(secret)
 | 
			
		||||
		const enc = new TextEncoder().encode(secret)
 | 
			
		||||
		return enc
 | 
			
		||||
	} catch (error) {
 | 
			
		||||
		throw new Error("failed to getJWTSecretKey", error.message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,15 +8,16 @@ import { storySchema } from "app/ui/forms/schemas"
 | 
			
		|||
import { pubSchema } from "app/ui/forms/schemas"
 | 
			
		||||
import { subSchema } from "app/ui/forms/schemas"
 | 
			
		||||
import { prepGenreData, prepStoryData } from "./validate"
 | 
			
		||||
import { SubForm } from "app/ui/forms/sub"
 | 
			
		||||
 | 
			
		||||
//TODO - data validation, error handling, unauthorized access handling
 | 
			
		||||
 | 
			
		||||
export async function createStory(data: Story & { genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
export async function createStory({ story, genres }: { story: Story, genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
	// will return undefined if middleware authorization fails
 | 
			
		||||
	"use server"
 | 
			
		||||
	try {
 | 
			
		||||
		const storyData = await prepStoryData(data)
 | 
			
		||||
		const genresArray = await prepGenreData(data.genres)
 | 
			
		||||
		const storyData = await prepStoryData(story)
 | 
			
		||||
		const genresArray = await prepGenreData(genres)
 | 
			
		||||
 | 
			
		||||
		//submit
 | 
			
		||||
		const res = await prisma.story.create({ data: storyData })
 | 
			
		||||
| 
						 | 
				
			
			@ -27,24 +28,17 @@ export async function createStory(data: Story & { genres: number[] }): Promise<{
 | 
			
		|||
			}
 | 
			
		||||
		})
 | 
			
		||||
		revalidatePath("/story")
 | 
			
		||||
		return { success: `Created the story '${data.title}'.` }
 | 
			
		||||
		return { success: `Created the story '${story.title}'.` }
 | 
			
		||||
	} catch (error) {
 | 
			
		||||
		console.error(error)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function createPub(data: Pub & { genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
export async function createPub({ pub, genres }: { pub: Pub, genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
	"use server"
 | 
			
		||||
	//prepare data
 | 
			
		||||
	const pubData = {
 | 
			
		||||
		title: data.title,
 | 
			
		||||
		link: data.link,
 | 
			
		||||
		query_after_days: data.query_after_days
 | 
			
		||||
	}
 | 
			
		||||
	const genresArray = data.genres.map(e => { return { id: e } })
 | 
			
		||||
	const genresArray = genres.map(e => { return { id: e } })
 | 
			
		||||
 | 
			
		||||
	//prepare schemas
 | 
			
		||||
	const schema = pubSchema.omit({ genres: true })
 | 
			
		||||
| 
						 | 
				
			
			@ -54,12 +48,12 @@ export async function createPub(data: Pub & { genres: number[] }): Promise<{ suc
 | 
			
		|||
	try {
 | 
			
		||||
 | 
			
		||||
		//validate
 | 
			
		||||
		schema.parse(pubData)
 | 
			
		||||
		schema.parse(pub)
 | 
			
		||||
		genresSchema.safeParse(genresArray)
 | 
			
		||||
 | 
			
		||||
		//submit
 | 
			
		||||
		const res = await prisma.pub.create({
 | 
			
		||||
			data: pubData
 | 
			
		||||
			data: pub
 | 
			
		||||
		})
 | 
			
		||||
		const genresRes = await prisma.pub.update({
 | 
			
		||||
			where: { id: res.id },
 | 
			
		||||
| 
						 | 
				
			
			@ -67,10 +61,9 @@ export async function createPub(data: Pub & { genres: number[] }): Promise<{ suc
 | 
			
		|||
				{ genres: { set: genresArray } }
 | 
			
		||||
		})
 | 
			
		||||
		revalidatePath("/publication")
 | 
			
		||||
		return { success: `Created the publication '${data.title}'.` }
 | 
			
		||||
		return { success: `Created the publication '${pub.title}'.` }
 | 
			
		||||
	} catch (error) {
 | 
			
		||||
		console.error(error)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,9 +10,10 @@ const tableMap = {
 | 
			
		|||
	"/submission": "sub"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function deleteRecord(id: number, pathname: Pathname): Promise<undefined | boolean> {
 | 
			
		||||
export async function deleteRecord(id: number, pathname: string): Promise<undefined | boolean> {
 | 
			
		||||
	const table = tableMap[pathname]
 | 
			
		||||
	try {
 | 
			
		||||
		//@ts-ignore
 | 
			
		||||
		const res = await prisma[table].delete({ where: { id } })
 | 
			
		||||
		console.log(`deleted from ${table}: ${res.id}`)
 | 
			
		||||
		revalidatePath(pathname)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
export default function pluralize(word: "story" | "publication" | "submission"): string {
 | 
			
		||||
export default function pluralize(word: string): string {
 | 
			
		||||
	const map = {
 | 
			
		||||
		story: "stories",
 | 
			
		||||
		publication: "publications",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,8 @@ import { prepGenreData, prepPubData, prepStoryData } from "./validate"
 | 
			
		|||
import { Genre, Pub, Story, Sub } from "@prisma/client"
 | 
			
		||||
import prisma from "./db"
 | 
			
		||||
import { revalidatePath } from "next/cache"
 | 
			
		||||
import { redirect } from "next/navigation"
 | 
			
		||||
import { storySchema, subSchema } from "app/ui/forms/schemas"
 | 
			
		||||
import { z } from "zod"
 | 
			
		||||
import { StoryWithGenres } from "app/story/page"
 | 
			
		||||
import { PubWithGenres } from "app/publication/page"
 | 
			
		||||
import { subSchema } from "app/ui/forms/schemas"
 | 
			
		||||
import { SubForm } from "app/ui/forms/sub"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function updateField({ datum, table, column, id, pathname }: { datum?: string | number | Genre[], table: string, column: string, id: number, pathname: string }) {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +43,7 @@ export async function updateGenres({ genres, table, id, pathname }: { genres: {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function updateSub(data: Sub): Promise<Sub> {
 | 
			
		||||
export async function updateSub(data: SubForm): Promise<Sub> {
 | 
			
		||||
	"use server"
 | 
			
		||||
	try {
 | 
			
		||||
		subSchema.parse(data)
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +57,7 @@ export async function updateSub(data: Sub): Promise<Sub> {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function updateStory(data: StoryWithGenres): Promise<{ success: string }> {
 | 
			
		||||
export async function updateStory(data: Story & { genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
	"use server"
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +83,7 @@ export async function updateStory(data: StoryWithGenres): Promise<{ success: str
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function updatePub(data: PubWithGenres): Promise<{ success: string }> {
 | 
			
		||||
export async function updatePub(data: Pub & { genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
	"use server"
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,17 +11,15 @@ const pubSchemaTrimmed = pubSchema.omit({ genres: true })
 | 
			
		|||
const genreSchema = z.object({ id: z.number() })
 | 
			
		||||
const genresSchema = z.array(genreSchema)
 | 
			
		||||
 | 
			
		||||
export async function prepStoryData(data: StoryWithGenres): Promise<{ title: string, word_count: number }> {
 | 
			
		||||
export async function prepStoryData(data: Story): Promise<{ title: string, word_count: number }> {
 | 
			
		||||
	const storyData = structuredClone(data)
 | 
			
		||||
	delete storyData.genres
 | 
			
		||||
	//throw an error if validation fails
 | 
			
		||||
	storySchemaTrimmed.safeParse(storyData)
 | 
			
		||||
	return storyData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function prepPubData(data: Pub & { genres: number[] }): Promise<Pub> {
 | 
			
		||||
export async function prepPubData(data: Pub): Promise<Pub> {
 | 
			
		||||
	const pubData = structuredClone(data)
 | 
			
		||||
	delete pubData.genres
 | 
			
		||||
	pubSchemaTrimmed.safeParse(pubData)
 | 
			
		||||
	return pubData
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ export default async function Page({ params }: { params: { id: string } }) {
 | 
			
		|||
      <PageHeader>{pub.title}</PageHeader>
 | 
			
		||||
      <GenreBadges genres={pub.genres} className="my-6" />
 | 
			
		||||
      <PageSubHeader>Submissions:</PageSubHeader>
 | 
			
		||||
      <DataTable columns={columns} data={pubSubs} type="submission" />
 | 
			
		||||
      <DataTable columns={columns} data={pubSubs} tableName="sub" />
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ export const columns: ColumnDef<PubWithGenres>[] = [
 | 
			
		|||
    },
 | 
			
		||||
    cell: cell => (
 | 
			
		||||
      <>
 | 
			
		||||
        {/* @ts-ignore */}
 | 
			
		||||
        <p className="block text-xs max-w-24 break-words md:hidden">{cell.getValue()}</p>
 | 
			
		||||
        <TextInputCell cellContext={cell} className="hidden md:block" />
 | 
			
		||||
      </>
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +50,7 @@ export const columns: ColumnDef<PubWithGenres>[] = [
 | 
			
		|||
    ),
 | 
			
		||||
    cell: cell => (
 | 
			
		||||
      <>
 | 
			
		||||
        {/* @ts-ignore */}
 | 
			
		||||
        <p className="block text-xs max-w-16 truncate md:hidden">{cell.getValue()}</p>
 | 
			
		||||
        <TextInputCell cellContext={cell} className="hidden md:block" />
 | 
			
		||||
      </>
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +80,7 @@ export const columns: ColumnDef<PubWithGenres>[] = [
 | 
			
		|||
    ),
 | 
			
		||||
    cell: cell => (
 | 
			
		||||
      <>
 | 
			
		||||
        {/* @ts-ignore */}
 | 
			
		||||
        <p className="block md:hidden text-center">{cell.getValue()}</p>
 | 
			
		||||
        <NumberInputCell cellContext={cell} className="hidden md:block" />
 | 
			
		||||
      </>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,14 +2,14 @@
 | 
			
		|||
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 { Genre, Pub } from "@prisma/client";
 | 
			
		||||
import { createPub } from "app/lib/create";
 | 
			
		||||
import PubForm from "app/ui/forms/pub";
 | 
			
		||||
import { Plus } from "lucide-react";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
import { PubWithGenres } from "./page";
 | 
			
		||||
 | 
			
		||||
export default function EditPubDialog({ genres, closeDialog, defaults, dbAction }: ComponentProps<"div"> & { genres: Genre[], closeDialog: () => void, defaults: PubWithGenres, dbAction: (data: PubWithGenres) => Promise<{ success: string }> }) {
 | 
			
		||||
export default function EditPubDialog({ genres, closeDialog, defaults, dbAction }: ComponentProps<"div"> & { genres: Genre[], closeDialog: () => void, defaults: PubWithGenres, dbAction: (data: Pub & { genres: number[] }) => Promise<{ success: string }> }) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
 | 
			
		|||
    },
 | 
			
		||||
    cell: cell => (
 | 
			
		||||
      <>
 | 
			
		||||
        {/* @ts-ignore */}
 | 
			
		||||
        <p className="block break-words max-w-28 md:hidden text-xs">{cell.getValue()}</p>
 | 
			
		||||
        <TextInputCell cellContext={cell} className="hidden md:block" />
 | 
			
		||||
      </>
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +60,7 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
 | 
			
		|||
    enableColumnFilter: false,
 | 
			
		||||
    cell: cell => (
 | 
			
		||||
      <>
 | 
			
		||||
        {/* @ts-ignore */}
 | 
			
		||||
        <p className="block md:hidden text-center text-xs">{cell.getValue()}</p>
 | 
			
		||||
        <NumberInputCell cellContext={cell} className="hidden md:block" />
 | 
			
		||||
      </>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,10 @@ import prisma from "app/lib/db";
 | 
			
		|||
import { revalidatePath } from "next/cache";
 | 
			
		||||
import { redirect } from "next/navigation";
 | 
			
		||||
import { CreateContainerContent, CreateContainerHeader, CreateContainer, CreateContainerDescription } from "app/ui/createContainer";
 | 
			
		||||
import { Story } from "@prisma/client";
 | 
			
		||||
export default async function Page() {
 | 
			
		||||
	const genres = await getGenres()
 | 
			
		||||
	async function createStory(data) {
 | 
			
		||||
	async function createStory(data: Story & { genres: number[] }): Promise<{ success: string }> {
 | 
			
		||||
		"use server"
 | 
			
		||||
		const genresArray = data.genres.map(e => { return { id: e } })
 | 
			
		||||
		const res = await prisma.story.create({
 | 
			
		||||
| 
						 | 
				
			
			@ -26,12 +27,14 @@ export default async function Page() {
 | 
			
		|||
		revalidatePath("/story")
 | 
			
		||||
		redirect("/story")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<CreateContainer>
 | 
			
		||||
			<CreateContainerHeader>New story</CreateContainerHeader>
 | 
			
		||||
			<CreateContainerContent>
 | 
			
		||||
				<CreateContainerDescription>Make an entry for a new work of fiction i.e. a thing you intend to submit for publication.</CreateContainerDescription>
 | 
			
		||||
				<StoryForm genres={genres} createStory={createStory} className="mt-6" />
 | 
			
		||||
				<StoryForm genres={genres} dbAction={createStory} className="mt-6" />
 | 
			
		||||
			</CreateContainerContent>
 | 
			
		||||
		</CreateContainer>
 | 
			
		||||
	)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,12 +2,12 @@
 | 
			
		|||
import { DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
 | 
			
		||||
import { Button } from "@/components/ui/button";
 | 
			
		||||
import { ComponentProps, useState } from "react";
 | 
			
		||||
import { Genre } from "@prisma/client";
 | 
			
		||||
import { Genre, Story } from "@prisma/client";
 | 
			
		||||
import StoryForm from "app/ui/forms/story";
 | 
			
		||||
import { StoryWithGenres } from "./page";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default function EditStoryDialog({ genres, closeDialog, defaults, dbAction }: ComponentProps<"div"> & { genres: Genre[], closeDialog: () => void, defaults: StoryWithGenres, dbAction: (data: StoryWithGenres) => Promise<{ success: string }> }) {
 | 
			
		||||
export default function EditStoryDialog({ genres, closeDialog, defaults, dbAction }: ComponentProps<"div"> & { genres: Genre[], closeDialog: () => void, defaults: StoryWithGenres, dbAction: (data: Story & { genres: number[] }) => Promise<{ success: string }> }) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,19 +10,12 @@ export default async function Page() {
 | 
			
		|||
	const stories = await getStories()
 | 
			
		||||
	const pubs = await getPubs()
 | 
			
		||||
	const responses = await getResponses()
 | 
			
		||||
	async function createSub(data) {
 | 
			
		||||
		"use server"
 | 
			
		||||
		const res = await prisma.sub.create({ data })
 | 
			
		||||
		console.log(res)
 | 
			
		||||
		revalidatePath("/submission")
 | 
			
		||||
		redirect("/submission")
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return (
 | 
			
		||||
		<CreateContainer>
 | 
			
		||||
			<CreateContainerHeader>New submission</CreateContainerHeader>
 | 
			
		||||
			<CreateContainerContent>
 | 
			
		||||
				<SubmissionForm stories={stories} pubs={pubs} responses={responses} createSub={createSub} />
 | 
			
		||||
				<SubmissionForm stories={stories} pubs={pubs} responses={responses} />
 | 
			
		||||
			</CreateContainerContent>
 | 
			
		||||
		</CreateContainer>
 | 
			
		||||
	)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
import { CheckboxReactHookFormMultiple } from "app/ui/forms/Checkboxdemo";
 | 
			
		||||
 | 
			
		||||
export default function Page() {
 | 
			
		||||
  return (
 | 
			
		||||
    <CheckboxReactHookFormMultiple />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -56,13 +56,13 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
	const pubsSelectItems = pubs.map(e => (
 | 
			
		||||
		<SelectItem value={e.id}>
 | 
			
		||||
		<SelectItem value={e.id} key={e.title}>
 | 
			
		||||
			{e.title}
 | 
			
		||||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
 | 
			
		||||
	const reponsesSelectItems = responses.map(e => (
 | 
			
		||||
		<SelectItem value={e.id}>
 | 
			
		||||
		<SelectItem value={e.id} key={e.title}>
 | 
			
		||||
			{e.response}
 | 
			
		||||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel className="text-sm md:text-base">Story</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue placeholder="Select something">
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel className="text-sm md:text-base">Publication</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue placeholder="Select something">
 | 
			
		||||
| 
						 | 
				
			
			@ -173,9 +173,8 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
									</FormControl>
 | 
			
		||||
								</PopoverTrigger>
 | 
			
		||||
								<PopoverContent className="w-auto p-0" align="start">
 | 
			
		||||
									<Calendar
 | 
			
		||||
										mode="single"
 | 
			
		||||
										selected={field.value}
 | 
			
		||||
									{/* @ts-ignore */}
 | 
			
		||||
									<Calendar mode="single" selected={field.value}
 | 
			
		||||
										onSelect={(e) => { field.onChange(e); setIsSubCalendarOpen(false); }}
 | 
			
		||||
										disabled={(date) =>
 | 
			
		||||
											date > new Date() || date < new Date("1900-01-01")
 | 
			
		||||
| 
						 | 
				
			
			@ -218,10 +217,8 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
									</FormControl>
 | 
			
		||||
								</PopoverTrigger>
 | 
			
		||||
								<PopoverContent className="w-auto p-0" align="start">
 | 
			
		||||
									<Calendar
 | 
			
		||||
										mode="single"
 | 
			
		||||
										selected={field.value}
 | 
			
		||||
										onSelect={(e) => { field.onChange(e); setIsRespCalendarOpen(false); }}
 | 
			
		||||
									{/* @ts-ignore */}
 | 
			
		||||
									<Calendar selected={field.value} onSelect={(e) => { field.onChange(e); setIsRespCalendarOpen(false); }}
 | 
			
		||||
										disabled={(date) =>
 | 
			
		||||
											date > new Date() || date < new Date("1900-01-01")
 | 
			
		||||
										}
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +241,7 @@ export default function EditSubmissionForm({ stories, pubs, responses, defaults,
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel className="text-sm md:text-base">Response</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,14 @@ export default function PubForm({ genres, dbAction, className, closeDialog, defa
 | 
			
		|||
 | 
			
		||||
	async function onSubmit(values: z.infer<typeof pubSchema>) {
 | 
			
		||||
		try {
 | 
			
		||||
			const res = await dbAction(values)
 | 
			
		||||
			const res = await dbAction({
 | 
			
		||||
				pub: {
 | 
			
		||||
					id: values?.id,
 | 
			
		||||
					title: values.title,
 | 
			
		||||
					link: values.link,
 | 
			
		||||
					query_after_days: values.query_after_days
 | 
			
		||||
				}, genres: values.genres
 | 
			
		||||
			})
 | 
			
		||||
			if (!res?.success) throw new Error("something went wrong")
 | 
			
		||||
			toast({ title: "Success!", description: res.success })
 | 
			
		||||
			router.refresh()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ export const formSchema = z.object({
 | 
			
		|||
	genres: z.array(z.number())
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default function StoryForm({ genres, dbAction, className, closeDialog, defaults }: ComponentProps<"div"> & { genres: Array<Genre>, dbAction: (data: any) => Promise<{ success: string }>, className: string, closeDialog: () => void, defaults?: StoryWithGenres }) {
 | 
			
		||||
export default function StoryForm({ genres, dbAction, className, closeDialog, defaults }: ComponentProps<"div"> & { genres: Array<Genre>, dbAction: (data: any) => Promise<{ success: string }>, className: string, closeDialog?: () => void, defaults?: StoryWithGenres }) {
 | 
			
		||||
	const form = useForm<z.infer<typeof formSchema>>({
 | 
			
		||||
		resolver: zodResolver(formSchema),
 | 
			
		||||
		defaultValues: {
 | 
			
		||||
| 
						 | 
				
			
			@ -40,13 +40,19 @@ export default function StoryForm({ genres, dbAction, className, closeDialog, de
 | 
			
		|||
			genres: defaults?.genres.map(e => e.id) ?? []
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	console.log("DEFAULTS: " + defaults)
 | 
			
		||||
 | 
			
		||||
	const router = useRouter()
 | 
			
		||||
 | 
			
		||||
	async function onSubmit(values: z.infer<typeof formSchema>) {
 | 
			
		||||
		try {
 | 
			
		||||
			const res = await dbAction(values)
 | 
			
		||||
			const res = await dbAction({
 | 
			
		||||
				story: {
 | 
			
		||||
					id: values?.id,
 | 
			
		||||
					title: values.title,
 | 
			
		||||
					word_count: values.word_count,
 | 
			
		||||
				},
 | 
			
		||||
				genres: values.genres
 | 
			
		||||
			})
 | 
			
		||||
			//server actions return undefined if middleware authentication fails
 | 
			
		||||
			if (!res?.success) throw new Error("something went wrong")
 | 
			
		||||
			toast({ title: "Success!", description: res.success })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,11 +36,12 @@ import { createSub } from "app/lib/create"
 | 
			
		|||
import { subSchema } from "./schemas"
 | 
			
		||||
import { useRouter } from "next/navigation"
 | 
			
		||||
import { Ban } from "lucide-react"
 | 
			
		||||
import { Story } from "@prisma/client"
 | 
			
		||||
 | 
			
		||||
export type SubForm = z.infer<typeof subSchema>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default function SubmissionForm({ stories, pubs, responses, defaults, closeDialog }: { stories: any, pubs: any, responses: any, defaults?: any, closeDialog: () => void }) {
 | 
			
		||||
export default function SubmissionForm({ stories, pubs, responses, defaults, closeDialog }: { stories: any, pubs: any, responses: any, defaults?: any, closeDialog?: () => void }) {
 | 
			
		||||
	const form = useForm<z.infer<typeof subSchema>>({
 | 
			
		||||
		resolver: zodResolver(subSchema),
 | 
			
		||||
		defaultValues: {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,19 +51,19 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
	})
 | 
			
		||||
	const [isSubCalendarOpen, setIsSubCalendarOpen] = useState(false);
 | 
			
		||||
	const [isRespCalendarOpen, setIsRespCalendarOpen] = useState(false);
 | 
			
		||||
	const storiesSelectItems = stories.map(e => (
 | 
			
		||||
		<SelectItem value={e.id.toString()} key={e.title}>
 | 
			
		||||
	const storiesSelectItems = stories.map((e: Story) => (
 | 
			
		||||
		<SelectItem value={e.id?.toString()} key={e.title}>
 | 
			
		||||
			{e.title}
 | 
			
		||||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
	const pubsSelectItems = pubs.map(e => (
 | 
			
		||||
		<SelectItem value={e.id}>
 | 
			
		||||
		<SelectItem value={e.id} key={e.title}>
 | 
			
		||||
			{e.title}
 | 
			
		||||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
 | 
			
		||||
	const reponsesSelectItems = responses.map(e => (
 | 
			
		||||
		<SelectItem value={e.id}>
 | 
			
		||||
		<SelectItem value={e.id} key={e.title}>
 | 
			
		||||
			{e.response}
 | 
			
		||||
		</SelectItem>
 | 
			
		||||
	))
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +72,7 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
 | 
			
		||||
	async function onSubmit(values: z.infer<typeof subSchema>) {
 | 
			
		||||
		try {
 | 
			
		||||
			//@ts-ignore
 | 
			
		||||
			const res = await createSub(values)
 | 
			
		||||
			if (!res) throw new Error("something went wrong")
 | 
			
		||||
			toast({ title: "Successfully created new submission!" })
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +104,7 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel>Story</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value?.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue placeholder="Select something">
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +127,7 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel className="text-sm md:text-base">Publication</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value?.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue placeholder="Select something">
 | 
			
		||||
| 
						 | 
				
			
			@ -169,9 +171,8 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
									</FormControl>
 | 
			
		||||
								</PopoverTrigger>
 | 
			
		||||
								<PopoverContent className="w-auto p-0" align="start">
 | 
			
		||||
									<Calendar
 | 
			
		||||
										mode="single"
 | 
			
		||||
										selected={field.value}
 | 
			
		||||
									{/* @ts-ignore */}
 | 
			
		||||
									<Calendar mode="single" selected={field.value}
 | 
			
		||||
										onSelect={(e) => { field.onChange(e); setIsSubCalendarOpen(false); }}
 | 
			
		||||
										disabled={(date) =>
 | 
			
		||||
											date > new Date() || date < new Date("1900-01-01")
 | 
			
		||||
| 
						 | 
				
			
			@ -214,9 +215,8 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
									</FormControl>
 | 
			
		||||
								</PopoverTrigger>
 | 
			
		||||
								<PopoverContent className="w-auto p-0" align="start">
 | 
			
		||||
									<Calendar
 | 
			
		||||
										mode="single"
 | 
			
		||||
										selected={field.value}
 | 
			
		||||
									{/* @ts-ignore */}
 | 
			
		||||
									<Calendar mode="single" selected={field.value}
 | 
			
		||||
										onSelect={(e) => { field.onChange(e); setIsRespCalendarOpen(false); }}
 | 
			
		||||
										disabled={(date) =>
 | 
			
		||||
											date > new Date() || date < new Date("1900-01-01")
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ export default function SubmissionForm({ stories, pubs, responses, defaults, clo
 | 
			
		|||
					render={({ field }) => (
 | 
			
		||||
						<FormItem>
 | 
			
		||||
							<FormLabel className="text-sm md:text-base">Response</FormLabel>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value}>
 | 
			
		||||
							<Select onValueChange={field.onChange} defaultValue={field.value?.toString()}>
 | 
			
		||||
								<FormControl>
 | 
			
		||||
									<SelectTrigger>
 | 
			
		||||
										<SelectValue>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import { ComponentProps, useState } from "react"
 | 
			
		|||
import { Row, Table, TableState } from "@tanstack/react-table"
 | 
			
		||||
 | 
			
		||||
export default function FormContextMenu({ table, row, openEditDialog, openDeleteDialog }: ComponentProps<"div"> & { table: Table<any>, row: Row<any>, openEditDialog: (row: Row<any>) => void, openDeleteDialog: (row: Row<any>) => void }) {
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const pathname = table.options.meta.pathname
 | 
			
		||||
  const selectedRows = table.getSelectedRowModel().flatRows
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ export function DataTable<TData, TValue>({
 | 
			
		|||
  const [columnVisibility, setColumnVisibility] =
 | 
			
		||||
    useState<VisibilityState>({})
 | 
			
		||||
  //
 | 
			
		||||
  const pathname: Pathname = usePathname()
 | 
			
		||||
  const pathname: string = usePathname()
 | 
			
		||||
  const table = useReactTable({
 | 
			
		||||
    data,
 | 
			
		||||
    columns,
 | 
			
		||||
| 
						 | 
				
			
			@ -141,17 +141,13 @@ export function DataTable<TData, TValue>({
 | 
			
		|||
            </Button>
 | 
			
		||||
          </DropdownMenuTrigger>
 | 
			
		||||
          <DropdownMenuContent align="end">
 | 
			
		||||
            {/*@ts-ignore*/}
 | 
			
		||||
            <DropdownMenuRadioGroup value={filterBy} onValueChange={setFilterBy} >
 | 
			
		||||
              {table
 | 
			
		||||
                .getAllColumns()
 | 
			
		||||
                .filter((column) => column.getCanFilter())
 | 
			
		||||
                .map((column) => {
 | 
			
		||||
                  return (
 | 
			
		||||
                    <DropdownMenuRadioItem value={column} className="capitalize" key={column.id}>
 | 
			
		||||
                      {column.id}
 | 
			
		||||
                    </DropdownMenuRadioItem>
 | 
			
		||||
                  )
 | 
			
		||||
                })}
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                .map((column) => { return (<DropdownMenuRadioItem value={column} className="capitalize" key={column.id}> {column.id} </DropdownMenuRadioItem>) })}
 | 
			
		||||
            </DropdownMenuRadioGroup>
 | 
			
		||||
          </DropdownMenuContent>
 | 
			
		||||
        </DropdownMenu>
 | 
			
		||||
| 
						 | 
				
			
			@ -234,6 +230,7 @@ export function DataTable<TData, TValue>({
 | 
			
		|||
            {`Delete ${Object.keys(table.getState().rowSelection).length} ${pluralize(pathname.slice(1))}?`}
 | 
			
		||||
          </DialogHeader>
 | 
			
		||||
          <DialogDescription>
 | 
			
		||||
            {/* @ts-ignore */}
 | 
			
		||||
            {`Deleting ${pluralize(tableNameToItemName(table.options.meta.tableName))} cannot be undone!`}
 | 
			
		||||
          </DialogDescription>
 | 
			
		||||
          <DialogFooter>
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +238,9 @@ export function DataTable<TData, TValue>({
 | 
			
		|||
              onClick={async () => {
 | 
			
		||||
                const selectedRows = table.getState().rowSelection
 | 
			
		||||
                const rowIds = Object.keys(selectedRows)
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                const res = await deleteRecords(recordIds, pathname)
 | 
			
		||||
                if (!res) toast({ title: "Oh dear...", description: "Failed to delete." })
 | 
			
		||||
                if (res) toast({ title: "Successfully deleted records of id:", description: JSON.stringify(recordIds) })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import { FormField, FormItem, FormLabel, FormMessage, FormControl, Form } from "
 | 
			
		|||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
 | 
			
		||||
import { Button } from "@/components/ui/button"
 | 
			
		||||
import { Checkbox } from "@/components/ui/checkbox"
 | 
			
		||||
import { ComponentProps, useState } from "react"
 | 
			
		||||
import { BaseSyntheticEvent, ComponentProps, EventHandler, useState } from "react"
 | 
			
		||||
import { EventType, useForm, UseFormReturn } from "react-hook-form"
 | 
			
		||||
import { CellContext } from "@tanstack/react-table"
 | 
			
		||||
import { z } from "zod"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,16 +16,18 @@ import { useRouter } from "next/navigation"
 | 
			
		|||
export default function GenrePickerInputCell(props: CellContext<any, any>) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const table = props.table.options.meta.tableName
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const pathname = props.table.options.meta.pathname
 | 
			
		||||
  const id = props.row.original.id
 | 
			
		||||
  const column = props.column.id
 | 
			
		||||
  const value = props.cell.getValue()
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const genres = props.table.options.meta.genres
 | 
			
		||||
  const [isActive, setIsActive] = useState(false)
 | 
			
		||||
  const router = useRouter()
 | 
			
		||||
  async function onSubmit({ genres }: { genres: number[] }, event: Event) {
 | 
			
		||||
  async function onSubmit({ genres }: { genres: number[] }, event: BaseSyntheticEvent) {
 | 
			
		||||
    event.preventDefault()
 | 
			
		||||
    try {
 | 
			
		||||
      const genresArray = genres.map((e) => { return { id: e } })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,11 +12,14 @@ import { Form, FormControl, FormField, FormItem, FormMessage } from "@/component
 | 
			
		|||
export default function NumberInputCell({ cellContext, className }: { cellContext: CellContext<any, any>, className: string }) {
 | 
			
		||||
  const [isActive, setIsActive] = useState(false)
 | 
			
		||||
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const table = cellContext.table.options.meta.tableName
 | 
			
		||||
  const id = cellContext.row.original.id
 | 
			
		||||
  const column = cellContext.column.id
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const pathname = cellContext.table.options.meta.pathname
 | 
			
		||||
  const value = cellContext.cell.getValue()
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const formSchema = cellContext.column.columnDef.meta.formSchema.pick({ [column]: true })
 | 
			
		||||
 | 
			
		||||
  const form = useForm<z.infer<typeof formSchema>>({
 | 
			
		||||
| 
						 | 
				
			
			@ -77,13 +80,8 @@ export default function NumberInputCell({ cellContext, className }: { cellContex
 | 
			
		|||
                >
 | 
			
		||||
                  <FormControl
 | 
			
		||||
                  >
 | 
			
		||||
                    <Input
 | 
			
		||||
                      className="md:w-24"
 | 
			
		||||
                      type="number"
 | 
			
		||||
                      autoFocus={true}
 | 
			
		||||
                      step={cellContext.column.columnDef.meta?.step}
 | 
			
		||||
                      {...field}
 | 
			
		||||
                    />
 | 
			
		||||
                    {/* @ts-ignore */}
 | 
			
		||||
                    <Input className="md:w-24" type="number" autoFocus={true} step={cellContext.column.columnDef.meta?.step} {...field} />
 | 
			
		||||
                  </FormControl>
 | 
			
		||||
                  <FormMessage />
 | 
			
		||||
                </FormItem>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,15 +13,14 @@ import { useRouter } from "next/navigation";
 | 
			
		|||
 | 
			
		||||
export function TextInputCell({ cellContext, className }: { className: string, cellContext: CellContext<any, any> }) {
 | 
			
		||||
  const [isActive, setIsActive] = useState(false)
 | 
			
		||||
  if (cellContext === undefined) {
 | 
			
		||||
    console.error("CELL CONTEXT UNDEFINED!")
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const table = cellContext.table.options.meta.tableName
 | 
			
		||||
  const id = cellContext.row.original.id
 | 
			
		||||
  const column = cellContext.column.id
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const pathname = cellContext.table.options.meta.pathname
 | 
			
		||||
  const value = cellContext.cell.getValue()
 | 
			
		||||
  //@ts-ignore
 | 
			
		||||
  const formSchema = cellContext.column.columnDef.meta.formSchema.pick({ [column]: true })
 | 
			
		||||
 | 
			
		||||
  const form = useForm<z.infer<typeof formSchema>>({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue