diff --git a/src/app/api/erettsegi/route.ts b/src/app/api/erettsegi/route.ts index 629da99..fd94524 100644 --- a/src/app/api/erettsegi/route.ts +++ b/src/app/api/erettsegi/route.ts @@ -9,12 +9,46 @@ export async function GET(req: NextRequest) { const idoszak = searchParams.get("idoszak"); const szint = searchParams.get("szint"); + if (!vizsgatargy && !ev && !idoszak && !szint) { + const currentYear = new Date().getFullYear(); + return NextResponse.json({ + parameters: { + vizsgatargy: { + type: "string", + required: true, + values: subjects.map((s) => ({ + value: s.value, + label: s.label, + })), + }, + ev: { + type: "integer", + required: true, + values: `2013 - ${currentYear}`, + }, + idoszak: { + type: "string", + required: true, + values: ["tavasz", "osz"], + }, + szint: { + type: "string", + required: true, + values: ["kozep", "emelt"], + }, + }, + example: + "/api/erettsegi?vizsgatargy=mat&ev=2023&idoszak=tavasz&szint=kozep", + }); + } + if (!vizsgatargy || !ev || !idoszak || !szint) { - const missingParams = []; - if (!vizsgatargy) missingParams.push("vizsgatargy"); - if (!ev) missingParams.push("ev"); - if (!idoszak) missingParams.push("idoszak"); - if (!szint) missingParams.push("szint"); + const missingParams = [ + !vizsgatargy && "vizsgatargy", + !ev && "ev", + !idoszak && "idoszak", + !szint && "szint", + ].filter(Boolean); return NextResponse.json( { error: `Hiányzó paraméterek: ${missingParams.join(", ")}` }, @@ -34,41 +68,16 @@ export async function GET(req: NextRequest) { ); } - let honap: string; - switch (idoszak) { - case "osz": - honap = "okt"; - break; - case "tavasz": - honap = "maj"; - break; - default: - return NextResponse.json( - { error: "Érvénytelen időszak" }, - { status: 400 }, - ); - } - - let prefix: string; - switch (szint) { - case "emelt": - prefix = `e_${vizsgatargy}`; - break; - case "kozep": - prefix = `k_${vizsgatargy}`; - break; - default: - return NextResponse.json( - { error: "Érvénytelen szint" }, - { status: 400 }, - ); - } + const honap = idoszak === "osz" ? "okt" : "maj"; + const prefix = szint === "emelt" ? `e_${vizsgatargy}` : `k_${vizsgatargy}`; const protocol = req.headers.get("x-forwarded-proto") === "https" ? "https" : "http"; const host = req.headers.get("host"); const baseUrl = `https://dload-oktatas.educatio.hu/erettsegi/feladatok_${ev}${idoszak}_${szint}/`; - const proxiedUrl = `${protocol}://${host}/api/proxy?link=${encodeURI(baseUrl)}`; + const proxiedUrl = `${protocol}://${host}/api/proxy?link=${encodeURI( + baseUrl, + )}`; const shortev = ev.slice(-2); const feladat = "fl"; @@ -76,40 +85,24 @@ export async function GET(req: NextRequest) { const forras = "for"; const megoldas = "meg"; - let flPdfUrl: string | undefined, - utPdfUrl: string | undefined, - flZipUrl: string | undefined, - utZipUrl: string | undefined, - flMp3Url: string | undefined; + const urls = { + flPdfUrl: `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`, + utPdfUrl: `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`, + flZipUrl: ["inf", "infoism", "digkult"].includes(vizsgatargy) + ? `${baseUrl}${prefix}${forras}_${shortev}${honap}_${feladat}.zip` + : undefined, + utZipUrl: ["inf", "infoism", "digkult"].includes(vizsgatargy) + ? `${baseUrl}${prefix}${megoldas}_${shortev}${honap}_${utmutato}.zip` + : undefined, + flMp3Url: ["angol", "nemet"].includes(vizsgatargy) + ? `${baseUrl}${prefix}_${shortev}${honap}_${feladat}.mp3` + : undefined, + }; - switch (vizsgatargy) { - case "inf": - case "infoism": - case "digkult": - flZipUrl = `${baseUrl}${prefix}${forras}_${shortev}${honap}_${feladat}.zip`; - flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`; - utZipUrl = `${baseUrl}${prefix}${megoldas}_${shortev}${honap}_${utmutato}.zip`; - utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`; - break; - case "angol": - case "nemet": - flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`; - utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`; - flMp3Url = `${baseUrl}${prefix}_${shortev}${honap}_${feladat}.mp3`; - break; - default: - flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`; - utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`; - break; - } - - return NextResponse.json( - { flPdfUrl, utPdfUrl, flZipUrl, utZipUrl, flMp3Url }, - { - status: 200, - headers: { "Cache-Control": "s-maxage=31536000" }, - }, - ); + return NextResponse.json(urls, { + status: 200, + headers: { "Cache-Control": "s-maxage=31536000" }, + }); } catch (e: unknown) { console.error("An unexpected error occurred in the API route:", e); return NextResponse.json( diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index e73df09..103020e 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -13,10 +13,15 @@ export async function GET(req: NextRequest) { const link = searchParams.get("link"); if (!link) { - return NextResponse.json( - { error: "Hiányzó paraméter: link" }, - { status: 400 }, - ); + return NextResponse.json({ + parameters: { + link: { + type: "string", + required: true, + }, + }, + example: `/api/proxy?link=https://dload-oktatas.educatio.hu/erettsegi/feladatok_2023tavasz_kozep/k_mat_23maj_fl.pdf`, + }); } let url: URL; @@ -48,8 +53,9 @@ export async function GET(req: NextRequest) { const body = await externalResponse.arrayBuffer(); const contentType = externalResponse.headers.get("content-type"); - const headers = new Headers(); - headers.set("Cache-Control", "s-maxage=31536000, stale-while-revalidate"); + const headers = new Headers({ + "Cache-Control": "s-maxage=31536000, stale-while-revalidate", + }); if (contentType) { headers.set("Content-Type", contentType); @@ -61,18 +67,14 @@ export async function GET(req: NextRequest) { return new Response(body, { status: 200, - headers: headers, + headers, }); } catch (e: unknown) { console.error("Proxy Error:", e); - if (e instanceof Error) { - return NextResponse.json( - { error: "Internal Server Error", message: e.message }, - { status: 500 }, - ); - } + const errorMessage = + e instanceof Error ? e.message : "An unexpected internal error occurred"; return NextResponse.json( - { error: "An unexpected internal error occurred" }, + { error: "Internal Server Error", message: errorMessage }, { status: 500 }, ); } diff --git a/src/app/api/validate/route.ts b/src/app/api/validate/route.ts index 6dd450c..77469c6 100644 --- a/src/app/api/validate/route.ts +++ b/src/app/api/validate/route.ts @@ -19,10 +19,16 @@ export async function GET(req: NextRequest) { const link = searchParams.get("link"); if (!link) { - return NextResponse.json( - { error: "Hiányzó paraméter: link" }, - { status: 400 }, - ); + return NextResponse.json({ + parameters: { + link: { + type: "string", + required: true, + allowed_hosts: ALLOWED_HOSTS, + }, + }, + example: `/api/validate?link=https://dload-oktatas.educatio.hu/erettsegi/feladatok_2023tavasz_kozep/k_mat_23maj_fl.pdf`, + }); } let url: URL; @@ -48,26 +54,13 @@ export async function GET(req: NextRequest) { } catch (e: unknown) { console.error("Validation Error:", e); - if (e instanceof Error) { - const cause = e.cause as { code?: unknown } | undefined; - return NextResponse.json( - { - error: "Internal Server Error", - message: e.message, - cause: cause?.code ? String(cause.code) : undefined, - stack: process.env.NODE_ENV === "development" ? e.stack : undefined, - }, - { status: 500 }, - ); - } + const errorResponse = { + error: "Internal Server Error", + message: e instanceof Error ? e.message : "An unexpected error occurred", + ...(process.env.NODE_ENV === "development" && + e instanceof Error && { stack: e.stack }), + }; - return NextResponse.json( - { - error: "Internal Server Error", - message: "An unexpected error occurred", - details: String(e), - }, - { status: 500 }, - ); + return NextResponse.json(errorResponse, { status: 500 }); } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 658f29e..8f23580 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,6 +3,7 @@ import Script from "next/script"; import { Providers } from "@/app/providers"; import { Inter } from "next/font/google"; import "@/styles/globals.css"; +import { AppProvider } from "@/ctx/app"; const inter = Inter({ subsets: ["latin"], @@ -45,7 +46,9 @@ export default function RootLayout({ data-website-id="7b196f47-39c9-4b8e-8dfd-b6e707282eea" />
-