diff --git a/.ncurc.json b/.ncurc.json index da849a4..e5e676e 100644 --- a/.ncurc.json +++ b/.ncurc.json @@ -1,3 +1,10 @@ { - "reject": ["eslint"] - } \ No newline at end of file + "reject": [ + "eslint", + "typescript", + "@types/eslint", + "@typescript-eslint/eslint-plugin", + "@typescript-eslint/parser", + "eslint-config-next" + ] +} diff --git a/bun.lockb b/bun.lockb index 0b87a8e..1598962 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components.json b/components.json index 97caaf1..01a0b42 100644 --- a/components.json +++ b/components.json @@ -13,7 +13,6 @@ "aliases": { "components": "@/components", "utils": "@/lib/utils", - "ui": "@/components/ui", - "magicui": "@/components/magicui" + "ui": "@/components/ui" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 35e984f..d027285 100644 --- a/package.json +++ b/package.json @@ -100,21 +100,25 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/eslint": "^8.56.10", + + "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/parser": "^8.1.0", + "eslint": "^8.57.0", + "eslint-config-next": "^14.2.4", + "eslint-plugin-drizzle": "^0.2.3", + + + "@faker-js/faker": "^9.0.3", "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.1", "@types/bun": "latest", - "@types/eslint": "^9.6.1", "@types/jest": "^29.5.13", "@types/node": "^22.7.4", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.7.0", - "@typescript-eslint/parser": "^8.7.0", "drizzle-kit": "^0.24.2", - "eslint": "8.57.0", - "eslint-config-next": "^14.2.13", - "eslint-plugin-drizzle": "^0.2.3", "jest": "^29.7.0", "postcss": "^8.4.47", "prettier": "^3.3.3", @@ -122,7 +126,7 @@ "tailwindcss": "^3.4.13", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "^5.6.2" + "typescript": "^5.5.3" }, "ct3aMetadata": { "initVersion": "7.37.0" diff --git a/src/app/api/upload/post/route.test.ts b/src/app/api/upload/post/route.test.ts deleted file mode 100644 index 5c8b990..0000000 --- a/src/app/api/upload/post/route.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { POST } from "./route"; -import { NextRequest, NextResponse } from "next/server"; -import { StatusCodes } from "http-status-codes"; -import fs from "fs"; -import path from "path"; -import { env } from "@/env"; -const mockGetServerSession = require("next-auth").getServerSession; - -jest.mock("next-auth", () => ({ - getServerSession: jest.fn(), -})); - -jest.mock("fs"); -jest.mock("path"); - -describe("POST /api/upload/post", () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it("should return UNAUTHORIZED if session is not found", async () => { - mockGetServerSession.mockResolvedValue(null); - - const request = new NextRequest( - new URL(`${env.NEXT_PUBLIC_SITE_URL}/api/upload/post`), - ); - const response = await POST(request); - - expect(response).toEqual( - NextResponse.json({ - error: "Unauthorized", - status: StatusCodes.UNAUTHORIZED, - }), - ); - }); - - it("should return BAD_REQUEST if id is not provided", async () => { - mockGetServerSession.mockResolvedValue({ user: { name: "test" } }); - - const request = new NextRequest( - new URL(`${env.NEXT_PUBLIC_SITE_URL}/api/upload/post`), - ); - const response = await POST(request); - - expect(response).toEqual( - NextResponse.json({ - error: "No post id in query", - status: StatusCodes.BAD_REQUEST, - }), - ); - }); - - it("should return BAD_REQUEST if file is not found in form data", async () => { - mockGetServerSession.mockResolvedValue({ user: { name: "test" } }); - - const url = new URL(`${env.NEXT_PUBLIC_SITE_URL}/api/upload/post?id=123`); - const request = new NextRequest(url); - request.formData = jest.fn().mockResolvedValue(new FormData()); - - const response = await POST(request); - - expect(response).toEqual( - NextResponse.json({ - error: "Cannot find file in form data", - status: StatusCodes.BAD_REQUEST, - }), - ); - }); - - it("should save the file and return success response", async () => { - mockGetServerSession.mockResolvedValue({ user: { name: "test" } }); - - const url = new URL(`${env.NEXT_PUBLIC_SITE_URL}/api/upload/post?id=123`); - const request = new NextRequest(url); - - const file = new Blob(["file content"], { type: "image/png" }); - const formData = new FormData(); - formData.append("image", file, "test.png"); - - request.formData = jest.fn().mockResolvedValue(formData); - - const buffer = Buffer.from(await file.arrayBuffer()); - const filePath = "123.png"; - - jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {}); - jest.spyOn(path, 'resolve').mockReturnValue(`/mocked/path/${filePath}`); - - const response = await POST(request); - - expect(fs.writeFileSync).toHaveBeenCalledWith( - `/mocked/path/${filePath}`, - buffer, - ); - expect(response).toEqual( - NextResponse.json({ - success: true, - url: env.NEXT_PUBLIC_SITE_URL + `/i/${filePath}`, - }), - ); - }); -}); diff --git a/src/components/magicui/bento-grid.tsx b/src/components/magicui/bento-grid.tsx deleted file mode 100644 index 342a957..0000000 --- a/src/components/magicui/bento-grid.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { ReactNode } from "react"; -import { ArrowRightIcon } from "@radix-ui/react-icons"; - -import { cn } from "@/lib/utils"; -import { Button } from "@/components/ui/button"; - -const BentoGrid = ({ - children, - className, -}: { - children: ReactNode; - className?: string; -}) => { - return ( -
- {children} -
- ); -}; - -const BentoCard = ({ - name, - className, - background, - Icon, - description, - href, - cta, -}: { - name: string; - className: string; - background: ReactNode; - Icon: any; - description: string; - href: string; - cta: string; -}) => ( -
-
{background}
-
- -

- {name} -

-

{description}

-
- -
- -
-
-
-); - -export { BentoCard, BentoGrid }; diff --git a/src/components/magicui/blur-in.tsx b/src/components/magicui/blur-in.tsx deleted file mode 100644 index 8014883..0000000 --- a/src/components/magicui/blur-in.tsx +++ /dev/null @@ -1,39 +0,0 @@ -"use client"; - -import { motion } from "framer-motion"; - -import { cn } from "@/lib/utils"; - -interface BlurIntProps { - word: string; - className?: string; - variant?: { - hidden: { filter: string; opacity: number }; - visible: { filter: string; opacity: number }; - }; - duration?: number; -} -const BlurIn = ({ word, className, variant, duration = 1 }: BlurIntProps) => { - const defaultVariants = { - hidden: { filter: "blur(10px)", opacity: 0 }, - visible: { filter: "blur(0px)", opacity: 1 }, - }; - const combinedVariants = variant || defaultVariants; - - return ( - - {word} - - ); -}; - -export default BlurIn; diff --git a/src/components/pages/post/post-actions.tsx b/src/components/pages/post/post-actions.tsx index a06b20a..89492aa 100644 --- a/src/components/pages/post/post-actions.tsx +++ b/src/components/pages/post/post-actions.tsx @@ -27,7 +27,7 @@ const PostActions: React.FC = ({ post }) => { title="Downvote" action={async () => { await vote.mutateAsync({ slug: post.slug, up: false }); - voteCount.refetch(); + await voteCount.refetch(); }} icon={} /> @@ -35,7 +35,7 @@ const PostActions: React.FC = ({ post }) => { title="Favourite" action={async () => { await vote.mutateAsync({ slug: post.slug, up: false }); - voteCount.refetch(); + await voteCount.refetch(); }} icon={} /> diff --git a/src/components/trending-posts.tsx b/src/components/trending-posts.tsx index efa0b06..f1d1694 100644 --- a/src/components/trending-posts.tsx +++ b/src/components/trending-posts.tsx @@ -1,8 +1,7 @@ import { api } from "@/trpc/server"; -import BlurIn from "./magicui/blur-in"; import Link from "next/link"; import { Icons } from "./icons"; -import { Post } from "@/lib/models/post"; +import { type Post } from "@/lib/models/post"; import { Card, CardContent, @@ -12,14 +11,15 @@ import { } from "@/components/ui/card"; import { Button } from "./ui/button"; import VoteCount from "./widgets/vote-count"; +import Loading from "@/components/widgets/loading"; export const TrendingPosts: React.FC = async () => { const trendingPosts = await api.post.getTrending(); return trendingPosts.length !== 0 ? (
{trendingPosts.map((post: Post) => ( -
- +
+ { ))}
) : ( - + ); }; diff --git a/src/components/widgets/vote-count.tsx b/src/components/widgets/vote-count.tsx index d5bd1f3..1ff3d36 100644 --- a/src/components/widgets/vote-count.tsx +++ b/src/components/widgets/vote-count.tsx @@ -14,6 +14,7 @@ const VoteCount: React.FC = ({ post }) => { return ( {voteCount.data ? ( + // eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions `${voteCount.data.voteCount} votes` ) : ( diff --git a/src/middleware.ts b/src/middleware.ts index 4fc1e81..22eb901 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,38 +1,38 @@ -import { NextRequest, NextResponse, URLPattern } from "next/server"; +// import { type NextRequest, NextResponse, URLPattern } from "next/server"; export { default } from "next-auth/middleware"; -export const config = { - matcher: ["/upload(.*)", "/i/:id(.*)"], -}; -const PATTERNS: [ - URLPattern, - ({ pathname }: { pathname: { groups: any } }) => any, -][] = [ - [ - new URLPattern({ pathname: "/i/:id" }), - ({ pathname }: { pathname: { groups: any } }) => pathname.groups, - ], -]; +// export const config = { +// matcher: ["/upload(.*)", "/i/:id(.*)"], +// }; +// const PATTERNS: [ +// URLPattern, +// ({ pathname }: { pathname: { groups: any } }) => any, +// ][] = [ +// [ +// new URLPattern({ pathname: "/i/:id" }), +// ({ pathname }: { pathname: { groups: any } }) => pathname.groups, +// ], +// ]; -const params = (url: string) => { - const input = url.split("?")[0]; - let result = {}; +// const params = (url: string) => { +// const input = url.split("?")[0]; +// let result = {}; - for (const [pattern, handler] of PATTERNS) { - if (!pattern) return; - const patternResult = pattern.exec(input); - if (patternResult !== null && "pathname" in patternResult) { - result = handler(patternResult); - break; - } - } - return result || {}; -}; -export async function middleware(request: NextRequest, response: NextResponse) { - const { id } = params(request.url) as { id?: string }; - if (!id) { - return NextResponse.next(); - } - return NextResponse.rewrite(new URL(`/uploads/${id}`, request.url)); -} +// for (const [pattern, handler] of PATTERNS) { +// if (!pattern) return; +// const patternResult = pattern.exec(input); +// if (patternResult !== null && "pathname" in patternResult) { +// result = handler(patternResult); +// break; +// } +// } +// return result || {}; +// }; +// export async function middleware(request: NextRequest, response: NextResponse) { +// const { id } = params(request.url) as { id?: string }; +// if (!id) { +// return NextResponse.next(); +// } +// return NextResponse.rewrite(new URL(`/uploads/${id}`, request.url)); +// }