React ile Çok Modüllü Dashboard Nasıl Yapılır?
Stok, satış, cari yaşlandırma gibi birden fazla modülü olan kurumsal bir dashboard uygulamasını React ile nasıl düzgün organize edersiniz? Modüler mimari ve lazy loading rehberi.
Sorun: Her Şey Birbirine Karışıyor
Küçük başlıyor. Bir stok tablosu, bir satış raporu. İşler yürüdükçe talepler geliyor:
- “Cari yaşlandırma da ekleyelim”
- “İrsaliye takibi lazım”
- “Saha talepleri modülü olsun”
6 ay sonra bakıyorsunuz: 15 tane ekran, yüzlerce dosya, hepsi birbirine bağlı. Bir yere dokunuyorsunuz, başka bir yer bozuluyor. Uygulama açılması 8 saniye sürüyor.
Çözüm: Baştan doğru klasör yapısı ve modüler mimari kurmak.
Ana Fikir: Her Modül Kendi Dünyası
Her modülün kendi dosyaları kendine ait olsun. Stok modülü satış modülünün dosyalarını bilmesin bile:
src/
├── modules/
│ ├── stok/ ← Stok ile ilgili her şey burada
│ │ ├── StokModulu.tsx
│ │ ├── StokTablosu.tsx
│ │ └── useStokVerisi.ts
│ │
│ ├── satis/ ← Satış ile ilgili her şey burada
│ │ ├── SatisModulu.tsx
│ │ └── useSatisVerisi.ts
│ │
│ ├── cari/ ← Cari yaşlandırma burada
│ └── irsaliye/ ← İrsaliye burada
│
├── shared/ ← Ortak kullanılan parçalar
│ ├── Button.tsx
│ ├── Tablo.tsx
│ └── supabase.ts
│
└── App.tsx ← Ana dosya — sadece yönlendirme yapar
Neden Bu Kadar Önemli?
Düzgün organize edilmemiş bir projede:
❌ Stok dosyası, satış dosyasını import ediyor
❌ Satış dosyası, cari dosyasını import ediyor
❌ Birini değiştirin, hepsi etkileniyor
❌ Tüm modüller tek seferde yükleniyor → yavaş
Modüler yapıda:
✅ Her modül bağımsız çalışır
✅ Birini değiştirince diğerleri etkilenmez
✅ Sadece görüntülenen modül yüklenir → hızlı
✅ Yeni modül eklemek kolay
Lazy Loading: Sadece Açılanı Yükle
Kullanıcı stok ekranını açtıysa, satış modülünü yüklemeye gerek yok. React bunu lazy ile yapar:
import { lazy, Suspense } from 'react';
const StokModulu = lazy(() => import('./modules/stok/StokModulu'));
const SatisModulu = lazy(() => import('./modules/satis/SatisModulu'));
const CariModulu = lazy(() => import('./modules/cari/CariModulu'));
Bu ne demek? Uygulama açıldığında sadece temel dosyalar yüklenir. Kullanıcı stok ekranını tıkladığında stok dosyaları o an indirilir.
Fark:
- Lazy loading olmadan: Tüm modüller tek seferde → 1.8 MB
- Lazy loading ile: Sadece açılan modül → başlangıçta 280 KB (%84 daha hızlı)
Sidebar Navigasyonu
Sol tarafta bir menü, sağ tarafta aktif modülün içeriği:
┌──────────┬──────────────────────────┐
│ 📦 Stok │ │
│ 💰 Satış │ [Aktif modülün │
│ 📊 Cari │ içeriği burada │
│ 🚛 İrsali│ gösterilir] │
│ 📋 Sipar.│ │
└──────────┴──────────────────────────┘
Kullanıcı sol menüden tıkladıkça, sağ taraftaki içerik değişir. Her modül kendi verilerini kendi çeker.
Her Modülün Kendi Veri Katmanı
Her modül kendi veritabanı sorgusunu yapar. Böylece modüller birbirine bağımlı olmaz:
// modules/stok/useStokVerisi.ts
function useStokVerisi(filtreler) {
return useQuery({
queryKey: ['stok', filtreler],
queryFn: async () => {
const { data } = await supabase
.from('v3_stock')
.select('*')
.order('stok_adi');
return data;
},
});
}
Her modülün kendi hook’u var. Stok modülü useStokVerisi, satış modülü useSatisVerisi kullanır. Birbirlerini bilmezler.
Yeni Modül Eklemek Çok Kolay
Yeni bir “Sipariş Takibi” modülü mü istendi? 3 adım:
modules/siparis/klasörü oluşturSiparisModulu.tsxyazApp.tsx’te menüye ekle
Var olan hiçbir dosyaya dokunmadınız bile.
Ne Zaman Bu Yapıya İhtiyacınız Var?
| Durum | Yapı |
|---|---|
| 1-3 ekran, basit uygulama | Tek klasörde yeterli |
| 4-7 ekran, büyüyen proje | Modül klasörleri şart |
| 8+ ekran, ekip çalışması | Lazy loading + modüler mimari zorunlu |
Bu Yaklaşımla 5-6 Modüle Kadar Rahat Çalışırsınız
Ama 15+ modüle çıkınca yeni zorluklar ortaya çıkar:
- Bir modüldeki veri başka bir modülde de gerekiyor (cross-module data)
- 40+ hook arasında koordinasyon
- 9 farklı rol için modül bazlı erişim kontrolü
- Hangi kullanıcı hangi modülü görecek?
Biz 15+ modüllü yapımızda bu sorunların hepsini çözdük. İhtiyacınız olursa deneyimimizden faydalanabilirsiniz.
Bu yazı AstaFlow Case Study serisinin bir parçasıdır.