diff --git a/apps/web/src/app/api/get-upload-url/route.ts b/apps/web/src/app/api/get-upload-url/route.ts index dc5b7328f..9fd75b9a8 100644 --- a/apps/web/src/app/api/get-upload-url/route.ts +++ b/apps/web/src/app/api/get-upload-url/route.ts @@ -70,8 +70,8 @@ export async function POST(request: NextRequest) { // Initialize R2 client const client = new AwsClient({ - accessKeyId: env.R2_ACCESS_KEY_ID, - secretAccessKey: env.R2_SECRET_ACCESS_KEY, + accessKeyId: env.R2_ACCESS_KEY_ID!, + secretAccessKey: env.R2_SECRET_ACCESS_KEY!, }); // Generate unique filename with timestamp @@ -80,7 +80,7 @@ export async function POST(request: NextRequest) { // Create presigned URL const url = new URL( - `https://${env.R2_BUCKET_NAME}.${env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com/${fileName}` + `https://${env.R2_BUCKET_NAME!}.${env.CLOUDFLARE_ACCOUNT_ID!}.r2.cloudflarestorage.com/${fileName}` ); url.searchParams.set("X-Amz-Expires", "3600"); // 1 hour expiry diff --git a/apps/web/src/app/api/sounds/search/route.ts b/apps/web/src/app/api/sounds/search/route.ts index c89bc76c6..8767eed96 100644 --- a/apps/web/src/app/api/sounds/search/route.ts +++ b/apps/web/src/app/api/sounds/search/route.ts @@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { env } from "@/env"; import { baseRateLimit } from "@/lib/rate-limit"; +import { isFreesoundConfigured } from "@/lib/transcription-utils"; const searchParamsSchema = z.object({ q: z.string().max(500, "Query too long").optional(), @@ -97,6 +98,27 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: "Too many requests" }, { status: 429 }); } + // Check Freesound configuration + const freesoundCheck = isFreesoundConfigured(); + if (!freesoundCheck.configured) { + // Log missing variables server-side only + console.error( + "Sound search not configured - missing environment variables:", + freesoundCheck.missingVars + ); + + return NextResponse.json( + { + error: "Sound search not configured", + message: "Sound search is not configured", + ...(env.NODE_ENV !== "production" && { + missingVars: freesoundCheck.missingVars, + }), + }, + { status: 503 } + ); + } + const { searchParams } = new URL(request.url); const validationResult = searchParamsSchema.safeParse({ @@ -150,7 +172,7 @@ export async function GET(request: NextRequest) { const params = new URLSearchParams({ query: query || "", - token: env.FREESOUND_API_KEY, + token: env.FREESOUND_API_KEY!, page: page.toString(), page_size: pageSize.toString(), sort: sortParam, diff --git a/apps/web/src/app/api/transcribe/route.ts b/apps/web/src/app/api/transcribe/route.ts index 9a497f65e..fdb91863b 100644 --- a/apps/web/src/app/api/transcribe/route.ts +++ b/apps/web/src/app/api/transcribe/route.ts @@ -112,7 +112,7 @@ export async function POST(request: NextRequest) { } // Call Modal transcription service - const response = await fetch(env.MODAL_TRANSCRIPTION_URL, { + const response = await fetch(env.MODAL_TRANSCRIPTION_URL!, { method: "POST", headers: { "Content-Type": "application/json", diff --git a/apps/web/src/components/landing/hero.tsx b/apps/web/src/components/landing/hero.tsx index 46d99b0cc..0e327fd7e 100644 --- a/apps/web/src/components/landing/hero.tsx +++ b/apps/web/src/components/landing/hero.tsx @@ -9,17 +9,23 @@ import { ArrowRight } from "lucide-react"; import Image from "next/image"; import { Handlebars } from "./handlebars"; import Link from "next/link"; +import { useState } from "react"; export function Hero() { + const [bgError, setBgError] = useState(false); return ( -
- landing-page.bg +
+ {!bgError && ( + Landing page background setBgError(true)} + priority + /> + )}