Skip to content

Commit

Permalink
Merge pull request #63 from hubcio2115/feat/create-project-form-youtube
Browse files Browse the repository at this point in the history
Feat/create-project-form-youtube
  • Loading branch information
hubcio2115 committed Sep 5, 2024
2 parents d4a422e + 6c1930f commit c670a1e
Show file tree
Hide file tree
Showing 67 changed files with 4,640 additions and 2,744 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.7.0
10 changes: 1 addition & 9 deletions apps/web/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# secrets in it. If you are cloning this repo, create a copy of this file named
# ".env" and populate it with your secrets.

# When adding additional environment variables, the schema in "/src/env.mjs"
# When adding additional environment variables, the schema in "/src/env.ts"
# should be updated accordingly.

NEXT_PUBLIC_API_URL="http://localhost:3000"
Expand All @@ -28,11 +28,3 @@ AUTH_GOOGLE_ID=""
AUTH_GOOGLE_SECRET=""

YOUTUBE_DATA_API_KEY=""

# Mux secrets
MUX_TOKEN_ID=""
MUX_TOKEN_SECRET=""

# Secret for communication with our webhook
MUX_WEBHOOK_SECRET=""
# URL for mux cors
8 changes: 0 additions & 8 deletions apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@ To start you'll need:
- `[email protected]`
- run `pnpm install`
- copy `.env.local.example` in `./apps/web` and rename it to `.env.local`

### Webhooks
We're using [Mux](https://www.mux.com/) for storing, uploading and preprocessing videos.
For *Mux* to communicate with our app it needs a webhook. But for localdevelopment
it doesn't have access to our local ip address. To fix that you'll need to forward your port to
the web.

We recommend [ngrok](https://ngrok.com/) for that. You can also figure it our yourself. :)
2 changes: 1 addition & 1 deletion apps/web/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from "drizzle-kit";

import { env } from "~/env.mjs";
import { env } from "~/env";

export default defineConfig({
schema: "./src/server/db/schema.ts",
Expand Down
13 changes: 3 additions & 10 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fileURLToPath } from "url";
import createJiti from "jiti";
const jiti = createJiti(fileURLToPath(import.meta.url));

jiti('./src/env');
jiti("./src/env.ts");

/** @type {import("next").NextConfig} */
const config = {
Expand All @@ -15,19 +15,12 @@ const config = {
remotePatterns: [
{
protocol: "https",
hostname: "i.ytimg.com",
hostname: "yt3.ggpht.com",
port: "",
pathname: "/vi/**",
pathname: "/ytc/**",
},
],
},
redirects: async () => [
{
source: "/dashboard/:name",
destination: "/dashboard/:name/overview",
permanent: true,
},
],
};

export default config;
72 changes: 40 additions & 32 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,77 +9,85 @@
"studio": "dotenv drizzle-kit studio",
"dev": "next dev",
"dev:turbo": "next dev --turbo",
"typecheck": "tsc --noEmit",
"lint": "next lint",
"test": "vitest",
"start": "next start"
},
"dependencies": {
"@auth/drizzle-adapter": "^0.8.2",
"@hookform/resolvers": "^3.6.0",
"@mux/mux-node": "^8.8.0",
"@mux/mux-uploader-react": "1.0.0-beta.17",
"@auth/drizzle-adapter": "^1.4.2",
"@googleapis/youtube": "^19.0.0",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
"@t3-oss/env-nextjs": "^0.10.1",
"@tanstack/react-query": "^5.49.2",
"@tanstack/react-query-devtools": "^5.49.2",
"@tanstack/react-query": "^5.51.23",
"@tanstack/react-query-devtools": "^5.51.23",
"@total-typescript/ts-reset": "^0.5.1",
"@vercel/postgres": "^0.8.0",
"@vercel/postgres": "^0.9.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"dotenv": "^16.4.5",
"drizzle-orm": "^0.30.10",
"drizzle-orm": "^0.33.0",
"drizzle-zod": "^0.5.1",
"geist": "^1.3.0",
"geist": "^1.3.1",
"google-auth-library": "^9.14.0",
"jiti": "^1.21.6",
"lucide-react": "^0.290.0",
"next": "^14.2.4",
"ky": "^1.7.1",
"lucide-react": "^0.412.0",
"next": "^14.2.5",
"next-auth": "5.0.0-beta.19",
"next-themes": "^0.2.1",
"next-themes": "^0.3.0",
"pg": "^8.12.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.52.0",
"tailwind-merge": "^1.14.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-hook-form": "^7.52.2",
"tailwind-merge": "^2.5.1",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
},
"devDependencies": {
"@softonus/prettier-plugin-whitespace-remover": "^1.0.1",
"@testing-library/react": "^14.3.1",
"@testing-library/react": "^16.0.0",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/eslint": "^8.56.10",
"@types/node": "20.8.9",
"@types/eslint": "^8.56.11",
"@types/node": "20.14.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"autoprefixer": "^10.4.20",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.21.4",
"drizzle-kit": "^0.24.0",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.4",
"eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-drizzle": "^0.2.3",
"eslint-plugin-prettier": "^5.1.3",
"jsdom": "^24.1.0",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.5.14",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2",
"vitest": "^1.6.0"
"eslint-plugin-prettier": "^5.2.1",
"jsdom": "^24.1.1",
"postcss": "^8.4.41",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.6",
"tailwindcss": "^3.4.9",
"typescript": "^5.5.4",
"vitest": "^2.0.5"
},
"ct3aMetadata": {
"initVersion": "7.20.2"
Expand Down
29 changes: 29 additions & 0 deletions apps/web/src/app/api/organizations/[name]/owner-channels/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NextRequest, NextResponse } from "next/server";
import { isUserInOrganization } from "~/server/api/utils/organizations";
import { getOwnerChannels } from "~/server/api/utils/project";
import { auth } from "~/server/auth";

export async function GET(
_req: NextRequest,
{ params }: { params: { name: string } },
) {
const session = await auth();

const isUserAuthorized =
session?.user && (await isUserInOrganization(session.user.id, params.name));

if (!isUserAuthorized) {
return NextResponse.json({ message: "UNAUTHORIZED" }, { status: 401 });
}

const [channels, err] = await getOwnerChannels(params.name);

if (err !== null) {
return NextResponse.json(
{ message: "Something went wrong on our end", cause: err },
{ status: 500 },
);
}

return NextResponse.json(channels);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "~/server/actions/organization";

export async function GET(
req: NextRequest,
_req: NextRequest,
{ params }: { params: { name: string } },
) {
const [organization, err] = await getOwnOrganizationByName(params.name);
Expand Down
58 changes: 0 additions & 58 deletions apps/web/src/app/api/webhooks/mux/route.ts

This file was deleted.

22 changes: 22 additions & 0 deletions apps/web/src/app/api/youtube/categories/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { NextResponse } from "next/server";
import { getYoutubeCategories } from "~/server/api/utils/project";
import { auth } from "~/server/auth";

export async function GET() {
const session = auth();

if (!session) {
return NextResponse.json({ message: "UNAUTHORIZED" }, { status: 401 });
}

const [categories, err] = await getYoutubeCategories();

if (err !== null) {
return NextResponse.json(
{ message: "Something went wrong on our end", cause: err },
{ status: 500 },
);
}

return NextResponse.json(categories);
}
22 changes: 22 additions & 0 deletions apps/web/src/app/api/youtube/languages/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { NextResponse } from "next/server";
import { getYoutubeSupportedLanguages } from "~/server/api/utils/project";
import { auth } from "~/server/auth";

export async function GET() {
const session = auth();

if (!session) {
return NextResponse.json({ message: "UNAUTHORIZED" }, { status: 401 });
}

const [languages, err] = await getYoutubeSupportedLanguages();

if (err !== null) {
return NextResponse.json(
{ message: "Something went wrong on our end", cause: err },
{ status: 500 },
);
}

return NextResponse.json(languages);
}
43 changes: 23 additions & 20 deletions apps/web/src/app/dashboard/[name]/create-project/page.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import VideUploadForm from "~/components/create-project/create-project-form";
import { createEndpointForMuxUpload } from "~/server/actions/mux";
import { getOwnOrganizationByName } from "~/server/actions/organization";
"use client";

type CreateProjectPageProps = {
params: {
name: string;
};
};
import { useRouter } from "next/navigation";
import ProjectForm from "~/components/create-project/project-form";
import { useCreateProjectMutation } from "~/lib/mutations/useCreateProjectMutation";

export default async function CreateProjectPage({
params,
}: CreateProjectPageProps) {
const [upload, uploadErr] = await createEndpointForMuxUpload();
if (uploadErr !== null) {
throw new Error(uploadErr);
}
interface CreateProjectPageProps {
params: { name: string };
}

export default function CreateProjectPage({ params }: CreateProjectPageProps) {
const router = useRouter();

const [org, err] = await getOwnOrganizationByName(params.name);
if (err !== null) {
throw new Error(err);
}
const mutation = useCreateProjectMutation(params.name, {
onSuccess: (project) => {
router.push(`/dashboard/${params.name}/project/${project.id}`);
},
onError: (err) => {
console.error(err);
},
});

return <VideUploadForm upload={upload} org={org} />;
return (
<div className="container flex max-w-[800px] flex-1 flex-col items-center pb-11">
<ProjectForm mutation={mutation} />
</div>
);
}
Loading

0 comments on commit c670a1e

Please sign in to comment.