diff --git a/.gitignore b/.gitignore index 3c1d217..c2814ab 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,9 @@ node_modules out dist .DS_Store -config.json -*.csv +src/config/config.json +src/data/*.csv +public/branding/*.png +public/branding/*.jpg +public/branding/*.jpeg +public/branding/*.svg diff --git a/package-lock.json b/package-lock.json index 6fccc01..e7f1655 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,14 @@ { - "name": "heights", + "name": "altarra", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "heights", + "name": "altarra", "version": "0.1.0", "dependencies": { + "lucide-react": "^0.562.0", "next": "14.1.0", "papaparse": "5.4.1", "react": "18.2.0", @@ -3834,6 +3835,15 @@ "dev": true, "license": "ISC" }, + "node_modules/lucide-react": { + "version": "0.562.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz", + "integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", diff --git a/package.json b/package.json index e5a99b1..bcc3448 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,24 @@ "private": true, "scripts": { "dev": "next dev", + "prebuild": "node scripts/setup-config.js", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { + "lucide-react": "^0.562.0", "next": "14.1.0", - "react": "18.2.0", - "react-dom": "18.2.0", "papaparse": "5.4.1", - "react-checkmark": "2.1.1" + "react": "18.2.0", + "react-checkmark": "2.1.1", + "react-dom": "18.2.0" }, "devDependencies": { "@types/node": "20.10.6", + "@types/papaparse": "5.3.14", "@types/react": "18.2.37", "@types/react-dom": "18.2.15", - "@types/papaparse": "5.3.14", "autoprefixer": "10.4.16", "eslint": "8.55.0", "eslint-config-next": "14.1.0", diff --git a/scripts/setup-config.js b/scripts/setup-config.js new file mode 100644 index 0000000..9139c36 --- /dev/null +++ b/scripts/setup-config.js @@ -0,0 +1,37 @@ +#!/usr/bin/env node + +/** + * Setup script: creates config.json from example if it doesn't exist. + * Runs during build phase. + */ + +const fs = require('fs') +const path = require('path') + +const projectRoot = path.join(__dirname, '..') +const configPath = path.join(projectRoot, 'src', 'config', 'config.json') +const examplePath = path.join(projectRoot, 'src', 'config', 'config.json.example') + +// Check if config.json exists +if (fs.existsSync(configPath)) { + console.log('✓ config.json found') + process.exit(0) +} + +// Check if example exists +if (!fs.existsSync(examplePath)) { + console.error('✗ config.json.example not found at', examplePath) + process.exit(1) +} + +// Copy example to config.json +try { + const exampleContent = fs.readFileSync(examplePath, 'utf8') + fs.writeFileSync(configPath, exampleContent) + console.log('✓ config.json created from example') + process.exit(0) +} catch (err) { + console.error('✗ Failed to create config.json:', err.message) + process.exit(1) +} + diff --git a/src/app/api/admin/upload/route.ts b/src/app/api/admin/upload/route.ts index 0de1a8b..ad93ab2 100644 --- a/src/app/api/admin/upload/route.ts +++ b/src/app/api/admin/upload/route.ts @@ -4,7 +4,6 @@ import path from 'node:path' import config from '@/config/config.json' export const runtime = 'nodejs' -export const config_edge = { maxDuration: 30 } export async function POST(req: NextRequest) { const password = req.headers.get('x-admin-password') || '' diff --git a/src/app/api/competition-name/route.ts b/src/app/api/competition-name/route.ts new file mode 100644 index 0000000..a1fd588 --- /dev/null +++ b/src/app/api/competition-name/route.ts @@ -0,0 +1,16 @@ +import { NextResponse } from 'next/server' +import { readFile } from 'node:fs/promises' +import path from 'node:path' + +export const runtime = 'nodejs' + +export async function GET() { + try { + const configPath = path.join(process.cwd(), 'src', 'config', 'config.json') + const content = await readFile(configPath, 'utf8') + const data = JSON.parse(content) + return NextResponse.json({ competitionName: data.competitionName }) + } catch { + return NextResponse.json({ competitionName: 'Altarra' }) + } +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2363c1a..c245e18 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,7 @@ import './globals.css' import type { Metadata } from 'next' import { Inter } from 'next/font/google' import Footer from '@/components/Footer' +import { LanguageProvider } from '@/context/LanguageContext' const inter = Inter({ subsets: ['latin'] }) @@ -14,8 +15,12 @@ export default function RootLayout({ children }: { children: React.ReactNode }) return ( -
{children}
-