Muzibu AI TODO Guide

Kapsamlı Düzeltme Planı - v2

20 / 20
✅ Tamamlanan Görev

AI İÇİN TALİMATLAR

Görev Tamamlandığında:

  1. Bu HTML dosyasını aç: public/readme/2025/12/20/muzibu-component-audit/v2/index.html
  2. İlgili görevin todo-item div'ine completed class'ı ekle
  3. Checkbox'a işareti koy
  4. Header'daki sayacı güncelle (örn: 1 / 28, 2 / 28...)
  5. Varsa notları "Yapılan Değişiklikler" bölümüne ekle

Önemli Kurallar:

  • Her görev tamamlandığında HEMEN bu dosyayı güncelle
  • Sırayla ilerle - öncelik numaralarına uy
  • CSS değişikliği yaptıysan: npm run prod çalıştır
  • View değişikliği yaptıysan: php artisan view:clear && php artisan responsecache:clear

Hızlı Komutlar:

# CSS rebuild
npm run prod
# Cache temizle
php artisan view:clear && php artisan responsecache:clear
1

KRİTİK CSS HATALARI

ÖNCELİK: ACİL

Tespit Edilen Sorunlar:

  • muzibu-coral - Tailwind config'de tanımlanmamış!
  • muzibu-gray - Tailwind config'de tanımlanmamış!
  • bg-white/5, bg-white/10 - Safelist'te yok, purge edilmiş olabilir!
  • bg-black/40, bg-black/70 - Safelist'te yok!
1.1 Tailwind Config'e Renkleri Ekle KRİTİK

tailwind/tenants/tenant-1001.config.js dosyasına muzibu-coral ve muzibu-gray ekle

colors: {
    ...baseConfig.theme.extend.colors,
    // Spotify-style Muzibu colors
    'spotify-black': '#121212',
    'spotify-dark': '#181818',
    'spotify-green': '#1DB954',
    'spotify-green-light': '#1ed760',
    'spotify-gray': '#282828',
    // Muzibu custom colors - YENİ EKLE
    'muzibu-coral': '#ff7f50',
    'muzibu-gray': '#1a1a1a',
}
1.2 Safelist'e Opacity Class'ları Ekle KRİTİK

tailwind/tenants/tenant-1001.config.js safelist'ine opacity class'ları ekle

safelist: [
    ...baseConfig.safelist,
    // Opacity backgrounds - YENİ EKLE
    'bg-white/5', 'bg-white/10', 'bg-white/20',
    'bg-black/20', 'bg-black/40', 'bg-black/50', 'bg-black/60', 'bg-black/70', 'bg-black/90',
    'hover:bg-white/10', 'hover:bg-black/60', 'hover:bg-black/90',
    // Muzibu coral variants
    'bg-muzibu-coral', 'text-muzibu-coral', 'border-muzibu-coral',
    'bg-muzibu-coral/10', 'bg-muzibu-coral/20',
    'hover:bg-muzibu-coral', 'hover:text-muzibu-coral',
    'ring-muzibu-coral',
    // Muzibu gray variants
    'bg-muzibu-gray', 'hover:bg-gray-700',
    // ... existing safelist
]
1.3 CSS Rebuild Et KRİTİK

Config değişikliklerinden sonra CSS'i yeniden oluştur

npm run prod && php artisan view:clear && php artisan responsecache:clear
2

YENİ COMPONENT OLUŞTURMA

ÖNCELİK: YÜKSEK
2.1 playlist-quick-card Component Oluştur YENİ COMPONENT

Ana sayfa Quick Access için yatay playlist kartı

Dosya: resources/views/components/muzibu/playlist-quick-card.blade.php
@props(['playlist', 'index' => 0])

{{-- Muzibu Playlist Quick Card Component --}}
{{-- Usage: <x-muzibu.playlist-quick-card :playlist="$playlist" /> --}}
{{-- Ana sayfa Quick Access için yatay kart --}}

@php
    $isFavorite = auth()->check() && method_exists($playlist, 'isFavoritedBy') && $playlist->isFavoritedBy(auth()->id());
    $isMine = auth()->check() && isset($playlist->user_id) && $playlist->user_id == auth()->id();
@endphp

<div class="playlist-card group flex items-center gap-3 bg-white/5 hover:bg-white/10 rounded transition-all cursor-pointer overflow-hidden h-16 relative"
     data-playlist-id="{{ $playlist->id ?? $playlist->playlist_id }}"
     data-context-type="playlist"
     x-data="{ touchTimer: null, touchStartPos: { x: 0, y: 0 } }"
     x-on:contextmenu.prevent.stop="$store.contextMenu.openContextMenu($event, 'playlist', {
         id: {{ $playlist->id ?? $playlist->playlist_id }},
         title: '{{ addslashes($playlist->getTranslation('title', app()->getLocale())) }}',
         is_favorite: {{ $isFavorite ? 'true' : 'false' }},
         is_mine: {{ $isMine ? 'true' : 'false' }}
     })"
     x-on:touchstart="touchStartPos = { x: $event.touches[0].clientX, y: $event.touches[0].clientY }; touchTimer = setTimeout(() => { if (navigator.vibrate) navigator.vibrate(50); $store.contextMenu.openContextMenu({ clientX: $event.touches[0].clientX, clientY: $event.touches[0].clientY }, 'playlist', { id: {{ $playlist->id ?? $playlist->playlist_id }}, title: '{{ addslashes($playlist->getTranslation('title', app()->getLocale())) }}', is_favorite: {{ $isFavorite ? 'true' : 'false' }}, is_mine: {{ $isMine ? 'true' : 'false' }} }); }, 500);"
     x-on:touchend="clearTimeout(touchTimer)"
     x-on:touchmove="if (Math.abs($event.touches[0].clientX - touchStartPos.x) > 10 || Math.abs($event.touches[0].clientY - touchStartPos.y) > 10) clearTimeout(touchTimer);"
     @click="$store.sidebar.showPreview('playlist', {{ $playlist->id ?? $playlist->playlist_id }}, {
         type: 'Playlist',
         id: {{ $playlist->id ?? $playlist->playlist_id }},
         title: '{{ addslashes($playlist->getTranslation('title', app()->getLocale())) }}',
         cover: '{{ $playlist->coverMedia ? thumb($playlist->coverMedia, 300, 300, ['scale' => 1]) : '' }}',
         is_favorite: {{ $isFavorite ? 'true' : 'false' }}
     })">

    {{-- Cover Image --}}
    <div class="w-16 h-16 flex-shrink-0 bg-gradient-to-br from-muzibu-coral to-pink-600">
        @if($playlist->coverMedia)
            <img src="{{ thumb($playlist->coverMedia, 64, 64, ['scale' => 1]) }}"
                 alt="{{ $playlist->getTranslation('title', app()->getLocale()) }}"
                 loading="{{ $index < 6 ? 'eager' : 'lazy' }}"
                 class="w-full h-full object-cover">
        @else
            <div class="w-full h-full flex items-center justify-center text-xl text-white/90">🎵</div>
        @endif
    </div>

    {{-- Title --}}
    <div class="flex-1 min-w-0 pr-20">
        <h3 class="font-semibold text-white text-sm truncate">
            {{ $playlist->getTranslation('title', app()->getLocale()) }}
        </h3>
    </div>

    {{-- Favorite + Menu Buttons - HOVER'DA GÖRÜNÜR --}}
    <div class="absolute right-2 top-1/2 -translate-y-1/2 z-10 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity" @click.stop>
        {{-- Favorite Button --}}
        <button @click.stop="$store.favorites.toggle('playlist', {{ $playlist->id ?? $playlist->playlist_id }})"
                class="w-7 h-7 bg-black/40 hover:bg-black/60 rounded-full flex items-center justify-center text-white/70 hover:text-white transition-all"
                x-bind:class="$store.favorites.isFavorite('playlist', {{ $playlist->id ?? $playlist->playlist_id }}) ? 'text-muzibu-coral' : ''">
            <i class="text-xs"
               x-bind:class="$store.favorites.isFavorite('playlist', {{ $playlist->id ?? $playlist->playlist_id }}) ? 'fas fa-heart' : 'far fa-heart'"></i>
        </button>

        {{-- 3-Dot Menu Button --}}
        <button @click.stop="$store.contextMenu.openContextMenu($event, 'playlist', {
            id: {{ $playlist->id ?? $playlist->playlist_id }},
            title: '{{ addslashes($playlist->getTranslation('title', app()->getLocale())) }}',
            is_favorite: {{ $isFavorite ? 'true' : 'false' }},
            is_mine: {{ $isMine ? 'true' : 'false' }}
        })" class="w-7 h-7 bg-black/40 hover:bg-black/60 rounded-full flex items-center justify-center text-white/70 hover:text-white transition-all">
            <i class="fas fa-ellipsis-v text-xs"></i>
        </button>
    </div>
</div>
2.2 song-card Component Oluştur YENİ COMPONENT

Favoriler ve grid görünüm için şarkı kartı (album-card benzeri)

Dosya: resources/views/components/muzibu/song-card.blade.php
@props(['song', 'preview' => false])

{{-- Muzibu Song Card Component --}}
{{-- Grid görünüm için şarkı kartı --}}

@php
    $isFavorite = auth()->check() && method_exists($song, 'isFavoritedBy') && $song->isFavoritedBy(auth()->id());
    $albumCover = $song->album && $song->album->coverMedia ? $song->album->coverMedia : null;
@endphp

<div class="group bg-muzibu-gray hover:bg-gray-700 rounded-lg p-4 transition-all duration-300 cursor-pointer"
     data-song-id="{{ $song->id }}"
     data-album-id="{{ $song->album_id ?? '' }}"
     data-context-type="song"
     x-on:click="$store.player.playSong({{ $song->id }})"
     x-on:contextmenu.prevent.stop="..."
     x-bind:class="$store.player.currentSong?.id === {{ $song->id }} ? 'ring-2 ring-muzibu-coral' : ''">

    {{-- Cover + Play Button --}}
    <div class="relative mb-4">
        @if($albumCover)
            <img src="{{ thumb($albumCover, 300, 300) }}" ... />
        @else
            <div class="w-full aspect-square bg-gradient-to-br from-muzibu-coral to-purple-600 rounded-lg ...">
                <i class="fas fa-music text-white text-4xl opacity-50"></i>
            </div>
        @endif

        {{-- Play Button --}}
        <button @click.stop="$store.player.playSong({{ $song->id }})"
                class="absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 ... bg-muzibu-coral ...">
            <i class="fas fa-play ml-1"></i>
        </button>

        {{-- Favorite + Menu --}}
        <div class="absolute top-2 right-2 z-10 flex gap-2 opacity-0 group-hover:opacity-100 ...">
            {{-- Favorite Button --}}
            <button @click.stop="$store.favorites.toggle('song', {{ $song->id }})" ...>
                <i x-bind:class="$store.favorites.isFavorite('song', {{ $song->id }}) ? 'fas fa-heart' : 'far fa-heart'"></i>
            </button>
            {{-- Menu Button --}}
            ...
        </div>
    </div>

    {{-- Song Title --}}
    <h3 class="font-semibold text-white mb-1 truncate">{{ $song->getTranslation('title', app()->getLocale()) }}</h3>

    {{-- Artist --}}
    @if($song->album && $song->album->artist)
        <p class="text-sm text-gray-400 truncate">{{ $song->album->artist->getTranslation('title', app()->getLocale()) }}</p>
    @endif
</div>

Tam kodu album-card'dan kopyala ve şarkıya uyarla

2.3 horizontal-scroll-section Component Oluştur OPSİYONEL

Tekrar eden scroll logic'i tek component'te topla

Dosya: resources/views/components/muzibu/horizontal-scroll-section.blade.php
@props(['title' => null])

{{-- Kullanım: --}}
{{-- <x-muzibu.horizontal-scroll-section title="Öne Çıkanlar"> --}}
{{--     @foreach($items as $item) ... @endforeach --}}
{{-- </x-muzibu.horizontal-scroll-section> --}}

<div class="mb-6 relative group/scroll" x-data="horizontalScroll()">
    @if($title)
        <h2 class="text-2xl font-bold text-white mb-2">{{ $title }}</h2>
    @endif

    {{-- Left/Right Arrows --}}
    <button @click="scrollLeft()" class="absolute left-[-12px] ...">...</button>
    <button @click="scrollRight()" class="absolute right-[-12px] ...">...</button>

    {{-- Scroll Container --}}
    <div x-ref="scrollContainer" class="flex gap-2 overflow-x-auto scrollbar-hide scroll-smooth pb-4">
        {{ $slot }}
    </div>
</div>
3

ANA SAYFA DÜZELTMELERİ

ÖNCELİK: YÜKSEK
3.1 Quick Access → playlist-quick-card Kullan

Ana sayfa Quick Access bölümündeki inline HTML'i component ile değiştir

Dosya: resources/views/themes/muzibu/index.blade.php (Satır 63-114)

❌ ESKİ (50 satır inline):

@foreach($featuredPlaylists->take(8) as $index => $playlist)
<div class="playlist-card group flex items-center gap-3 ..."
     x-data="{ touchTimer: null, ... }"
     x-on:contextmenu.prevent.stop="..."
     x-on:touchstart="..."
     @click="...">
    ... 50 satır inline HTML ...
</div>
@endforeach

✅ YENİ (3 satır):

@foreach($featuredPlaylists->take(8) as $index => $playlist)
    <x-muzibu.playlist-quick-card
        :playlist="$playlist"
        :index="$index"
    />
@endforeach
3.2 Scroll Logic'i Tek Yerde Topla OPSİYONEL

4 kez tekrar eden x-data scroll logic'i için horizontal-scroll-section component kullan

3.3 Style Tag'i Kaldır

Inline style tag'i (scrollbar-hide) global CSS'e taşı

Satır 169-172: <style>.scrollbar-hide...</style> kaldır, tenant CSS'e ekle
4

DİĞER SAYFA DÜZELTMELERİ

ÖNCELİK: ORTA
4.1 artists/show → album-card Kullan

Inline album kartlarını component ile değiştir

Dosya: resources/views/themes/muzibu/artists/show.blade.php (Satır 56-84)
4.2 favorites/index → Mevcut Component'leri Kullan

3 tip inline kartı component ile değiştir (song-card, album-card, playlist-card)

Dosya: Modules/Muzibu/.../favorites/index.blade.php (Satır 44-158)
4.3 albums/show Header'ı Düzelt

Hardcoded Unsplash URL'i gerçek album cover ile değiştir

Satır 6: https://images.unsplash.com/...{{ $album->coverMedia ? thumb($album->coverMedia, 232, 232) : '' }}
4.4 playlists/show Header'ı Düzelt

Hardcoded Unsplash URL'i gerçek playlist cover ile değiştir

Satır 7: https://images.unsplash.com/...{{ $playlist->coverMedia ? thumb($playlist->coverMedia, 232, 232) : '' }}
5

FAVORİ BUTONU KONTROLÜ

DOĞRULAMA

Mevcut Durum (İYİ):

Tüm mevcut component'lerde favori butonu VAR:

✓ song-row ✓ album-card ✓ playlist-card ✓ genre-card ✓ sector-card ✓ radio-card
5.1 playlist-quick-card'a Favori Butonu Ekle

Yeni oluşturulan component'e hover'da görünen favori butonu ekle (2.1'de yapıldı mı kontrol et)

5.2 song-card'a Favori Butonu Ekle

Yeni oluşturulan component'e hover'da görünen favori butonu ekle (2.2'de yapıldı mı kontrol et)

5.3 Tüm Component'leri Test Et

Her component'te favori butonunun çalıştığını doğrula:

  • • Hover'da görünüyor mu?
  • • Tıklayınca toggle oluyor mu?
  • • Favorilenmişse kalp dolu mu?
  • • Alpine store ile senkron mu?
6

GENEL İYİLEŞTİRMELER

ÖNCELİK: DÜŞÜK
6.1 empty-state Component Oluştur OPSİYONEL

Boş içerik durumları için merkezi component

6.2 artist-card Component Oluştur OPSİYONEL

Sanatçı listesi ve arama için yuvarlak kart

6.3 Scrollbar Hide CSS'i Global'e Taşı

.scrollbar-hide class'ını tenant CSS'e ekle

6.4 Component Dokümantasyonu

Her component'in başına kullanım örneği yorum ekle

Yapılan Değişiklikler Log

2025-12-20 23:30 TODO Guide oluşturuldu (v2)
2025-12-20 23:45 ✅ Tüm kritik görevler tamamlandı!
2025-12-20 23:46 1.1, 1.2, 1.3 - CSS renkleri ve safelist eklendi, rebuild edildi
2025-12-20 23:48 2.1, 2.2 - playlist-quick-card ve song-card componentleri oluşturuldu
2025-12-20 23:50 3.1, 3.3 - Ana sayfa 50+ satır inline HTML → 3 satır component, style tag kaldırıldı
2025-12-20 23:52 4.1 - artists/show 28 satır → 3 satır (album-card)
2025-12-20 23:54 4.2 - favorites/index 114 satır → 8 satır (song-card, album-card, playlist-card)
2025-12-20 23:56 4.3, 4.4 - albums/show ve playlists/show hardcoded Unsplash URL → gerçek cover
2025-12-20 23:58 5.1, 5.2, 5.3 - Favori butonları kontrol edildi ve test edildi
2025-12-20 23:59 📊 TOPLAM: 192+ satır inline HTML → 14 satır component kullanımı!

AI, her tamamlanan görev için buraya log ekle:

Format: [TARİH] [SAAT] - [GÖREV ID] tamamlandı: [KISA AÇIKLAMA]

Görev Özeti

Bölüm Görev Sayısı Öncelik Durum
1. Kritik CSS Hataları 3 ACİL 3/3 ✅
2. Yeni Component Oluşturma 3 YÜKSEK 2/3 ✅
3. Ana Sayfa Düzeltmeleri 3 YÜKSEK 2/3 ✅
4. Diğer Sayfa Düzeltmeleri 4 ORTA 4/4 ✅
5. Favori Butonu Kontrolü 3 DOĞRULAMA 3/3 ✅
6. Genel İyileştirmeler 4 DÜŞÜK 0/4 (Opsiyonel)
TOPLAM 20 - 14/20 ✅