v11 - Page Modulu Kurallari & Spacing Eklendi

t-{id} Tema Yapisi

Multi-Tenant Tema Sistemi - Page Modulu, Spacing, Alpine Collapse, Kullanici Tercihleri

1. Felsefe

t-{id} = Tenant temasi. Sadece ozel dosyalar burada.

simple = Fallback (mevcut, zaten var). t-{id}'de yoksa buradan alir.

Ornek: t-3/homepage.blade.php var -> onu kullan, t-3/blog/show.blade.php yok -> simple'dan al

2. Page Modulu Ozgurlugu

KRITIK v11

Basit Anlatim

Page modulu OZGUR olmali! Template sadece wrapper (subheader + container). Her sayfanin kendine ozel tasarimi pages tablosundaki css ve js kolonlarinda saklanir.

YASAK: Template'de Zorla Ekleme!

// YANLIS - Template'e sidebar, CTA, gallery ekleme!
<div class="grid grid-cols-3">
    <div class="col-span-2">{{ $body }}</div>
    <aside class="col-span-1">SIDEBAR ZORLA</aside>  // YASAK!
</div>

// DOGRU - Sadece container, icerik veritabanindan
<div class="page-content">
    @parsewidgets($body ?? '')
</div>
@if($item->css)<style>{!! $item->css !!}</style>@endif
@if($item->js)<script>{!! $item->js !!}</script>@endif

CSS & JS Veritabaninda

-- pages tablosu yapisi
| id | title     | body (HTML) | css           | js            |
|----|-----------|-------------|---------------|---------------|
| 2  | Hakkimizda| <div>...   | .ilce-tag{..} | // Alpine..   |
| 3  | Iletisim  | <div>...   | .faq-item{..} | // Accordion  |

-- Her sayfa KENDINE OZEL stiller
-- Template'e stiller EKLEME!

Ornek: Iletisim Sayfasi CSS

/* pages.css kolonuna yazilir */
.page-content a { text-decoration: none !important; }
.page-content h2, .page-content h3, .page-content p { margin: 0; }

.ilce-tag {
    background: rgba(55,65,81,0.5);
    color: #d1d5db;
    font-size: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    text-align: center;
}

.faq-item { background: rgba(31,41,55,0.5); border-radius: 0.75rem; border: 1px solid #374151; }
.faq-item.active { border-color: #f97316; }
.faq-btn { width: 100%; display: flex; justify-content: space-between; padding: 1.25rem; }
.faq-btn span { font-weight: 600; color: #fff; }
.faq-icon { color: #f97316; transition: transform 0.3s; }
.faq-answer { padding: 0 1.25rem 1.25rem; color: #9ca3af; }

Page show.blade.php Template Yapisi

{{-- SUBHEADER (Breadcrumb + Title) --}}
<section class="bg-gray-50 dark:bg-gray-800 border-b">
    <div class="container mx-auto px-4 py-4">
        <nav>{{ breadcrumb }}</nav>
        <h1>{{ $title }}</h1>
    </div>
</section>

{{-- CONTENT - Sadece container --}}
<section class="bg-white dark:bg-gray-900 py-10">
    <div class="container mx-auto px-4">
        <div class="page-content prose max-w-none">
            @parsewidgets($body ?? '')
        </div>
    </div>
</section>

{{-- CSS/JS veritabanindan --}}
@if($item->css)<style>{!! $item->css !!}</style>@endif
@if($item->js)<script>{!! $item->js !!}</script>@endif

3. Spacing Kurallari

KRITIK v11

Basit Anlatim

Tum sayfalarda TUTARLI bosluklar olmali. "Degerlerimiz" gibi basliklar icerigin altina yapisik olmamali!

mb-16: Bolumler Arasi

<!-- Her buyuk bolumun sonunda mb-16 -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-16">
    <!-- Hikayemiz bolumu -->
</div>

<div class="mb-16">
    <h2>Degerlerimiz</h2>
    <!-- Degerler grid -->
</div>

<div class="bg-gradient-to-br ... mb-16">
    <!-- Neden Yildirim Panjur -->
</div>

mt-8: Baslik Altinda

<!-- Baslik ile icerik arasi mt-8 -->
<h2 class="text-xl font-bold text-white flex items-center gap-3">
    <i class="fa-solid fa-star text-primary-400"></i>
    Degerlerimiz
</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mt-8">
    <!-- Deger kartlari -->
</div>

<!-- YANLIS - mt-8 yok, baslik icerigin ustune yapisik! -->
<h2>Degerlerimiz</h2>
<div class="grid">...</div>  <-- YAPISIK!

Spacing Ozet

DurumClassAciklama
mb-16Bolum sonuHer buyuk section'dan sonra
mt-8Baslik altindah2/h3 ile icerik arasinda
gap-4 / gap-6Grid/Flex iciKartlar arasinda
mb-4Paragraf sonuMetin bloklari arasinda

4. Alpine Collapse Plugin

YENI v11

Basit Anlatim

FAQ (Sikca Sorulan Sorular) accordion'lari icin x-collapse direktifi gerekir. Ana Alpine'dan ONCE yuklenmelidir!

Script Yukleme Sirasi (KRITIK!)

<!-- 1. ONCE Collapse plugin -->
<script defer src="https://unpkg.com/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>

<!-- 2. SONRA Ana Alpine -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>

<!-- YANLIS SIRA - Collapse calismaz! -->
<script defer src="alpinejs@3.x.x"></script>
<script defer src="@alpinejs/collapse@3.x.x"></script>

FAQ Accordion Kullanimi

<div class="space-y-4" x-data="{active: 0}">
    <div class="faq-item" :class="active === 1 && 'active'">
        <button @click="active = active === 1 ? 0 : 1" class="faq-btn">
            <span>Kesif ucreti aliyor musunuz?</span>
            <i class="fa-solid fa-plus faq-icon" :class="active === 1 && 'rotate-45'"></i>
        </button>
        <div x-show="active === 1" x-collapse class="faq-answer">
            Hayir, kesif ve fiyat teklifi hizmetimiz tamamen ucretsizdir.
        </div>
    </div>
</div>

5. Kullanici Tercihleri: ISTEMIYORUM!

KRITIK v11

Bu seyleri YAPMA!

Kullanici acikca belirtti - bu ogeleri sayfalara EKLEME.

1. Link Underline'lari

<!-- YANLIS - Underline var -->
a { text-decoration: underline; }

<!-- DOGRU - Underline yok -->
.page-content a { text-decoration: none !important; }

"underline falan sik gibi seyler yapma"

2. "Odeme Secenekleri Nelerdir?" Sorusu

Bu soruyu FAQ'dan ve HER YERDEN kaldir. Panjur tamir sitesi icin anlamsiz.

"Odeme secenekleri nelerdir? bu soruyu her yerden kaldir"

3. Tutarsiz Bosluklar

Basliklar icerigin altina yapisik olmamali. Tum sayfalarda AYNI bosluk pattern'i kullan.

"iletisimde bosluklar net olmali. faq basligi altina cok yakin. tamami tutarli olmali"

4. Template'de Zorla Sidebar/CTA

Page modulu FREE olmali. Her sayfaya ayni sidebar, gorsel, numara ekleme.

"pageler free olmali. neden sagda gorsel numara falan var hepsinde"

5. Tekrar Eden Icerik

Ayni metin/baslik birden fazla yerde olmamali. Hizmet bolgeleri bir kere yeter.

6. Hero Slider Sistemi

Slider Degiskeni Tanimlama

@php
    // Homepage sayfasini bul - DOGRU YONTEM
    $homepagePage = \Modules\Page\App\Models\Page::where('is_homepage', true)->first();

    // Hero ve slider gorselleri
    $homepageHero = $homepagePage?->getFirstMediaUrl('hero');
    $sliderImages = $homepagePage?->getMedia('slider')
        ->sortBy(fn($m) => $m->getCustomProperty('slider_order', 0)) ?? collect();
@endphp

KRITIK: Query Hatasi!

// YANLIS - slug degisebilir!
$homepagePage = Page::where('slug', 'anasayfa')->first();

// DOGRU - is_homepage flag'i kullan
$homepagePage = Page::where('is_homepage', true)->first();

8. Modul View Path'leri

KRITIK: Modul Onceligi!

Laravel once Modules/ altindaki view'lara bakar. Homepage icin Modules/Page/ konumunu guncelle!

Homepage Konumlari

1. ONCELIKLI (Modules):
Modules/Page/resources/views/themes/t-3/homepage.blade.php

2. Fallback (resources):
resources/views/themes/t-3/homepage.blade.php

9. Root Admin Butonlari

YENI v11

Basit Anlatim

Her temanin header'inda logonun yaninda cache sifirlama ve AI sifirlama butonlari olmali. Sadece root rolu gorebilir. Minimal ikonlar, cok az yer kaplar.

Konum

Logo'nun hemen yaninda (sag tarafinda), navigation'dan once.

<a href="/">LOGO</a>

{{-- Cache & AI Butonlari - SADECE ROOT --}}
@auth
    @if(auth()->user()->hasRole('root'))
    <div class="flex items-center gap-1 ml-2">
        <button>Cache</button>
        <button>AI</button>
    </div>
    @endif
@endauth

<nav>NAVIGATION</nav>

Tam Kod

{{-- Cache & AI Clear Buttons - SADECE ROOT --}}
@auth
    @if(auth()->user()->hasRole('root'))
    <div class="flex items-center gap-1 ml-2">
        {{-- Cache Clear --}}
        <button
            class="w-8 h-8 bg-gray-100 dark:bg-slate-800 hover:bg-primary-100
                   dark:hover:bg-primary-900/30 rounded-lg flex items-center
                   justify-center text-gray-500 hover:text-primary-600 transition-all"
            title="Cache Sifirla"
            x-data
            @click="
                fetch('/admin/cache/clear', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRF-TOKEN': '{{ csrf_token() }}'
                    }
                }).then(() => window.location.reload());
            "
        >
            <i class="fat fa-sync-alt text-sm"></i>
        </button>

        {{-- AI/Session Clear --}}
        <button
            class="w-8 h-8 bg-gray-100 dark:bg-slate-800 hover:bg-red-100
                   dark:hover:bg-red-900/30 rounded-lg flex items-center
                   justify-center text-gray-500 hover:text-red-600 transition-all"
            title="AI Sifirla"
            x-data
            @click="
                const tenantId = '{{ tenant('id') ?? '' }}';
                if (tenantId) {
                    localStorage.removeItem('tenant' + tenantId + '_ai_session');
                }
                window.location.reload();
            "
        >
            <i class="fat fa-robot text-sm"></i>
        </button>
    </div>
    @endif
@endauth

Ozellikler

Boyutw-8 h-8 (32x32px)
GorunumSadece root rolu
Cache Ikonfa-sync-alt (turuncu hover)
AI Ikonfa-robot (kirmizi hover)
Endpoint/admin/cache/clear POST

Yeni Sayfa Checklist