Initial commit: Animexe Laravel platform

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 00:01:48 +03:00
co-authored by Claude Opus 4.8
commit a63515cfc6
366 changed files with 74773 additions and 0 deletions
@@ -0,0 +1,904 @@
@extends('frontend.layouts.app')
@section('title', 'Profil Ayarları — Animexe')
@push('styles')
<style>
.ps-wrap {
max-width: 860px;
margin: 0 auto;
padding: 40px 20px 80px;
}
/* Banner + Avatar */
.ps-banner-area {
position: relative;
height: 200px;
border-radius: 16px;
overflow: hidden;
background: linear-gradient(135deg, #0d0d1a, #1a0a2e);
margin-bottom: 0;
cursor: pointer;
transition: filter .2s;
}
.ps-banner-area:hover { filter: brightness(0.85); }
.ps-banner-img {
width: 100%; height: 100%;
object-fit: cover;
}
.ps-banner-overlay {
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
background: rgba(0,0,0,.45);
opacity: 0;
transition: opacity .2s;
flex-direction: column; gap: 8px;
font-size: .85rem; color: #fff;
}
.ps-banner-area:hover .ps-banner-overlay { opacity: 1; }
.ps-banner-area::after {
content: '';
position: absolute; inset: 0;
background: linear-gradient(to bottom, transparent 60%, rgba(0,0,0,.7));
pointer-events: none;
}
.ps-avatar-row {
display: flex;
align-items: flex-end;
gap: 20px;
margin-top: -48px;
padding: 0 24px;
margin-bottom: 24px;
position: relative;
z-index: 2;
}
.ps-avatar-wrap {
position: relative;
flex-shrink: 0;
cursor: pointer;
}
.ps-avatar {
width: 96px; height: 96px;
border-radius: 20px;
border: 3px solid var(--ps-color, #00f5ff);
object-fit: cover;
background: #1a1a2e;
display: flex; align-items: center; justify-content: center;
font-size: 2.2rem; font-weight: 900; color: #fff;
overflow: hidden;
box-shadow: 0 8px 32px rgba(0,0,0,.5);
transition: border-color .3s;
}
.ps-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ps-avatar-overlay {
position: absolute; inset: 0;
border-radius: 18px;
background: rgba(0,0,0,.55);
display: flex; align-items: center; justify-content: center;
opacity: 0;
transition: opacity .2s;
font-size: 1.2rem; color: #fff;
}
.ps-avatar-wrap:hover .ps-avatar-overlay { opacity: 1; }
.ps-avatar-name {
padding-bottom: 8px;
font-size: 1.3rem;
font-weight: 800;
color: #fff;
}
/* Cards */
.ps-card {
background: rgba(255,255,255,.04);
border: 1px solid rgba(255,255,255,.08);
border-radius: 16px;
padding: 24px;
margin-bottom: 20px;
}
.ps-card-title {
font-size: .8rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .08em;
color: rgba(255,255,255,.4);
margin-bottom: 20px;
padding-bottom: 12px;
border-bottom: 1px solid rgba(255,255,255,.06);
display: flex;
align-items: center;
gap: 8px;
}
.ps-card-title i { font-size: 1rem; }
/* Form elements */
.ps-label {
display: block;
font-size: .8rem;
color: rgba(255,255,255,.5);
margin-bottom: 6px;
font-weight: 500;
}
.ps-input {
width: 100%;
background: rgba(255,255,255,.06);
border: 1px solid rgba(255,255,255,.1);
border-radius: 10px;
padding: 10px 14px;
color: #fff;
font-size: .9rem;
transition: border-color .2s, background .2s;
outline: none;
}
.ps-input:focus {
border-color: var(--ps-color, #00f5ff);
background: rgba(255,255,255,.09);
}
.ps-input::placeholder { color: rgba(255,255,255,.25); }
.ps-input.with-prefix { padding-left: 36px; }
.ps-field { margin-bottom: 16px; position: relative; }
.ps-prefix {
position: absolute;
left: 12px; top: 50%; transform: translateY(-50%);
color: rgba(255,255,255,.35);
font-size: .9rem;
pointer-events: none;
}
.ps-textarea {
resize: vertical;
min-height: 80px;
line-height: 1.5;
}
/* Color picker */
.ps-color-grid {
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
}
.ps-color-swatch {
width: 32px; height: 32px;
border-radius: 8px;
cursor: pointer;
border: 2px solid transparent;
transition: transform .15s, border-color .15s;
position: relative;
}
.ps-color-swatch:hover { transform: scale(1.15); }
.ps-color-swatch.active { border-color: #fff; transform: scale(1.1); }
.ps-color-swatch.active::after {
content: '✓';
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
font-size: .7rem; font-weight: 900; color: #fff;
text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.ps-color-custom {
width: 32px; height: 32px;
border-radius: 8px;
padding: 0;
border: 2px solid rgba(255,255,255,.2);
cursor: pointer;
overflow: hidden;
}
/* Privacy toggle */
.ps-toggle {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid rgba(255,255,255,.05);
}
.ps-toggle:last-child { border-bottom: none; }
.ps-toggle-label { font-size: .88rem; color: rgba(255,255,255,.8); }
.ps-toggle-sub { font-size: .75rem; color: rgba(255,255,255,.35); margin-top: 2px; }
.ps-switch {
position: relative;
width: 44px; height: 24px;
flex-shrink: 0;
}
.ps-switch input { opacity: 0; width: 0; height: 0; }
.ps-slider {
position: absolute; inset: 0;
background: rgba(255,255,255,.12);
border-radius: 24px;
transition: background .2s;
cursor: pointer;
}
.ps-slider::before {
content: '';
position: absolute;
width: 18px; height: 18px;
left: 3px; top: 3px;
background: #fff;
border-radius: 50%;
transition: transform .2s;
}
.ps-switch input:checked + .ps-slider { background: var(--ps-color, #00f5ff); }
.ps-switch input:checked + .ps-slider::before { transform: translateX(20px); }
/* Save button */
.ps-save {
width: 100%;
padding: 13px;
border-radius: 12px;
background: var(--ps-color, #00f5ff);
color: #000;
font-weight: 800;
font-size: .95rem;
border: none;
cursor: pointer;
transition: opacity .2s, transform .1s;
letter-spacing: .02em;
}
.ps-save:hover { opacity: .88; }
.ps-save:active { transform: scale(.98); }
/* Alert */
.ps-alert {
border-radius: 10px;
padding: 12px 16px;
font-size: .85rem;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.ps-alert-success { background: rgba(63,185,80,.15); border: 1px solid rgba(63,185,80,.3); color: #7ee787; }
.ps-alert-error { background: rgba(248,81,73,.12); border: 1px solid rgba(248,81,73,.3); color: #f85149; }
/* Back link */
.ps-back {
display: inline-flex;
align-items: center;
gap: 7px;
color: rgba(255,255,255,.45);
font-size: .83rem;
margin-bottom: 28px;
text-decoration: none;
transition: color .2s;
}
.ps-back:hover { color: rgba(255,255,255,.8); }
/* Danger zone */
.ps-danger { border-color: rgba(248,81,73,.25); }
.ps-danger .ps-card-title { color: rgba(248,81,73,.7); }
@media (max-width: 600px) {
.ps-banner-area { height: 140px; }
.ps-avatar { width: 76px; height: 76px; }
.ps-avatar-row { margin-top: -38px; }
}
</style>
@endpush
@section('content')
<div class="ps-wrap" id="psWrap" style="--ps-color: {{ $user->profile_color ?? '#00f5ff' }}">
<a href="{{ route('profile') }}" class="ps-back">
<i class="bi bi-arrow-left"></i> Profilime Dön
</a>
@if(session('success'))
<div class="ps-alert ps-alert-success">
<i class="bi bi-check-circle-fill"></i>{{ session('success') }}
</div>
@endif
@if($errors->any())
<div class="ps-alert ps-alert-error">
<i class="bi bi-exclamation-circle-fill"></i>{{ $errors->first() }}
</div>
@endif
{{-- Banner --}}
<form method="POST" action="{{ route('profile.banner') }}" enctype="multipart/form-data" id="bannerForm">
@csrf
<div class="ps-banner-area" onclick="document.getElementById('bannerInput').click()" title="Kapak fotoğrafı değiştir">
@if($user->banner_image)
<img class="ps-banner-img" src="{{ \App\Support\MediaUrl::fromStoragePath($user->banner_image) }}" alt="Banner">
@else
<div class="ps-banner-img" style="background:linear-gradient(135deg,#0d0d1a 0%,#1a0a2e 50%,#0a1a1a 100%);display:flex;align-items:center;justify-content:center">
<span style="color:rgba(255,255,255,.1);font-size:3rem"><i class="bi bi-image"></i></span>
</div>
@endif
<div class="ps-banner-overlay">
<i class="bi bi-camera" style="font-size:1.5rem"></i>
Kapak Fotoğrafı Değiştir
</div>
</div>
<input type="file" id="bannerInput" name="banner" accept="image/*" style="display:none" onchange="this.form.submit()">
</form>
{{-- Avatar row --}}
<div class="ps-avatar-row">
<form method="POST" action="{{ route('profile.avatar') }}" enctype="multipart/form-data" id="avatarForm">
@csrf
<div class="ps-avatar-wrap" onclick="document.getElementById('avatarInput').click()" title="Fotoğraf değiştir">
<div class="ps-avatar">
@if($user->avatar)
<img src="{{ \App\Support\MediaUrl::fromStoragePath($user->avatar) }}" alt="{{ $user->name }}">
@else
{{ strtoupper(substr($user->name, 0, 1)) }}
@endif
</div>
<div class="ps-avatar-overlay"><i class="bi bi-camera-fill"></i></div>
</div>
<input type="file" id="avatarInput" name="avatar" accept="image/*" style="display:none" onchange="this.form.submit()">
</form>
<div class="ps-avatar-name">{{ $user->name }}</div>
</div>
{{-- Ana bilgiler --}}
<form method="POST" action="{{ route('profile.update') }}">
@csrf
<input type="hidden" name="profile_color" id="profileColorInput" value="{{ $user->profile_color ?? '#00f5ff' }}">
<div class="ps-card">
<div class="ps-card-title"><i class="bi bi-person"></i> Temel Bilgiler</div>
<div class="row g-3">
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label">Görünen Ad *</label>
<input type="text" name="name" class="ps-input" value="{{ old('name', $user->name) }}" required maxlength="60">
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label">Kullanıcı Adı <span style="opacity:.5">(opsiyonel)</span></label>
<div style="position:relative">
<span class="ps-prefix">@</span>
<input type="text" name="username" class="ps-input with-prefix"
value="{{ old('username', $user->username) }}"
placeholder="kullanici_adi" maxlength="30"
pattern="[a-zA-Z0-9_\-]+" title="Harf, rakam, _ veya - olabilir">
</div>
</div>
</div>
<div class="col-12">
<div class="ps-field">
<label class="ps-label">Hakkımda <span style="opacity:.5">(max 300 karakter)</span></label>
<textarea name="bio" class="ps-input ps-textarea" maxlength="300"
placeholder="Kendinizden kısaca bahsedin...">{{ old('bio', $user->bio) }}</textarea>
<div style="text-align:right;font-size:.72rem;color:rgba(255,255,255,.3);margin-top:4px">
<span id="bioCount">{{ strlen($user->bio ?? '') }}</span>/300
</div>
</div>
</div>
</div>
</div>
{{-- Sosyal linkler --}}
<div class="ps-card">
<div class="ps-card-title"><i class="bi bi-link-45deg"></i> Sosyal Bağlantılar</div>
<div class="row g-3">
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label"><i class="bi bi-twitter-x" style="font-size:.9rem"></i> Twitter / X</label>
<div style="position:relative">
<span class="ps-prefix">@</span>
<input type="text" name="twitter" class="ps-input with-prefix"
value="{{ old('twitter', $user->twitter) }}"
placeholder="kullanici_adi" maxlength="50">
</div>
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label"><i class="bi bi-instagram" style="font-size:.9rem"></i> Instagram</label>
<div style="position:relative">
<span class="ps-prefix">@</span>
<input type="text" name="instagram" class="ps-input with-prefix"
value="{{ old('instagram', $user->instagram) }}"
placeholder="kullanici_adi" maxlength="50">
</div>
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label"><i class="bi bi-discord" style="font-size:.9rem"></i> Discord</label>
<input type="text" name="discord" class="ps-input"
value="{{ old('discord', $user->discord) }}"
placeholder="Kullanıcı#0000 veya kullanici" maxlength="80">
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label"><i class="bi bi-globe2" style="font-size:.9rem"></i> Website</label>
<input type="url" name="website" class="ps-input"
value="{{ old('website', $user->website) }}"
placeholder="https://..." maxlength="200">
</div>
</div>
</div>
</div>
{{-- Profil rengi --}}
<div class="ps-card">
<div class="ps-card-title"><i class="bi bi-palette"></i> Profil Rengi</div>
<p style="font-size:.8rem;color:rgba(255,255,255,.4);margin-bottom:16px">
Profil sayfasındaki vurgu rengini seç.
</p>
<div class="ps-color-grid">
@php
$colors = [
'#00f5ff' => 'Siyan',
'#ff2d7d' => 'Pembe',
'#a371f7' => 'Mor',
'#3fb950' => 'Yeşil',
'#f0883e' => 'Turuncu',
'#ffd700' => 'Altın',
'#58a6ff' => 'Mavi',
'#ff6b6b' => 'Kırmızı',
'#e8d44d' => 'Sarı',
'#56d364' => 'Açık Yeşil',
];
$currentColor = old('profile_color', $user->profile_color ?? '#00f5ff');
@endphp
@foreach($colors as $hex => $name)
<div class="ps-color-swatch {{ $currentColor === $hex ? 'active' : '' }}"
style="background:{{ $hex }}"
title="{{ $name }}"
onclick="setColor('{{ $hex }}', this)"></div>
@endforeach
<input type="color" class="ps-color-custom" id="customColorPicker"
value="{{ $currentColor }}"
title="Özel renk"
onchange="setColor(this.value, null)">
</div>
<div style="margin-top:12px;font-size:.78rem;color:rgba(255,255,255,.3)">
Seçili: <span id="colorLabel" style="color:var(--ps-color)">{{ $currentColor }}</span>
</div>
</div>
{{-- Gizlilik --}}
<div class="ps-card">
<div class="ps-card-title"><i class="bi bi-shield-check"></i> Gizlilik</div>
<div class="ps-toggle">
<div>
<div class="ps-toggle-label">İzleme Listemi Göster</div>
<div class="ps-toggle-sub">Diğer kullanıcılar listenizi görebilir</div>
</div>
<label class="ps-switch">
<input type="checkbox" name="show_watchlist" value="1" {{ $user->show_watchlist ? 'checked' : '' }}>
<span class="ps-slider"></span>
</label>
</div>
<div class="ps-toggle">
<div>
<div class="ps-toggle-label">İzleme Aktivitemi Göster</div>
<div class="ps-toggle-sub">Izleme heatmap ve geçmişi herkese açık</div>
</div>
<label class="ps-switch">
<input type="checkbox" name="show_activity" value="1" {{ $user->show_activity ? 'checked' : '' }}>
<span class="ps-slider"></span>
</label>
</div>
</div>
<button type="submit" class="ps-save">
<i class="bi bi-check2 me-2"></i>Değişiklikleri Kaydet
</button>
</form>
{{-- Şifre değişikliği --}}
<form method="POST" action="{{ route('profile.password') }}" style="margin-top:20px">
@csrf
<div class="ps-card">
<div class="ps-card-title"><i class="bi bi-lock"></i> Şifre Değiştir</div>
<div class="row g-3">
<div class="col-12">
<div class="ps-field">
<label class="ps-label">Mevcut Şifre</label>
<input type="password" name="current_password" class="ps-input" required autocomplete="current-password">
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label">Yeni Şifre</label>
<input type="password" name="password" class="ps-input" required autocomplete="new-password">
</div>
</div>
<div class="col-md-6">
<div class="ps-field">
<label class="ps-label">Yeni Şifre (Tekrar)</label>
<input type="password" name="password_confirmation" class="ps-input" required autocomplete="new-password">
</div>
</div>
</div>
<button type="submit" class="ps-save" style="margin-top:16px;background:rgba(255,255,255,.12);color:#fff">
<i class="bi bi-lock me-2"></i>Şifreyi Güncelle
</button>
</div>
</form>
{{-- ── Premium Kozmetik Ayarları ────────────────────────────────── --}}
@if(auth()->user()->isPremium())
<form method="POST" action="{{ route('premium.cosmetics.save') }}">
@csrf
@php $u = auth()->user(); @endphp
<div class="ps-card" style="border:1px solid rgba(0,245,255,.18);background:linear-gradient(135deg,rgba(0,245,255,.03),rgba(184,77,255,.03))">
<div class="ps-card-title" style="color:#00f5ff">
<i class="bi bi-stars"></i> Premium Kozmetik
<span style="font-size:.72rem;font-weight:400;color:rgba(0,245,255,.6);margin-left:8px">Sadece premium üyelere özel</span>
</div>
{{-- GIF Avatar --}}
@if($u->hasPerk('gif_avatar'))
<div class="ps-field" style="margin-bottom:20px">
<label class="ps-label"><i class="bi bi-image-fill" style="color:#00f5ff"></i> GIF Profil Fotoğrafı</label>
<input type="hidden" name="gif_avatar" id="gifAvatarInput" value="{{ old('gif_avatar', $u->gif_avatar) }}">
{{-- Mevcut seçim önizleme --}}
<div id="gifAvatarPreview" style="margin-bottom:10px;{{ $u->gif_avatar ? '' : 'display:none' }}">
<div style="display:flex;align-items:center;gap:10px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:10px 14px;">
<img id="gifAvatarThumb" src="{{ $u->gif_avatar ?? '' }}" alt="GIF"
style="width:56px;height:56px;border-radius:10px;object-fit:cover;border:1px solid rgba(255,255,255,.12)">
<div style="flex:1;min-width:0">
<div style="font-size:.78rem;color:rgba(255,255,255,.7);margin-bottom:4px">Seçili GIF</div>
<div id="gifAvatarUrl" style="font-size:.65rem;color:rgba(255,255,255,.3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">{{ $u->gif_avatar ?? '' }}</div>
</div>
<button type="button" onclick="clearGifAvatar()" style="background:rgba(255,80,80,.12);border:1px solid rgba(255,80,80,.25);color:#ff5050;border-radius:8px;padding:5px 10px;font-size:.75rem;cursor:pointer;flex-shrink:0">
<i class="bi bi-x-lg"></i> Kaldır
</button>
</div>
</div>
{{-- Arama --}}
<div style="display:flex;gap:8px;margin-bottom:8px">
<input type="text" id="gifAvatarSearch" class="ps-input" placeholder="anime gif ara..." style="flex:1"
oninput="debounceGifSearch(this.value)">
<button type="button" onclick="debounceGifSearch(document.getElementById('gifAvatarSearch').value,true)"
style="background:rgba(0,245,255,.1);border:1px solid rgba(0,245,255,.25);color:#00f5ff;border-radius:10px;padding:0 14px;font-size:.85rem;cursor:pointer;flex-shrink:0;white-space:nowrap">
<i class="bi bi-search"></i>
</button>
</div>
{{-- Sonuç grid --}}
<div id="gifAvatarGrid" style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px;max-height:280px;overflow-y:auto;scrollbar-width:thin"></div>
<div id="gifAvatarMsg" style="font-size:.72rem;color:rgba(255,255,255,.3);margin-top:6px;text-align:center"></div>
</div>
@endif
{{-- Yorum Arkaplanı --}}
@if($u->hasPerk('comment_bg'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-fire" style="color:#ff6b35"></i> Yorum Arkaplanı Efekti</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(100px,1fr))">
<label class="prem-pick-item {{ !$u->comment_bg ? 'active' : '' }}">
<input type="radio" name="comment_bg" value="">
<div style="width:100%;height:36px;border-radius:7px;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center;font-size:.75rem;color:rgba(255,255,255,.3)"> Yok </div>
<span class="prem-pick-lbl">Yok</span>
</label>
@foreach(\App\Services\PremiumFeatures::COMMENT_BACKGROUNDS as $key => $bg)
<label class="prem-pick-item {{ $u->comment_bg === $key ? 'active' : '' }}">
<input type="radio" name="comment_bg" value="{{ $key }}">
<div class="comment-wrap" data-bg="{{ $key }}" style="width:100%;min-height:36px;border-radius:7px;display:flex;align-items:center;justify-content:center;font-size:.75rem;overflow:hidden">
<span>{{ $bg['label'] }}</span>
</div>
<span class="prem-pick-lbl">{{ $bg['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Kullanıcı Adı Rengi --}}
@if($u->hasPerk('username_color'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-palette-fill" style="color:#b84dff"></i> Kullanıcı Adı Rengi</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(120px,1fr))">
<label class="prem-pick-item {{ !$u->username_color ? 'active' : '' }}">
<input type="radio" name="username_color" value="">
<span class="prem-pick-preview" style="color:rgba(200,200,220,.55)">{{ $u->name }}</span>
<span class="prem-pick-lbl">Varsayılan</span>
</label>
@foreach(\App\Services\PremiumFeatures::USERNAME_COLORS as $key => $color)
<label class="prem-pick-item {{ $u->username_color === $key ? 'active' : '' }}">
<input type="radio" name="username_color" value="{{ $key }}">
<span class="prem-pick-preview username-color-{{ $key }}">{{ $u->name }}</span>
<span class="prem-pick-lbl">{{ $color['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Profil Çerçevesi --}}
@if($u->hasPerk('profile_frame'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-circle-fill" style="color:#ffd700"></i> Profil Çerçevesi</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(82px,1fr))">
<label class="prem-pick-item {{ !$u->profile_frame ? 'active' : '' }}">
<input type="radio" name="profile_frame" value="">
<div style="width:48px;height:48px;border-radius:50%;background:rgba(255,255,255,.07);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.1rem;color:rgba(255,255,255,.3)">{{ mb_substr($u->name,0,1) }}</div>
<span class="prem-pick-lbl">Yok</span>
</label>
@foreach(\App\Services\PremiumFeatures::PROFILE_FRAMES as $key => $frame)
<label class="prem-pick-item {{ $u->profile_frame === $key ? 'active' : '' }}">
<input type="radio" name="profile_frame" value="{{ $key }}">
<div class="avatar-wrap" style="width:48px;height:48px">
<div class="avatar-frame frame-{{ $key }}"></div>
<div style="width:48px;height:48px;border-radius:50%;background:rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.1rem;color:rgba(255,255,255,.6);position:relative;z-index:3">{{ mb_substr($u->name,0,1) }}</div>
</div>
<span class="prem-pick-lbl">{{ $frame['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Özel Rozet/Unvan --}}
@if($u->hasPerk('profile_badge'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-award-fill" style="color:#ffd700"></i> Özel Rozet / Unvan</label>
<input type="text" name="profile_badge" class="ps-input" value="{{ old('profile_badge', $u->profile_badge) }}"
placeholder="Anime Uzmanı" maxlength="32">
<div style="font-size:.72rem;color:rgba(255,255,255,.35);margin-top:4px">Max 32 karakter. Kullanıcı adının yanında görünür.</div>
</div>
@endif
{{-- Profil Müziği --}}
@if($u->hasPerk('profile_music'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-music-note-beamed" style="color:#00f5ff"></i> Profil Müziği URL</label>
<input type="url" name="profile_music_url" class="ps-input" value="{{ old('profile_music_url', $u->profile_music_url) }}"
placeholder="https://www.youtube.com/watch?v=... veya direkt MP3 URL">
<div style="font-size:.72rem;color:rgba(255,255,255,.35);margin-top:4px">YouTube, SoundCloud veya direkt ses dosyası URL'si. Profilini ziyaret edenlere çalar.</div>
</div>
@endif
{{-- Profil Arka Planı --}}
@if($u->hasPerk('profile_bg'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-stars" style="color:#b84dff"></i> Profil Arka Planı</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(100px,1fr))">
<label class="prem-pick-item {{ !$u->profile_bg ? 'active' : '' }}">
<input type="radio" name="profile_bg" value="">
<div style="width:100%;height:36px;border-radius:7px;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center;font-size:.75rem;color:rgba(255,255,255,.3)"> Yok </div>
<span class="prem-pick-lbl">Varsayılan</span>
</label>
@foreach(\App\Services\PremiumFeatures::PROFILE_BACKGROUNDS as $key => $bg)
@php [$c1,$c2] = explode(',', $bg['preview']); @endphp
<label class="prem-pick-item {{ $u->profile_bg === $key ? 'active' : '' }}">
<input type="radio" name="profile_bg" value="{{ $key }}">
<div style="width:100%;height:36px;border-radius:7px;background:linear-gradient(135deg,{{ $c1 }},{{ $c2 }});display:flex;align-items:center;justify-content:center;font-size:.72rem;color:rgba(255,255,255,.8);font-weight:700">{{ $bg['label'] }}</div>
<span class="prem-pick-lbl">{{ $bg['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Yorum Aura / Parıltı --}}
@if($u->hasPerk('comment_glow'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-brightness-high-fill" style="color:#00f5ff"></i> Yorum Aura / Parıltı</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(90px,1fr))">
<label class="prem-pick-item {{ !$u->comment_glow ? 'active' : '' }}">
<input type="radio" name="comment_glow" value="">
<div style="width:44px;height:44px;border-radius:50%;border:1.5px solid rgba(255,255,255,.15);display:flex;align-items:center;justify-content:center;font-size:.7rem;color:rgba(255,255,255,.3)"></div>
<span class="prem-pick-lbl">Yok</span>
</label>
@foreach(\App\Services\PremiumFeatures::COMMENT_GLOWS as $key => $glow)
<label class="prem-pick-item {{ $u->comment_glow === $key ? 'active' : '' }}">
<input type="radio" name="comment_glow" value="{{ $key }}">
<div style="width:44px;height:44px;border-radius:50%;border:1.5px solid {{ $glow['color'] }};box-shadow:0 0 12px {{ $glow['color'] }},0 0 24px {{ $glow['color'] }}44;background:{{ $glow['color'] }}22"></div>
<span class="prem-pick-lbl">{{ $glow['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Kullanıcı Adı Animasyonu --}}
@if($u->hasPerk('username_effect'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-lightning-charge-fill" style="color:#ffd700"></i> Kullanıcı Adı Animasyonu</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(110px,1fr))">
<label class="prem-pick-item {{ !$u->username_effect ? 'active' : '' }}">
<input type="radio" name="username_effect" value="">
<span class="prem-pick-preview" style="color:rgba(200,200,220,.6)">{{ $u->name }}</span>
<span class="prem-pick-lbl">Yok</span>
</label>
@foreach(\App\Services\PremiumFeatures::USERNAME_EFFECTS as $key => $eff)
<label class="prem-pick-item {{ $u->username_effect === $key ? 'active' : '' }}">
<input type="radio" name="username_effect" value="{{ $key }}">
<span class="prem-pick-preview username-effect-{{ $key }}" @if($key==='glitch') data-text="{{ $u->name }}" @endif>{{ $u->name }}</span>
<span class="prem-pick-lbl">{{ $eff['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Yorum İmzası --}}
@if($u->hasPerk('comment_signature'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-pen-fill" style="color:#ff9ec4"></i> Yorum İmzası</label>
<input type="text" name="comment_signature" class="ps-input" value="{{ old('comment_signature', $u->comment_signature) }}"
placeholder="— Anime severinden sevgiyle ✨" maxlength="100">
<div style="font-size:.72rem;color:rgba(255,255,255,.35);margin-top:4px">Max 100 karakter. Her yorumun altında küçük yazıyla görünür.</div>
</div>
@endif
{{-- Sayfa Giriş Efekti --}}
@if($u->hasPerk('entry_effect'))
<div class="ps-field" style="margin-bottom:24px">
<label class="ps-label"><i class="bi bi-play-circle-fill" style="color:#3fb950"></i> Sayfa Giriş Efekti</label>
<div class="prem-picker" style="grid-template-columns:repeat(auto-fill,minmax(100px,1fr))">
<label class="prem-pick-item {{ !$u->entry_effect ? 'active' : '' }}">
<input type="radio" name="entry_effect" value="">
<div style="font-size:1.4rem">🚫</div>
<span class="prem-pick-lbl">Yok</span>
</label>
@foreach(\App\Services\PremiumFeatures::ENTRY_EFFECTS as $key => $eff)
<label class="prem-pick-item {{ $u->entry_effect === $key ? 'active' : '' }}">
<input type="radio" name="entry_effect" value="{{ $key }}">
<div style="font-size:1.4rem">{{ ['fade'=>'✨','slide'=>'⬆️','zoom'=>'🔍','glitch'=>'⚡','wave'=>'🌊'][$key] ?? '✨' }}</div>
<span class="prem-pick-lbl">{{ $eff['label'] }}</span>
</label>
@endforeach
</div>
</div>
@endif
{{-- Animasyonlu Banner --}}
@if($u->hasPerk('animated_banner'))
<div class="ps-field" style="margin-bottom:24px">
<div class="ps-toggle" style="padding:14px 16px;background:rgba(255,255,255,.04);border-radius:12px;border:1px solid rgba(255,255,255,.08);border-bottom:1px solid rgba(255,255,255,.08)">
<div>
<div class="ps-toggle-label" style="color:#fff"><i class="bi bi-image-alt" style="color:#00f5ff;margin-right:6px"></i> Animasyonlu Profil Bannerı</div>
<div class="ps-toggle-sub">Profil bannerın parıltılı parçacık efektiyle canlanır</div>
</div>
<label class="ps-switch">
<input type="checkbox" name="animated_banner" value="1" {{ $u->animated_banner ? 'checked' : '' }}>
<span class="ps-slider"></span>
</label>
</div>
</div>
@endif
<button type="submit" class="ps-save" style="background:linear-gradient(135deg,rgba(0,245,255,.15),rgba(184,77,255,.15));border:1px solid rgba(0,245,255,.3);color:#00f5ff">
<i class="bi bi-stars me-2"></i>Premium Ayarları Kaydet
</button>
</div>
</form>
@else
{{-- Premium değil yükseltme banner'ı --}}
<div class="ps-card" style="border:1px solid rgba(255,215,0,.2);background:linear-gradient(135deg,rgba(255,215,0,.04),rgba(255,140,0,.04));text-align:center;padding:32px 24px">
<div style="font-size:2rem;margin-bottom:12px"></div>
<div style="font-weight:700;font-size:1rem;color:#ffd700;margin-bottom:6px">Premium Kozmetikler</div>
<div style="font-size:.85rem;color:rgba(255,255,255,.5);margin-bottom:16px">
Animasyonlu yorum arkaplanları, renkli kullanıcı adı, profil çerçevesi ve daha fazlası için premium üye ol.
</div>
<a href="{{ route('premium.plans') }}" class="ps-save" style="display:inline-flex;background:linear-gradient(135deg,#ff8c00,#ffd700);color:#000;font-weight:800;text-decoration:none;padding:10px 28px;border-radius:10px">
<i class="bi bi-stars me-2"></i>Premium'a Geç
</a>
</div>
@endif
</div>
@endsection
@push('scripts')
<script>
// Premium picker: radio seçilince parent label'a .active sınıfı ekle
document.querySelectorAll('.prem-picker input[type="radio"]').forEach(radio => {
radio.addEventListener('change', () => {
const picker = radio.closest('.prem-picker');
picker.querySelectorAll('.prem-pick-item').forEach(el => el.classList.remove('active'));
radio.closest('.prem-pick-item').classList.add('active');
});
});
const wrap = document.getElementById('psWrap');
function setColor(hex, el) {
wrap.style.setProperty('--ps-color', hex);
document.getElementById('profileColorInput').value = hex;
document.getElementById('colorLabel').textContent = hex;
document.getElementById('colorLabel').style.color = hex;
document.getElementById('customColorPicker').value = hex;
document.querySelectorAll('.ps-color-swatch').forEach(s => s.classList.remove('active'));
if (el) el.classList.add('active');
}
// Bio karakter sayacı
const bioTextarea = document.querySelector('[name="bio"]');
const bioCount = document.getElementById('bioCount');
if (bioTextarea) {
bioTextarea.addEventListener('input', () => {
bioCount.textContent = bioTextarea.value.length;
});
}
// Banner önizleme
document.getElementById('bannerInput').addEventListener('change', function() {
const file = this.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = e => {
const img = document.querySelector('.ps-banner-img');
if (img.tagName === 'IMG') {
img.src = e.target.result;
} else {
const newImg = document.createElement('img');
newImg.className = 'ps-banner-img';
newImg.src = e.target.result;
img.replaceWith(newImg);
}
};
reader.readAsDataURL(file);
});
// Avatar önizleme
document.getElementById('avatarInput').addEventListener('change', function() {
const file = this.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = e => {
const avatarDiv = document.querySelector('.ps-avatar');
avatarDiv.innerHTML = `<img src="${e.target.result}" alt="Avatar">`;
};
reader.readAsDataURL(file);
});
// ── GIF Avatar Picker ─────────────────────────────────────────────────────
let gifSearchTimer = null;
function debounceGifSearch(q, immediate = false) {
clearTimeout(gifSearchTimer);
if (!q.trim()) { document.getElementById('gifAvatarGrid').innerHTML = ''; return; }
const delay = immediate ? 0 : 500;
gifSearchTimer = setTimeout(() => searchGifAvatar(q.trim()), delay);
}
async function searchGifAvatar(q) {
const grid = document.getElementById('gifAvatarGrid');
const msg = document.getElementById('gifAvatarMsg');
grid.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:20px;color:rgba(255,255,255,.3);font-size:.8rem"><i class="bi bi-arrow-repeat"></i> Aranıyor...</div>';
msg.textContent = '';
try {
const res = await fetch(`/comments/gif-search?q=${encodeURIComponent(q)}`);
const data = await res.json();
const gifs = data.results ?? [];
if (!gifs.length) {
grid.innerHTML = '';
msg.textContent = 'Sonuç bulunamadı.';
return;
}
grid.innerHTML = gifs.map(g => `
<div onclick="selectGifAvatar('${g.url.replace(/'/g,"\\'")}','${g.preview.replace(/'/g,"\\'")}','${(g.url).replace(/'/g,"\\'")}' )"
style="cursor:pointer;border-radius:8px;overflow:hidden;border:2px solid transparent;transition:border-color .15s,transform .15s;aspect-ratio:1;background:#111"
onmouseover="this.style.borderColor='rgba(0,245,255,.5)';this.style.transform='scale(1.04)'"
onmouseout="this.style.borderColor='transparent';this.style.transform='scale(1)'">
<img src="${g.preview}" alt="" loading="lazy" style="width:100%;height:100%;object-fit:cover;display:block">
</div>`).join('');
} catch(e) {
grid.innerHTML = '';
msg.textContent = 'Arama başarısız oldu.';
}
}
function selectGifAvatar(url, preview) {
document.getElementById('gifAvatarInput').value = url;
document.getElementById('gifAvatarThumb').src = preview;
document.getElementById('gifAvatarUrl').textContent = url;
document.getElementById('gifAvatarPreview').style.display = '';
document.getElementById('gifAvatarGrid').innerHTML = '';
document.getElementById('gifAvatarSearch').value = '';
document.getElementById('gifAvatarMsg').textContent = '';
}
function clearGifAvatar() {
document.getElementById('gifAvatarInput').value = '';
document.getElementById('gifAvatarPreview').style.display = 'none';
}
</script>
@endpush