diff --git a/.env.development b/.env.development deleted file mode 100644 index 0ab01ef..0000000 --- a/.env.development +++ /dev/null @@ -1,14 +0,0 @@ -DATABASE_URL="postgresql://postgres:hackme@localhost:5432/opengifame" - - -UPLOAD_PATH=/srv/dev/opengifame/working/uploads -NEXTAUTH_SECRET="tAOVgxpY1U0BsnPCr6Gf8WVkmRMkp06ztUfwMhBKMQ4=" -NEXTAUTH_URL="https://opengifame.dev.fergl.ie:3000" - -NEXT_PUBLIC_DEBUG_MODE=1 -NEXT_PUBLIC_SITE_NAME=Open Gifame -NEXT_PUBLIC_SITE_DESCRIPTION=Robot powered giffage -NEXT_PUBLIC_SITE_URL=https://opengifame.dev.fergl.ie:3000 -NEXT_PUBLIC_SITE_OG_IMAGE=https://opengifame.dev.fergl.ie:3000/icon.png -NEXT_PUBLIC_SITE_TWITTER=https://twitter.com/opengifame -NEXT_PUBLIC_SITE_GITHUB=https://github.com/fergalmoran/opengifame diff --git a/.gitignore b/.gitignore index b15ed6a..0a29f41 100644 --- a/.gitignore +++ b/.gitignore @@ -34,8 +34,8 @@ yarn-error.log* # local env files # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables .env -.env*.local - +.env* +.notenv* # vercel .vercel diff --git a/bun.lockb b/bun.lockb index 19ad319..f2e884b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/drizzle/0000_dazzling_cerebro.sql b/drizzle/0000_dazzling_cerebro.sql deleted file mode 100644 index d6773fc..0000000 --- a/drizzle/0000_dazzling_cerebro.sql +++ /dev/null @@ -1,67 +0,0 @@ -CREATE TABLE IF NOT EXISTS "account" ( - "user_id" varchar(255) NOT NULL, - "type" varchar(255) NOT NULL, - "provider" varchar(255) NOT NULL, - "provider_account_id" varchar(255) NOT NULL, - "refresh_token" text, - "access_token" text, - "expires_at" integer, - "token_type" varchar(255), - "scope" varchar(255), - "id_token" text, - "session_state" varchar(255), - CONSTRAINT "account_provider_provider_account_id_pk" PRIMARY KEY("provider","provider_account_id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "post" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(256), - "created_by" varchar(255) NOT NULL, - "created_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updated_at" timestamp with time zone -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "session" ( - "session_token" varchar(255) PRIMARY KEY NOT NULL, - "user_id" varchar(255) NOT NULL, - "expires" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user" ( - "id" varchar(255) PRIMARY KEY NOT NULL, - "name" varchar(255), - "email" varchar(255) NOT NULL, - "email_verified" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, - "image" varchar(255), - "password" text -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "verification_token" ( - "identifier" varchar(255) NOT NULL, - "token" varchar(255) NOT NULL, - "expires" timestamp with time zone NOT NULL, - CONSTRAINT "verification_token_identifier_token_pk" PRIMARY KEY("identifier","token") -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "post" ADD CONSTRAINT "post_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -CREATE INDEX IF NOT EXISTS "account_user_id_idx" ON "account" USING btree ("user_id");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "created_by_idx" ON "post" USING btree ("created_by");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "name_idx" ON "post" USING btree ("name");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "session_user_id_idx" ON "session" USING btree ("user_id"); \ No newline at end of file diff --git a/drizzle/0001_wooden_ink.sql b/drizzle/0001_wooden_ink.sql deleted file mode 100644 index 53988e9..0000000 --- a/drizzle/0001_wooden_ink.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE IF NOT EXISTS "image" ( - "id" varchar(255) PRIMARY KEY NOT NULL, - "name" varchar, - "tags" text[], - "created_by" varchar(255) NOT NULL, - "created_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updated_at" timestamp with time zone -); ---> statement-breakpoint -ALTER TABLE "post" ALTER COLUMN "id" SET DATA TYPE varchar(255);--> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "image" ADD CONSTRAINT "image_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json deleted file mode 100644 index d2763f0..0000000 --- a/drizzle/meta/0000_snapshot.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "id": "3cde7a7b-e714-4d18-a93a-9e07c9e48f5a", - "prevId": "00000000-0000-0000-0000-000000000000", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "token_type": { - "name": "token_type", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_state": { - "name": "session_state", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "account_user_id_idx": { - "name": "account_user_id_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_provider_account_id_pk": { - "name": "account_provider_provider_account_id_pk", - "columns": [ - "provider", - "provider_account_id" - ] - } - }, - "uniqueConstraints": {} - }, - "public.post": { - "name": "post", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "created_by": { - "name": "created_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "CURRENT_TIMESTAMP" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "created_by_idx": { - "name": "created_by_idx", - "columns": [ - { - "expression": "created_by", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "name_idx": { - "name": "name_idx", - "columns": [ - { - "expression": "name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "post_created_by_user_id_fk": { - "name": "post_created_by_user_id_fk", - "tableFrom": "post", - "tableTo": "user", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "session_token": { - "name": "session_token", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "session_user_id_idx": { - "name": "session_user_id_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "CURRENT_TIMESTAMP" - }, - "image": { - "name": "image", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.verification_token": { - "name": "verification_token", - "schema": "", - "columns": { - "identifier": { - "name": "identifier", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verification_token_identifier_token_pk": { - "name": "verification_token_identifier_token_pk", - "columns": [ - "identifier", - "token" - ] - } - }, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json deleted file mode 100644 index dc4bec6..0000000 --- a/drizzle/meta/0001_snapshot.json +++ /dev/null @@ -1,418 +0,0 @@ -{ - "id": "01ae1334-57ff-4e93-8599-bdc2689aea71", - "prevId": "3cde7a7b-e714-4d18-a93a-9e07c9e48f5a", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "token_type": { - "name": "token_type", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_state": { - "name": "session_state", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "account_user_id_idx": { - "name": "account_user_id_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_provider_account_id_pk": { - "name": "account_provider_provider_account_id_pk", - "columns": [ - "provider", - "provider_account_id" - ] - } - }, - "uniqueConstraints": {} - }, - "public.image": { - "name": "image", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar", - "primaryKey": false, - "notNull": false - }, - "tags": { - "name": "tags", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "created_by": { - "name": "created_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "CURRENT_TIMESTAMP" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "image_created_by_user_id_fk": { - "name": "image_created_by_user_id_fk", - "tableFrom": "image", - "tableTo": "user", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.post": { - "name": "post", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "created_by": { - "name": "created_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "CURRENT_TIMESTAMP" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "created_by_idx": { - "name": "created_by_idx", - "columns": [ - { - "expression": "created_by", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "name_idx": { - "name": "name_idx", - "columns": [ - { - "expression": "name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "post_created_by_user_id_fk": { - "name": "post_created_by_user_id_fk", - "tableFrom": "post", - "tableTo": "user", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "session_token": { - "name": "session_token", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "session_user_id_idx": { - "name": "session_user_id_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "CURRENT_TIMESTAMP" - }, - "image": { - "name": "image", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.verification_token": { - "name": "verification_token", - "schema": "", - "columns": { - "identifier": { - "name": "identifier", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verification_token_identifier_token_pk": { - "name": "verification_token_identifier_token_pk", - "columns": [ - "identifier", - "token" - ] - } - }, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json deleted file mode 100644 index 7d3cb47..0000000 --- a/drizzle/meta/_journal.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "7", - "dialect": "postgresql", - "entries": [ - { - "idx": 0, - "version": "7", - "when": 1725454391060, - "tag": "0000_dazzling_cerebro", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1726068700784, - "tag": "0001_wooden_ink", - "breakpoints": true - } - ] -} \ No newline at end of file diff --git a/next.config.js b/next.config.js index 5fa34bd..e0a7c57 100644 --- a/next.config.js +++ b/next.config.js @@ -7,11 +7,13 @@ await import("./src/env.js"); /** @type {import("next").NextConfig} */ const config = { images: { - domains: ["localhost"], remotePatterns: [ { hostname: "avatars.githubusercontent.com", }, + { + hostname: "localhost", + }, ], }, }; diff --git a/package.json b/package.json index a95e969..4476248 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "start": "next start" }, "dependencies": { - "@auth/drizzle-adapter": "^1.4.2", + "@auth/drizzle-adapter": "^1.5.0", "@headlessui/react": "^2.1.8", "@hookform/resolvers": "^3.9.0", "@radix-ui/react-accordion": "^1.2.0", @@ -61,7 +61,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "1.0.0", - "date-fns": "^3.6.0", + "date-fns": "^4.0.0", "drizzle-orm": "^0.33.0", "embla-carousel-react": "^8.3.0", "geist": "^1.3.1", @@ -81,29 +81,29 @@ "react-dom": "^18.3.1", "react-hook-form": "^7.53.0", "react-icons": "^5.3.0", - "react-resizable-panels": "^2.1.2", + "react-resizable-panels": "^2.1.3", "recharts": "^2.12.7", "server-only": "^0.0.1", "sonner": "^1.5.0", "superjson": "^2.2.1", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", - "vaul": "^0.9.2", + "vaul": "^0.9.3", "zod": "^3.23.8" }, "devDependencies": { - "@faker-js/faker": "^9.0.0", - "@types/eslint": "^8.56.10", - "@types/node": "^22.5.4", - "@types/react": "^18.3.5", + "@faker-js/faker": "^9.0.1", + "@types/eslint": "^9.6.1", + "@types/node": "^22.5.5", + "@types/react": "^18.3.6", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.1.0", - "@typescript-eslint/parser": "^8.1.0", + "@typescript-eslint/eslint-plugin": "^8.5.0", + "@typescript-eslint/parser": "^8.5.0", "drizzle-kit": "^0.24.2", - "eslint": "^8.57.0", - "eslint-config-next": "^14.2.4", + "eslint": "^9.10.0", + "eslint-config-next": "^14.2.11", "eslint-plugin-drizzle": "^0.2.3", - "postcss": "^8.4.45", + "postcss": "^8.4.47", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.6", "tailwindcss": "^3.4.11", diff --git a/scripts/reset.sh b/scripts/reset.sh new file mode 100755 index 0000000..86657ac --- /dev/null +++ b/scripts/reset.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +export PGUSER=postgres +export PGPASSWORD=hackme +export PGHOST=localhost + +echo Removing migrations +rm -rf drizzle +echo "Dropping db" + +dropdb -f --if-exists opengifame +echo "Creating db" +createdb opengifame + +source .env.development +bun run db:generate +bun run db:push + +rm /srv/dev/opengifame/working/uploads/* -rfv +# # bun run src/db/migrate.ts +# bun run ./src/server/db/scripts/seed.ts +# bun run ./src/server/db/scripts/auth.ts diff --git a/src/app/api/upload/post/route.ts b/src/app/api/upload/post/route.ts index 7ecced6..817f7bc 100644 --- a/src/app/api/upload/post/route.ts +++ b/src/app/api/upload/post/route.ts @@ -2,6 +2,13 @@ import { getServerSession } from "next-auth"; import { StatusCodes } from "http-status-codes"; import { env } from "@/env"; import { type NextRequest, NextResponse } from "next/server"; +import fs from "fs"; +import { pipeline } from "stream"; +import { promisify } from "util"; +import path from "path"; +import { FilePen } from "lucide-react"; +import { fileURLToPath } from "url"; +const pump = promisify(pipeline); export async function POST(request: NextRequest) { const session = await getServerSession(); @@ -12,15 +19,31 @@ export async function POST(request: NextRequest) { status: StatusCodes.UNAUTHORIZED, }); } - const searchParams = request.nextUrl.searchParams; - const id = searchParams.get("id"); + const id = request.nextUrl.searchParams.get("id"); - const uploadDir = env.UPLOAD_PATH; - return Response.json( - { - id, - session, - uploadDir, - } - ); + if (!id) { + return NextResponse.json({ + error: "No post id in query", + status: StatusCodes.BAD_REQUEST, + }); + } + const formData = await request.formData(); + const body = Object.fromEntries(formData); + const file = (body.image as Blob) || null; + + if (file) { + const buffer = Buffer.from(await file.arrayBuffer()); + const extension = path.extname((body.image as File).name); + const filePath = `${id}${extension}`; + + fs.writeFileSync(path.resolve(env.UPLOAD_PATH, filePath), buffer); + return NextResponse.json({ + success: true, + url: env.NEXT_PUBLIC_SITE_URL + `/i/${filePath}`, + }); + } + return NextResponse.json({ + error: "Cannot find file in form data", + status: StatusCodes.BAD_REQUEST, + }); } diff --git a/src/components/pages/landing-page.tsx b/src/components/pages/landing-page.tsx index b58d3cb..2115222 100644 --- a/src/components/pages/landing-page.tsx +++ b/src/components/pages/landing-page.tsx @@ -3,10 +3,10 @@ import React from "react"; const LandingPage: React.FC = () => { return (
-
-

- Warning contains{" "} - Gifs +
+

+ Contains + Gifs

diff --git a/src/components/pages/upload-page.tsx b/src/components/pages/upload-page.tsx index 8b0b4ed..4430676 100644 --- a/src/components/pages/upload-page.tsx +++ b/src/components/pages/upload-page.tsx @@ -19,6 +19,8 @@ import { env } from "@/env"; import { logger } from "@/lib/logger"; import { api } from "@/trpc/react"; import { STATUS_CODES } from "http"; +import { StatusCodes } from "http-status-codes"; +import { z } from "zod"; type FormValues = { title: string; @@ -38,6 +40,21 @@ const UploadPage: React.FC = () => { image: undefined, }, }); + + // const imageSchema = z.object({ + // image: z + // .any() + // .refine((file) => { + // if (file.size === 0 || file.name === undefined) return false; + // else return true; + // }, "Please update or add new image.") + + // .refine( + // (file) => ACCEPTED_IMAGE_TYPES.includes(file?.type), + // ".jpg, .jpeg, .png and .webp files are accepted.", + // ) + // .refine((file) => file.size <= MAX_FILE_SIZE, `Max file size is 5MB.`), + // }); const createImage = api.image.create.useMutation({ onSuccess: async (e) => { console.log("upload-page", "onSuccess", e); @@ -45,13 +62,16 @@ const UploadPage: React.FC = () => { if (e.id && file) { const body = new FormData(); body.set("image", file); - const response = await fetch(`/api/upload/profile-image?${e.id}`, { + const response = await fetch(`/api/upload/post?id=${e.id}`, { method: "POST", body, }); - - await utils.image.invalidate(); - router.replace("/"); + if (response.status === StatusCodes.CREATED) { + await utils.image.invalidate(); + router.replace("/"); + } + logger.error("upload-page", "createImage", response.statusText); + throw new Error(response.statusText); } else { //TODO: Probably need to delete the image from the database logger.error("upload-page", "onSuccess", "Error uploading image"); diff --git a/src/components/trending-images.tsx b/src/components/trending-images.tsx index a552404..3470e1c 100644 --- a/src/components/trending-images.tsx +++ b/src/components/trending-images.tsx @@ -3,7 +3,6 @@ import { useState } from "react"; import { api } from "@/trpc/react"; -import ImageUpload from "./widgets/image-upload"; export function TrendingImages() { const [latestPost] = api.post.getLatest.useSuspenseQuery(); diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..1cc5c34 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,5 @@ +export { default } from "next-auth/middleware"; + +export const config = { + matcher: ["/upload(.*)"], +}; diff --git a/src/server/api/routers/post.ts b/src/server/api/routers/post.ts index 011a10c..a398eaa 100644 --- a/src/server/api/routers/post.ts +++ b/src/server/api/routers/post.ts @@ -27,7 +27,7 @@ export const postRouter = createTRPCRouter({ }), getLatest: publicProcedure.query(async ({ ctx }) => { - const post = await ctx.db.query.posts.findFirst({ + const post = await ctx.db.query.images.findMany({ orderBy: (posts, { desc }) => [desc(posts.createdAt)], }); diff --git a/src/server/db/index.ts b/src/server/db/index.ts index 8cc0d71..7620318 100644 --- a/src/server/db/index.ts +++ b/src/server/db/index.ts @@ -11,7 +11,6 @@ import * as schema from "./schema"; const globalForDb = globalThis as unknown as { conn: postgres.Sql | undefined; }; - export const connection = globalForDb.conn ?? postgres(env.DATABASE_URL); if (env.NODE_ENV !== "production") globalForDb.conn = connection;