# impact.tr Next.js 16 + Tailwind 4. SSG, markdown-driven content, self-host (Docker). ## Dev / build ```bash npm install npm run dev # localhost:3000 (we use 3010 in the background) npm run build # production build npm run start # serve the production build ``` Docker: ```bash docker compose up -d --build # HOST_PORT=3010 by default ``` ## Content workflow (no CMS, yalnızca markdown + git) Yeni edisyon, yeni yarışma formatı, yeni foto = dosya ekle + commit + push. Site otomatik güncellenir. ### Yeni edisyon ekle 1. `content/editions/.md` dosyası oluştur. Örnek: ```md --- slug: ankara-hands-on-2026 competition: hands-on-challenge # hands-on-challenge | ideathon | robo-soccer name: Hands-On Challenge — Ankara Regional status: past # past | upcoming | announced startDate: "2026-06-14" endDate: "2026-06-15" city: Ankara venue: ODTÜ KKM stats: teams: 24 participants: 200 volunteers: 25 winners: - { place: 1, team: "Takım Adı", school: "Okul", members: 4 } - { place: 2, team: "...", school: "...", members: 3 } teams: - { name: "Takım A", school: "Lise X", size: 4 } - { name: "Takım B", school: "Ü. Y", size: 3 } partners: - "Partner 1" testimonials: - { by: "İsim", org: "Kurum", quote: "..." } summary: "Tek cümlelik özet, kart & meta yerlerinde görünür." --- Serbest metin (markdown). `##`, `###`, listeler, bağlantılar. ``` 2. Foto klasörü oluştur (opsiyonel): `public/photos//01.jpg` … `NN.jpg`. Şu an otomatik galeri **sadece** `cemberlitas-hands-on-2026` için bağlı — yeni edisyonları otomatik çekmesi için tek satırlık helper gerekiyor (aşağıda TODO). 3. Commit + push → SSG yeniden üretir, anasayfadaki "Edisyonlar" grid'i ve toplam metrikler (`stats` varsa) otomatik güncellenir. ### Yeni yarışma formatı `content/competitions/.md`: ```md --- slug: archeology-hackathon name: Archeology Hackathon Challenge short: Kültürel miras hackathonu tagline: "Bir cümle hook." format: "Kısa açıklama." durationDays: 2 ageGroups: [Lise, Üniversite] categories: [Veri, Görüntü işleme] color: brand # brand | accent | pink order: 4 --- Markdown body. ``` Sonra `src/components/Nav.tsx`'a bir link daha ekle; ve `src/lib/content.ts`'te `CompetitionSlug` union type'ına yeni slug'ı ekle. ### Yeni yorum / review `src/lib/reviews.ts` içindeki `reviews` dizisine ekle: ```ts { quote: "...", by: "İsim", org: "Kurum", edition: "Çemberlitaş 2026", } ``` Edition-specific testimonial'lar için o edisyonun `.md` dosyasındaki `testimonials` alanını kullan — edisyon detay sayfasında görünür. ### Foto ekle - Yeni foto: `public/photos//.jpg`. 1600px genişlik civarı, JPG quality ~78 öneri. - Çoklu indirme için Drive linki varsa: ```bash /tmp/gdown-venv/bin/gdown --folder "" -O public/photos/ # sonra Pillow ile 1600px'e küçült (script örneği geliştirilebilir) ``` ## Pending / TODO Kod seviyesinde hazır olup **veri bekleyen** şeyler: - [ ] **Ataköy edisyonu** — tarih (`startDate`/`endDate`) doğrulanmalı. Şu an `2025-12-20/21` tahmin. Takım listesi + kazananlar eklenmeli. - [ ] **Çemberlitaş Hands-On 2026** — 16 takımın tam listesi (okul + kişi) `teams` alanına girilmeli. Tüm podium (2. ve 3.) girilmeli. - [ ] **Çemberlitaş Ideathon 2025** — stats (katılımcı/takım sayısı), kazananlar, varsa foto klasörü. - [ ] **Robo Soccer** — resmi isim kesinleşirse (`Robo Soccer` mı `Impact Robo Soccer` mı), tarih/mekan netleşince `istanbul-robo-soccer.md` ve `ankara-robo-soccer.md` güncellenmeli. Başvuru Google Forms URL'si ekle → yarışma sayfasına embed. - [ ] **Ataköy foto klasörü** — Drive'da `1JzYEOfWaT6oTSDgycG0GCg-rXrlZRK5K` çekilemedi (sadece boş alt klasörler indirdi). Manuel indirip `public/photos/atakoy-hands-on/` altına kopyalanmalı. - [ ] **Ek testimonials** — şu an yalnızca M. Buğrahan Kılıç'ın yorumu var. Katılımcı/gönüllü yorumları toplanmalı. - [ ] **Diğer etkinlikler (LinkedIn'den çıkan)** — ZAĞANOS International STEM Expo, ZAĞANOS Case Study Challenge, Archeology Hackathon Challenge, Arduino workshops. Bunların hangisi ayrı bir format mı, hangisi tek seferlik mi karar ver; `content/competitions/` veya `content/editions/` altına uygun şekilde eklenmeli. Kod seviyesinde **yapılacaklar**: - [ ] Otomatik edisyon galerisi: `public/photos//` klasörü varsa edisyon detay sayfasına otomatik `` düşsün. Şu an sadece `cemberlitas-hands-on-2026` için hardcoded. `src/lib/photos.ts` gibi bir helper: `getEditionPhotos(slug)` → `fs.readdirSync` ile otomatik. - [ ] **OG image** (`src/app/opengraph-image.tsx`) — WhatsApp/Slack/Twitter link preview için. - [ ] **sitemap.xml** ve **robots.txt** (`src/app/sitemap.ts`, `src/app/robots.ts`). - [ ] **Google Forms embed** Robo Soccer başvuru için. Form URL'si geldiğinde `/yarismalar/robo-soccer/basvuru` route'u ya da yarışma sayfasına iframe blok. - [ ] **Yorum gönderme** — şu an `mailto:` linki. İleride bir Google Forms ile Sheets'e düşsün; yeni yorumları elden `reviews.ts`'ye taşıma akışı. - [ ] **"Önceki etkinlikler" arşiv sayfası** — `/edisyonlar` index'i henüz yok; ana sayfadan 6 kart görünüyor. Tüm edisyonları listeleyen bir sayfa eklenmeli. - [ ] **Gerçek logo** — şu an "i" harfi violet blok. IG'deki "impact" wordmark SVG'ye çevirilip `public/logo.svg` + `Logo.tsx` güncellenmeli. - [ ] **Foto optimizasyonu** — şu an 1600px JPG. Next Image zaten optimize ediyor ama AVIF/WebP export eklenebilir. - [ ] **E-posta rate-limiting / iletişim formu** — mailto iyi ama spam gelirse form'a taşıyabiliriz. ## Deploy Self-host Docker Compose. Üretim adımları: ```bash # Reverse proxy (caddy/nginx) impact.tr → 127.0.0.1:3010 docker compose up -d --build docker compose logs -f web ``` Reverse proxy örneği (Caddy): ```caddy impact.tr { reverse_proxy 127.0.0.1:3010 } ``` ## Yapı ``` content/ competitions/*.md # yarışma formatları editions/*.md # edisyonlar (metrik, kazanan, takım, testimonial) public/ photos//*.jpg # edisyon/format fotoğrafları src/ app/ # App Router sayfaları page.tsx # anasayfa yarismalar/[slug]/ # yarışma detay edisyonlar/[slug]/ # edisyon detay sponsor/, hakkimizda/, iletisim/ components/ # Nav, Footer, Section, PageHero, Gallery, PhotoStrip, ... lib/ content.ts # markdown loader, helpers contact.ts # iletişim, ekip, değerler, SDG (tek kaynak) reviews.ts # yorumlar + foto index ``` ## İletişim - Site: [impact.tr](https://impact.tr) - E-posta: contact@impact.tr · info@impact.tr · hello@impact.tr - Ekip: tarik@ · tuna@ · yigit@ impact.tr - Instagram: [@impact.tr](https://www.instagram.com/impact.tr/) - LinkedIn: [impactcommunit](https://www.linkedin.com/company/impactcommunit/)