diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2f28b36b0..995dbf19f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -86,14 +86,6 @@ Thank you for your interest in contributing to OpenCut! This document provides g # Or use an online generator: https://generate-secret.vercel.app/32 ``` - **Optional Variables (for Google OAuth):** - - ```bash - # Only needed if you want to test Google login - GOOGLE_CLIENT_ID="your-google-client-id" - GOOGLE_CLIENT_SECRET="your-google-client-secret" - ``` - 5. Run database migrations: `bun run db:migrate` 6. Start the development server: `bun run dev` diff --git a/README.md b/README.md index 30fc43a60..6d3937a7f 100644 --- a/README.md +++ b/README.md @@ -124,14 +124,6 @@ Before you begin, ensure you have the following installed on your system: # Or use an online generator: https://generate-secret.vercel.app/32 ``` - **Optional Variables (for Google OAuth):** - - ```bash - # Only needed if you want to test Google login - GOOGLE_CLIENT_ID="your-google-client-id" - GOOGLE_CLIENT_SECRET="your-google-client-secret" - ``` - 5. Run database migrations: `bun run db:migrate` from (inside apps/web) 6. Start the development server: `bun run dev` from (inside apps/web) @@ -155,6 +147,10 @@ We welcome contributions! Please see our [Contributing Guide](.github/CONTRIBUTI Thanks to [Vercel](https://vercel.com?utm_source=github-opencut&utm_campaign=oss) for their support of open-source software. + + Vercel OSS Program + + [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FOpenCut-app%2FOpenCut&project-name=opencut&repository-name=opencut) ## License diff --git a/apps/web/.env.example b/apps/web/.env.example index 834171a02..d63df851e 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -7,10 +7,6 @@ DATABASE_URL="postgresql://opencut:opencutthegoat@localhost:5432/opencut" NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3000 BETTER_AUTH_SECRET=your-secret-key-here -#Google Clients -GOOGLE_CLIENT_ID= -GOOGLE_CLIENT_SECRET= - # Development Environment NODE_ENV=development diff --git a/apps/web/drizzle.config.ts b/apps/web/drizzle.config.ts index 615eea570..87547bd04 100644 --- a/apps/web/drizzle.config.ts +++ b/apps/web/drizzle.config.ts @@ -1,23 +1,20 @@ import type { Config } from "drizzle-kit"; import * as dotenv from "dotenv"; +import { env } from "@/env"; // Load the right env file based on environment -if (process.env.NODE_ENV === "production") { +if (env.NODE_ENV === "production") { dotenv.config({ path: ".env.production" }); } else { dotenv.config({ path: ".env.local" }); } -if (!process.env.DATABASE_URL) { - throw new Error("DATABASE_URL is not set"); -} - export default { schema: "../../packages/db/src/schema.ts", dialect: "postgresql", dbCredentials: { - url: process.env.DATABASE_URL, + url: env.DATABASE_URL, }, out: "./migrations", - strict: process.env.NODE_ENV === "production", + strict: env.NODE_ENV === "production", } satisfies Config; diff --git a/apps/web/migrations/0002_cuddly_pretty_boy.sql b/apps/web/migrations/0002_cuddly_pretty_boy.sql new file mode 100644 index 000000000..fc8aed796 --- /dev/null +++ b/apps/web/migrations/0002_cuddly_pretty_boy.sql @@ -0,0 +1 @@ +ALTER TABLE "users" ALTER COLUMN "email_verified" SET DEFAULT false; \ No newline at end of file diff --git a/apps/web/migrations/meta/0002_snapshot.json b/apps/web/migrations/meta/0002_snapshot.json new file mode 100644 index 000000000..9155d9714 --- /dev/null +++ b/apps/web/migrations/meta/0002_snapshot.json @@ -0,0 +1,359 @@ +{ + "id": "1b9148ed-497b-4e53-8cf6-f556c8fe7f7f", + "prevId": "b7d920ca-6dd0-430f-8ee6-1d38fdf3e80f", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.accounts": { + "name": "accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "accounts_user_id_users_id_fk": { + "name": "accounts_user_id_users_id_fk", + "tableFrom": "accounts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sessions_token_unique": { + "name": "sessions_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.verifications": { + "name": "verifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.waitlist": { + "name": "waitlist", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "waitlist_email_unique": { + "name": "waitlist_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/web/migrations/meta/_journal.json b/apps/web/migrations/meta/_journal.json index 9cbceb13c..309c040e0 100644 --- a/apps/web/migrations/meta/_journal.json +++ b/apps/web/migrations/meta/_journal.json @@ -15,6 +15,13 @@ "when": 1750689835736, "tag": "0001_tricky_jackpot", "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1752569400809, + "tag": "0002_cuddly_pretty_boy", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index 4e5018202..07b36dcb0 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -21,6 +21,8 @@ "@hookform/resolvers": "^3.9.1", "@opencut/auth": "workspace:*", "@opencut/db": "workspace:*", + "@t3-oss/env-core": "^0.13.8", + "@t3-oss/env-nextjs": "^0.13.8", "@upstash/ratelimit": "^2.0.5", "@upstash/redis": "^1.35.0", "@vercel/analytics": "^1.4.1", @@ -36,7 +38,7 @@ "input-otp": "^1.4.1", "lucide-react": "^0.468.0", "motion": "^12.18.1", - "next": "^15.3.4", + "next": "^15.4.1", "next-themes": "^0.4.4", "pg": "^8.16.2", "radix-ui": "^1.4.2", @@ -45,6 +47,7 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.54.0", "react-icons": "^5.4.0", + "react-markdown": "^10.1.0", "react-phone-number-input": "^3.4.11", "react-resizable-panels": "^2.1.7", "recharts": "^2.14.1", diff --git a/apps/web/public/opengraph-image.jpg b/apps/web/public/open-graph/default.jpg similarity index 100% rename from apps/web/public/opengraph-image.jpg rename to apps/web/public/open-graph/default.jpg diff --git a/apps/web/public/open-graph/roadmap.jpg b/apps/web/public/open-graph/roadmap.jpg new file mode 100644 index 000000000..63374c4f6 Binary files /dev/null and b/apps/web/public/open-graph/roadmap.jpg differ diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 71716e74b..9ac54262f 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -4,7 +4,6 @@ import Script from "next/script"; import "./globals.css"; import { Toaster } from "../components/ui/sonner"; import { TooltipProvider } from "../components/ui/tooltip"; -import { DevelopmentDebug } from "../components/development-debug"; import { StorageProvider } from "../components/storage-provider"; import { baseMetaData } from "./metadata"; import { defaultFont } from "../lib/font-config"; @@ -24,7 +23,6 @@ export default function RootLayout({ {children} -