Skip to content

Commit

Permalink
4 multiples pdfs (#79)
Browse files Browse the repository at this point in the history
* update: uploadthing to latest

* checkpoint: form, api/post/create and dropzone ready. BD and PostView have to be adapted.

* add: new column in Post with correct values

* feat: all scripts adapted to urls

Maybe it is time to do files instead of urls

* refactor: urls (string[]) to files (File[])
  • Loading branch information
PauMatas committed Mar 26, 2024
1 parent 9228816 commit 09598cb
Show file tree
Hide file tree
Showing 17 changed files with 391 additions and 103 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,3 @@ next-env.d.ts

userbase.csv
pscale_dump_apunts-dades_main_20240310_112108
prisma/migrations
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"lint": "next lint",
"postinstall": "prisma generate",
"format": "prettier --write .",
"prepare": "husky"
"prepare": "husky",
"post-files-from-content": "node scripts/post-files-from-content.js"
},
"prisma": {
"seed": "node prisma/seed.js"
Expand Down Expand Up @@ -60,7 +61,7 @@
"@types/node": "20.2.5",
"@types/react": "18.2.7",
"@types/react-dom": "18.2.4",
"@uploadthing/react": "^4.1.3",
"@uploadthing/react": "^6.4.0",
"@upstash/redis": "^1.21.0",
"autoprefixer": "10.4.14",
"axios": "^1.4.0",
Expand All @@ -83,7 +84,7 @@
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.50.1",
"react-pdf": "^7.7.0",
"react-pdf": "^7.7.1",
"react-textarea-autosize": "^8.4.1",
"readline-sync": "^1.4.10",
"server-only": "^0.0.1",
Expand All @@ -93,7 +94,7 @@
"tailwindcss-animate": "^1.0.5",
"ts-node": "^9.1.1",
"typescript": "5.0.4",
"uploadthing": "^4.1.3",
"uploadthing": "^6.6.0",
"yarn": "^1.22.21",
"zod": "^3.22.4"
},
Expand Down
31 changes: 16 additions & 15 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ model User {
username String? @unique
generacio Int @default(2020)
image String?
isAdmin Boolean @default(false)
isAdmin Boolean @default(false)
accounts Account[]
sessions Session[]
posts Post[]
Expand Down Expand Up @@ -97,21 +97,22 @@ model Question {
}

model Post {
id String @id @default(cuid())
title String
content String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
subjectId String
authorId String
tipus TipusType
year Int
id String @id @default(cuid())
title String
content String?
files Json @default(dbgenerated())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
subjectId String
authorId String
tipus TipusType
year Int
isAnonymous Boolean @default(false)
NonUploaderAuthorEmail String?
isAnonymous Boolean @default(false)
subject Subject @relation(fields: [subjectId], references: [id])
author User @relation(fields: [authorId], references: [id])
comments Comment[]
votes PostVote[]
subject Subject @relation(fields: [subjectId], references: [id])
author User @relation(fields: [authorId], references: [id])
comments Comment[]
votes PostVote[]
@@index([title])
}
Expand Down
39 changes: 39 additions & 0 deletions scripts/post-files-from-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { PrismaClient } = require("@prisma/client")
const { default: axios } = require("axios")

const prisma = new PrismaClient()

async function updateRecords() {
try {
const recordsToUpdate = await prisma.Post.findMany()

for (const record of recordsToUpdate) {
const response = await axios.get(record.content, {
responseType: "blob",
})
const fileObject = new File([response.data], "PDF Sense Nom")

await prisma.Post.update({
where: { id: record.id },
data: {
files: JSON.stringify([
{
name: fileObject.name,
size: fileObject.size,
type: fileObject.type,
url: record.content,
},
]),
},
})
}

console.log("Records updated successfully.")
} catch (error) {
console.error("Error updating records:", error)
} finally {
await prisma.$disconnect()
}
}

updateRecords()
11 changes: 10 additions & 1 deletion src/app/api/subject/post/create/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ export async function POST(req: Request) {
await db.post.create({
data: {
title: title,
content: pdf,
files: JSON.stringify(
pdf.map((file) => {
return {
name: file.name,
size: file.size,
type: file.type,
url: file.url,
}
}),
),
subjectId: subject.id,
authorId: authorId,
tipus: tipus as TipusType,
Expand Down
3 changes: 0 additions & 3 deletions src/app/api/subject/post/vote/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export async function PATCH(req: Request) {
if (votesAmt >= CACHE_AFTER_UPVOTES) {
const cachePayload: CachedPost = {
authorName: post.author.name ?? "",
content: post.content ?? "",
id: post.id,
title: post.title,
currentVote: null,
Expand Down Expand Up @@ -99,7 +98,6 @@ export async function PATCH(req: Request) {
if (votesAmt >= CACHE_AFTER_UPVOTES) {
const cachePayload: CachedPost = {
authorName: post.author.name ?? "",
content: post.content ?? "",
id: post.id,
title: post.title,
currentVote: voteType,
Expand Down Expand Up @@ -131,7 +129,6 @@ export async function PATCH(req: Request) {
if (votesAmt >= CACHE_AFTER_UPVOTES) {
const cachePayload: CachedPost = {
authorName: post.author.name ?? "",
content: post.content ?? "",
id: post.id,
title: post.title,
currentVote: voteType,
Expand Down
27 changes: 7 additions & 20 deletions src/app/api/uploadthing/core.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,25 @@
import { createUploadthing, type FileRouter } from "uploadthing/next"
import { UploadThingError } from "@uploadthing/shared"
import { UploadThingError } from "uploadthing/server"
import { getToken } from "next-auth/jwt"

const f = createUploadthing()

// FileRouter for your app, can contain multiple FileRoutes
export const ourFileRouter = {
// Define as many FileRoutes as you like, each with a unique routeSlug
imageUploader: f({ image: { maxFileSize: "4MB" } })
// Set permissions and file types for this FileRoute
.middleware(async (req) => {
// This code runs on your server before upload
.middleware(async ({ req }) => {
const user = await getToken({ req })

// If you throw, the user will not be able to upload
if (!user)
throw new UploadThingError({
code: "FORBIDDEN",
message: "Unauthorized",
})

// Whatever is returned here is accessible in onUploadComplete as `metadata`
if (!user) throw new UploadThingError("Unauthorized")
return { userId: user.id }
})
.onUploadComplete(async ({}) => {}),

// Another FileRoute (made by myself, not by the library)
fileUploader: f({
pdf: { maxFileCount: 1, maxFileSize: "128MB" },
text: { maxFileCount: 5 },
pdf: { maxFileCount: 10, maxFileSize: "32MB" },
text: { maxFileCount: 10, maxFileSize: "32MB" },
})
.middleware(async (req) => {
.middleware(async ({ req }) => {
const user = await getToken({ req })
if (!user) throw new UploadThingError({ code: "FORBIDDEN" })
if (!user) throw new UploadThingError("Unauthorized")
return { userId: user.id }
})
.onUploadComplete(async ({}) => {}),
Expand Down
5 changes: 2 additions & 3 deletions src/app/api/uploadthing/route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { createNextRouteHandler } from "uploadthing/next"
import { createRouteHandler } from "uploadthing/next"

import { ourFileRouter } from "./core"

// Export routes for Next App Router
export const { GET, POST } = createNextRouteHandler({
export const { GET, POST } = createRouteHandler({
router: ourFileRouter,
})
23 changes: 12 additions & 11 deletions src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import { Checkbox } from "@/components/ui/checkbox"
import { ApuntsPostCreationRequest } from "@/lib/validators/post"
import { uploadFiles } from "@/lib/uploadthing"
import Fireworks from "react-canvas-confetti/dist/presets/fireworks"
import { MultiFileDropzone } from "@/components/MultiFileDropzone"

const formSchema = z.object({
pdf: z.any(),
pdf: z.array(z.any()),
title: z.string({
required_error: "Selecciona un títol",
}),
Expand All @@ -43,6 +44,7 @@ const formSchema = z.object({
required_error: "Selecciona un email",
}),
})
type FormSchemaType = z.infer<typeof formSchema>

export function ProfileForm({
PreselectedSubject,
Expand Down Expand Up @@ -123,10 +125,12 @@ export function ProfileForm({
form.setValue("authorEmail", "Uploader")
}
}, [form, isAdmin])
async function onSubmit(data: ApuntsPostCreationRequest) {
const [res] = await uploadFiles([data.pdf], "fileUploader")
async function onSubmit(data: FormSchemaType) {
const res = await uploadFiles("fileUploader", {
files: data.pdf,
})
const payload: ApuntsPostCreationRequest = {
pdf: res.fileUrl,
pdf: res,
title: data.title,
year: Number(data.year),
assignatura: data.assignatura,
Expand Down Expand Up @@ -233,13 +237,10 @@ export function ProfileForm({
<FormLabel>Fitxers PDF</FormLabel>
<FormControl>
<div className="grid w-full max-w-sm items-center gap-1.5">
<Input
id="pdf-file"
type="file"
onChange={(e) => {
if (e.target.files) {
field.onChange(e.target.files[0])
}
<MultiFileDropzone
value={field.value}
onChange={(acceptedFiles) => {
field.onChange(acceptedFiles)
}}
/>
</div>
Expand Down
Loading

0 comments on commit 09598cb

Please sign in to comment.