foşur.
foşur.
Anadolu Yakası'nda kapıda mobil araç yıkama. Siz bekleyin, biz gelelim.
Site İçi Görüntüler
Proje & Bağlam
Foşur, Anadolu Yakası'nda faaliyet gösterecek mobil araç yıkama hizmeti için sıfırdan tasarlanıp geliştirilen tam yığın bir web uygulaması. Kullanıcı randevu alır, haritada konumunu işaretler; ekip gelir, yıkar, gider.
Tasarım referansı Uber. Çünkü Uber'i herkes biliyor — aynı akış mantığı araç yıkamaya uyarlandı: paket seç, konumu işaretle, ekip gelsin.
Neden Tek HTML?
Bu projenin en ilginç teknik kararı buydu. Ama foşur bir PWA — yani telefona kurulabilen, offline çalışabilen bir 'uygulama'. Her sayfa geçişinde yeniden yükleme olmadan ekranlar arasında geçiş yapmak kritik.
Çözüm: tek index.html içinde 15 ekran, CSS ile göster/gizle. Ekranlar arası slide animasyonu — native uygulama hissi. Build adımı yok, 5300 satır temiz HTML/CSS/JS.
15 Ekran, Tek Dosya
Hizmet Paketleri
Fiyatlar admin panelinden veritabanına güncellenir, siteye otomatik yansır. Araç tipi ek ücreti, isteğe bağlı ekstralar ve ₺50 Stripe kapora.
Damla — Sadakat Sistemi
'Pul' demek sıradan gelirdi. 'Damla' — su temalı, akılda kalıcı. Her foşurmada 1 damla. Yeterli biriktir, bir foşurma bedava. Kademe atladıkça gereken damla sayısı düşüyor.
Referans kodu sistemi de var. Damla verme işlemi admin onayı gerektiriyor — double-award önlemek için appointments tablosunda damla_awarded flag.
Öne Çıkan Özellikler
4 Adımlı Randevu Akışı
Paket → Araç → Konum → Özet. Her adım ayrı ekran, slide animasyon geçiş. Progress bar ile ilerleme gösterimi.
Leaflet.js Harita Entegrasyonu
Leaflet.js + OpenStreetMap, sıfır maliyet. Geolocation API ile konum, sürüklenebilir pin, reverse geocoding ile adres dönüşümü.
Damla Sadakat Sistemi
8 damla ekranı (s6). Dolu yeşil, boş gri. Tier badge, referans kodu. Admin onaylı damla verme — çift verilemez.
Admin Paneli (admin.html)
Ayrı admin.html — durum bazlı randevu yönetimi, Damla verme, fiyat güncelleme, bölge yönetimi. is_admin=true ile doğrulama.
Backend & Veritabanı
Vercel serverless Node.js — her endpoint ayrı dosya. 7 iş endpoint + 2 yardımcı (_db.js MySQL pool, _helpers.js). Şifre bcrypt, auth token bazlı.
Bcrypt hash, VAPID push altyapısı (hazır, aktif değil), Stripe kapora endpoint (key girilince devreye girer).
Teknik Zorluklar
15 Ekran Tek HTML: Performans
⚡ Sorun
15 ekranın tamamı DOM'da aynı anda bulunduğu için sayfa ağırlığı arttı ve initial render yavaşladı. display:none kullanan ekranlar için tarayıcı yine de tüm içeriği parse ediyordu.
✓ Çözüm
Ekranlar display:none yerine visibility:hidden + height:0 + overflow:hidden kombinasyonuyla gizlendi. Bu yöntemde layout hesabı yapılmıyor. Kritik ekranlar (s0-s4) önce yükleniyor, diğerleri lazy-init ediliyor.
iOS Safe Area + Leaflet Harita
⚡ Sorun
iPhone'da alt navigasyon çubuğu Leaflet haritasının zoom kontrollerinin üstüne biniyordu. env(safe-area-inset-bottom) değeri Leaflet'in kendi container'ına uygulanamıyordu.
✓ Çözüm
Leaflet attribution kontrolü CSS ile alt soldan sağa taşındı. Zoom kontrolleri haritanın sağ üstüne alındı. Harita container'ına padding-bottom: calc(env(safe-area-inset-bottom) + 80px) eklendi.
Damla Çift Verilme Race Condition
⚡ Sorun
Admin hızlı çift tıkladığında 'Damla Ver' API'si iki kez tetiklendi ve aynı randevuya çift damla eklendi. Database transaction olmadığında SELECT + UPDATE arasına başka istek giriyordu.
✓ Çözüm
appointments tablosuna damla_awarded boolean sütunu eklendi. API önce damla_awarded=false kontrolü yapıyor, sonra transaction içinde hem damla_awarded=true hem de stamps+1 güncellemesini yapıyor. Çift tıkla ikinci istek engelleniyor.