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...
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.