A modern website for the Formula Racing Team (FRT) to publish news, events, galleries, cars, publications, sponsors, and recruitment information. The site includes a CMS-backed content model and a public-facing Next.js application.
Technologies used: Next.js (App Router) with React 19, TypeScript, Tailwind CSS 4, Payload CMS 3, PostgreSQL, FullCalendar, Lucide icons, ESLint, and Docker/Compose.
src/app/— Public-facing Next.js routes (App Router)src/collections/— Payload CMS collections (Articles, Events, Cars, Gallery, etc.)src/(payload)— Payload admin integrationsrc/components/— UI components (cards, navbar, calendar, etc.)public/— Static assetsmigrations/— Database migrations (if/when used)
- Node.js 18+ (Node 20 LTS recommended)
- Yarn 1.22+
- Docker & Docker Compose
Create a .env file in the project root. Minimum required:
DATABASE_URI— PostgreSQL connection string (e.g.postgres://user:pass@localhost:5432/frt)PAYLOAD_SECRET— Random string used by Payload for session/signing
Optional (only if you configure corresponding integrations):
- S3-compatible storage:
S3_BUCKET,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEY,S3_REGION,S3_ENDPOINT - Social APIs:
FACEBOOK_*,INSTAGRAM_*,TWITTER_*,YOUTUBE_*
Never commit secrets to version control.
You can run the project either fully in Docker (recommended for parity) or run the app locally with Postgres in Docker.
This will start Postgres and the app container on port 3000.
# Build and start services in the background
docker compose up -d --build
# View logs (optional)
docker compose logs -f appThen open:
- App: http://localhost:3000
- Payload Admin: http://localhost:3000/admin
# 1) Start only the database
docker compose up -d postgres
# 2) Install dependencies
yarn install
# 3) Start Next.js dev server (Turbopack)
yarn devOpen http://localhost:3000. Admin is available at http://localhost:3000/admin.
yarn dev— Run the development serveryarn build— Create an optimized production buildyarn start— Start the production serveryarn lint— Run ESLint
A /karrier oldal (korábban „Tagfelvétel", a /tagfelvetel útvonal 308-cal ide irányít) mindig elérhető, akkor is, ha éppen nincs nyitott pozíció.
- Karrier csoportok (
recruitmentkollekció) — csoportonként kép, rendezési szám, leírás, és a pozíciók listája. Egy pozícióhoz megadható:- bevezető szöveg (opcionális),
- tetszőleges számú szekció (pl. Feladatok, Szükséges skillek, Miben fejlődhetsz, Előnyök),
- három kiemelt tudnivaló: Csatlakozás, Időráfordítás, Részegység — ezek ikonokkal jelennek meg a leírás alatt,
- „Nyitott pozíció" jelölőnégyzet: csak a bepipált pozíciók jelennek meg az oldalon.
- Karrier oldal globális beállítás (
career-settings) — az oldal bevezetője, a jelentkezés módja (beépített űrlap vagy külső Google űrlap), és a jelentkezés nyitva/zárva állapota. - Jelentkezések (
job-applicationskollekció) — a beépített űrlapon beérkezett jelentkezések. A kollekciócreatejogosultsága zárt: beküldeni csak a/api/karrier/jelentkezesvégponton keresztül lehet.
A beépített űrlap minden jelentkezést elment a Payloadba, és ha be van állítva egy táblázat, egy sorral kiegészíti azt is. A táblázat hibája nem akadályozza meg a jelentkezés mentését — a státusz a jelentkezés oldalsávjában látszik (Kiírva / Kihagyva / Hiba), és a „Kiírás újra a táblázatba" gombbal bármikor pótolható.
-
A Google Cloud Console-ban hozz létre egy projektet, és engedélyezd benne a Google Sheets API-t.
-
IAM & Admin → Service Accounts → Create service account. Szerepkör nem kell hozzá.
-
A fióknál Keys → Add key → Create new key → JSON, töltsd le a kulcsot.
-
A letöltött JSON-ból két érték kell a
.env-be:GOOGLE_SERVICE_ACCOUNT_EMAIL=<a JSON "client_email" mezője> GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY="<a JSON "private_key" mezője, a \n-ekkel együtt>"A privát kulcsot idézőjelek közé tedd, és hagyd benne a
\nkaraktereket — a kód alakítja vissza sortörésekké.
- Hozz létre egy Google Sheets táblázatot (üresen is jó, a fejlécet mi írjuk bele).
- Megosztás → add hozzá a szolgáltatásfiók e-mail címét Szerkesztő jogosultsággal. A pontos címet az adminban a mező alatt kiírjuk.
- Payload admin → Karrier oldal → Jelentkezés → Google táblázat linkje: illeszd be a táblázat linkjét, és mentsd.
Mentéskor rögtön ellenőrizzük, hogy a táblázat elérhető-e; ha nincs megosztva vagy rossz a link, a mező hibaüzenetet ad. A mező üresen hagyható — ilyenkor a jelentkezések csak az adminba érkeznek.
A kiírt oszlopok sorrendje: Beküldve, Név, E-mail, Telefon, Egyetem / kar, Szak, Félév, Csoport, Pozíció, Motiváció.
Docker images are built in GitHub Actions and published to GitHub Container Registry. The VPS only pulls an immutable image, runs the environment-specific Payload migrations, and recreates the application container without building source code.
- Pushes to
stagingdeploy automatically to the isolated staging Compose project. - Production is started manually from the
mainbranch and is protected by the GitHubProductionenvironment. - Production deployments create a PostgreSQL backup before migrations.
- Failed application health checks restore the previous application image. Database migrations are never rolled back automatically.
See docs/deployment.md for environment setup, required secrets and variables, first deployment, verification, and rollback instructions. The older preview runbook remains available as a manual fallback.
- News/Articles, Events calendar, Galleries, Cars, Members, Publications, Sponsors, Association, Support Us, and Contact sections
- CMS-driven content editing with Payload
- Theming and reusable UI components
If you have questions or want to contribute, feel free to open an issue or PR.
A Karrier oldal → Űrlap kérdései fülön szerkeszthetők a magyar/angol feliratok, segédszövegek, sorrend, kötelezőség és láthatóság. Új kérdésként rövid vagy hosszú szöveg, egy- vagy többválasztós mező és jelölőnégyzet adható hozzá. A név, e-mail és hozzájárulás kötelező; a csoport és pozíció mező megőrzi az automatikus kitöltést. A hozzájárulás mindig az űrlap végén jelenik meg. A kérdés- és opcióazonosítók állandók. A jelentkezések a beküldéskori kérdéseket, opciókat és válaszokat is tárolják. Ha kitöltés közben módosul az űrlap, a beküldés frissíti a kérdéseket és újraellenőrzést kér, miközben a beírt válaszok és a kiválasztott CV megmaradnak.
Az opcionális CV egy érvényes, nem titkosított PDF lehet, maximum 5 MiB.
A fájl a privát application-cvs kollekcióba kerül, csak bejelentkezett admin
olvashatja vagy töltheti le. A jelentkezés törlése a hozzá tartozó fájlt is törli.
A nyilvános médiatárba nem kerül önéletrajz. Helyi tárolási útvonal:
private/cvs; a CV_STORAGE_DIR változóval felülírható. Dockerben külön,
környezetenként elkülönített applicant_cvs kötet tárolja a fájlokat.
Állítsd be a NEXT_PUBLIC_SERVER_URL változót az adott környezet nyilvános
HTTPS címére (helyben például http://localhost:3107). A Google-táblázat a
korábbi tíz oszlop után a További válaszok és Jelentkezés az adminban
oszlopokat kapja. A második linkről adminbelépés után tölthető le a CV.
Ha a K–L oszlopban már saját adatok vannak, az export hibát jelez, és nem írja
felül őket: előbb helyezd át ezeket, majd használd az újraszinkronizálás gombot.
A jelentkezés és CV táblázathiba esetén is megmarad.
A Kapcsolat bejegyzésben szerkeszthető a kiállítási gomb HTTPS linkje és magyar/angol felirata. Üres linknél a gomb nem jelenik meg. Ezeket a beállításokat csak bejelentkezett admin módosíthatja.
Ellenőrzések: yarn test:career, yarn tsc --noEmit, yarn eslint <érintett fájlok>.
Adatbázis-frissítés: yarn payload:migrate; generált típusok: yarn payload:generate-types.