@extends('layouts.app') @section('title', $user->name . ' — Channel | ' . config('app.name')) @section('main_class', 'no-pad') @section('extra_styles') @endsection @section('content') {{-- ─────────────── PREVIEW BANNER ─────────────────── --}} @if($preview)
You're viewing your profile as others see it
Back to my channel
@endif {{-- ───────────────────── BANNER ───────────────────── --}}
@if($user->banner) @endif
@if($isOwner && !$preview) @else
@auth @else Subscribe @endauth
@endif
{{-- ─────────────────── CHANNEL HEADER ─────────────── --}} @php $headerSocialMap = [ 'twitter' => ['icon'=>'bi-twitter-x', 'color'=>'#38bdf8', 'bg'=>'rgba(56,189,248,.1)', 'hover'=>'#38bdf8', 'href'=>fn($v)=>"https://twitter.com/{$v}"], 'instagram' => ['icon'=>'bi-instagram', 'color'=>'#818cf8', 'bg'=>'rgba(129,140,248,.1)', 'hover'=>'#818cf8', 'href'=>fn($v)=>"https://instagram.com/{$v}"], 'facebook' => ['icon'=>'bi-facebook', 'color'=>'#60a5fa', 'bg'=>'rgba(96,165,250,.1)', 'hover'=>'#60a5fa', 'href'=>fn($v)=>"https://facebook.com/{$v}"], 'youtube' => ['icon'=>'bi-youtube', 'color'=>'#94a3b8', 'bg'=>'rgba(148,163,184,.1)', 'hover'=>'#94a3b8', 'href'=>fn($v)=>"https://youtube.com/@{$v}"], 'tiktok' => ['icon'=>'bi-tiktok', 'color'=>'#67e8f9', 'bg'=>'rgba(103,232,249,.1)', 'hover'=>'#67e8f9', 'href'=>fn($v)=>"https://tiktok.com/@{$v}"], 'linkedin' => ['icon'=>'bi-linkedin', 'color'=>'#7dd3fc', 'bg'=>'rgba(125,211,252,.1)', 'hover'=>'#7dd3fc', 'href'=>fn($v)=>"https://linkedin.com/in/{$v}"], 'whatsapp' => ['icon'=>'bi-whatsapp', 'color'=>'#4ade80', 'bg'=>'rgba(74,222,128,.1)', 'hover'=>'#4ade80', 'href'=>fn($v)=>"https://wa.me/".preg_replace('/\D/','',$v)], 'website' => ['icon'=>'bi-globe2', 'color'=>'#a78bfa', 'bg'=>'rgba(167,139,250,.1)', 'hover'=>'#a78bfa', 'href'=>fn($v)=>preg_match('/^https?:\/\//',$v)?$v:"https://{$v}"], 'social_phone' => ['icon'=>'bi-telephone-fill', 'color'=>'#34d399', 'bg'=>'rgba(52,211,153,.1)', 'hover'=>'#34d399', 'href'=>fn($v)=>"tel:{$v}"], 'social_email' => ['icon'=>'bi-envelope-fill', 'color'=>'#fbbf24', 'bg'=>'rgba(251,191,36,.1)', 'hover'=>'#fbbf24', 'href'=>fn($v)=>"mailto:{$v}"], 'google_location'=> ['icon'=>'bi-geo-alt-fill', 'color'=>'#6ee7b7', 'bg'=>'rgba(110,231,183,.1)', 'hover'=>'#6ee7b7', 'href'=>fn($v)=>$v], ]; @endphp
{{-- Avatar --}}
{{ $user->name }} @if($isOwner && !$preview) @endif
{{-- Info --}}
{{-- Name row --}}

{{ $user->name }}

@if($user->email_verified_at) @endif
{{-- Flat stats row — no pills --}}
{{ number_format($videos->count() + $shorts->count()) }} videos · {{ number_format($totalViews) }} views · {{ number_format($user->subscriber_count) }} {{ Str::plural('subscriber', $user->subscriber_count) }} @if($user->location) · {{ $user->location }} @endif · Joined {{ $user->created_at->format('M Y') }} @if($user->birthday) @php $age = \Carbon\Carbon::parse($user->birthday)->age; @endphp · {{ $age }} yrs @endif @if($user->gender === 'male') · Male @elseif($user->gender === 'female') · Female @endif
@if($user->bio)
{{ $user->bio }} @if(strlen($user->bio) > 120) @endif
@endif {{-- Horoscope + Compatibility strip & Social buttons side by side --}} @if($horoscope || $socialLinks->isNotEmpty()) @php $hColor = $horoscope ? \App\Helpers\Horoscope::elementColor($horoscope['element']) : null; $showCompat = $horoscope && ($compatibility !== null && $viewerSign && !$isOwner); if ($showCompat) { $compatColor = $compatibility >= 75 ? '#22c55e' : ($compatibility >= 55 ? '#eab308' : '#ef4444'); $compatLabel = $compatibility >= 85 ? 'Soulmates' : ($compatibility >= 70 ? 'Great match' : ($compatibility >= 55 ? 'Good vibes' : ($compatibility >= 40 ? 'Some friction' : 'Tough combo'))); } @endphp
@if($horoscope)
{{ $horoscope['emoji'] }} {{ $horoscope['name'] }} {{ $horoscope['element'] }}
@if($showCompat)
❤️ {{ $compatibility }}%
{{ $compatLabel }}
@endif
@endif @if($socialLinks->isNotEmpty())
@foreach($socialLinks as $slink) @if(isset($headerSocialMap[$slink->platform])) @php $sm = $headerSocialMap[$slink->platform]; @endphp @endif @endforeach
@endif
@endif {{-- Action buttons (owner only) --}} @if($isOwner && !$preview)
{{-- Logout All Devices Modal — appended to body on open to escape stacking context --}} @endif
{{-- ──────────────────────── TABS ───────────────────── --}}
@if($shorts->count() > 0) @endif @if(($playlists && $playlists->count() > 0) || $isOwner) @endif @if($isOwner) @endif
{{-- spacer pushes content below the fixed tabs bar on mobile --}} {{-- ─────────────────────── WALL TAB ────────────────── --}}
{{-- ── LEFT: composer + feed ── --}}
{{-- Composer (owner only) --}} @auth @if(Auth::id() === $user->id)
@csrf
{{ Auth::user()->name }}
{{-- Multi-image preview grid --}} {{-- Selected video chips --}}
@if($user->videos->count() > 0) @endif
@endif @endauth {{-- Posts feed --}} @forelse($posts as $post) @php $postLiked = Auth::check() && $post->isLikedBy(Auth::user()); $bodyLen = strlen($post->body ?? ''); $isShort = $bodyLen > 0 && $bodyLen <= 80 && !$post->image && !$post->video_id && !$post->postImages->count() && !$post->postVideos->count(); @endphp
{{-- Header --}}
{{ $post->user->name }} @auth @if(Auth::id() === $post->user_id || Auth::user()->isAdmin())
@csrf @method('DELETE')
@endif @endauth
{{-- Body --}} @if($post->body)
{{ $post->body }}
@endif {{-- Images (new multi-image) --}} @php $postImgs = $post->postImages; $legacyImg = (!$postImgs->count() && $post->image) ? $post->image_url : null; $imgCount = $postImgs->count() ?: ($legacyImg ? 1 : 0); $countClass = $imgCount === 1 ? 'count-1' : ($imgCount === 2 ? 'count-2' : ($imgCount === 3 ? 'count-3' : ($imgCount === 4 ? 'count-4' : ($imgCount > 4 ? 'count-more' : '')))); @endphp @if($imgCount > 0)
@if($legacyImg)
@else @foreach($postImgs->take(4) as $idx => $img)
@if($idx === 3 && $imgCount > 4)
+{{ $imgCount - 4 }}
@endif
@endforeach @endif
@endif {{-- Videos (new multi-video) --}} @php $postVids = $post->postVideos->filter(fn($pv) => $pv->video?->exists); $legacyVid = (!$postVids->count() && $post->video_id && $post->video?->exists) ? $post->video : null; $allVids = $legacyVid ? collect([$legacyVid]) : $postVids->map(fn($pv) => $pv->video); @endphp @if($allVids->count())
@foreach($allVids as $v)
{{ $v->title }}
{{ \Illuminate\Support\Number::abbreviate($v->view_count, precision: 1) }} @if($v->duration) {{ $v->formatted_duration }}@endif @if($v->is_shorts) Short@endif
@endforeach
@endif {{-- Actions --}}
@auth @else {{ $post->reaction_count > 0 ? $post->reaction_count : '' }} Like @endauth
@empty {{-- Empty state --}}

Nothing here yet

@auth @if(Auth::id() === $user->id)

This is your wall. Share a thought, a photo, or one of your videos with your community!

@else

{{ $user->name }} hasn't shared anything yet — check back soon!

@endif @else

{{ $user->name }} hasn't shared anything yet. Sign in to be notified when they do.

@endauth
@endforelse
{{-- ── RIGHT: sidebar ── --}}
@if(!$horoscope && $isOwner)
🔮
Your Horoscope Awaits

Add your birthday to unlock your zodiac sign, age, personality traits, and compatibility with visitors.

@elseif($horoscope) @php $swHColor = \App\Helpers\Horoscope::elementColor($horoscope['element']); $swPct = $compatibility; $swCColor = $swPct !== null ? ($swPct >= 75 ? '#4ade80' : ($swPct >= 55 ? '#fbbf24' : '#f87171')) : null; $swLabel = $swPct !== null ? ($swPct >= 85 ? 'Soulmates' : ($swPct >= 70 ? 'Great Match' : ($swPct >= 55 ? 'Good Vibes' : ($swPct >= 40 ? 'Some Friction' : 'Tough Combo')))) : null; $swEmoji = $swPct !== null ? ($swPct >= 85 ? '✨' : ($swPct >= 70 ? '💛' : ($swPct >= 55 ? '🙂' : ($swPct >= 40 ? '🤔' : '⚡')))) : null; @endphp
{{-- Sign row --}}
{{ $horoscope['emoji'] }}
{{ $horoscope['name'] }} {{ $horoscope['symbol'] }}
{{ $horoscope['element'] }} sign
{{-- Traits --}}
@foreach($horoscope['traits'] as $trait) {{ $trait }} @endforeach
{{-- Compat section --}} @if($swPct !== null && $viewerSign)
{{ $viewerSign['emoji'] }}You ❤️ {{ $horoscope['emoji'] }}{{ explode(' ', $user->name)[0] }}
{{ $swPct }}% {{ $swEmoji }} {{ $swLabel }}
@elseif(auth()->check() && !auth()->user()->birthday && auth()->id() !== $user->id)
🔮 Add your birthday to see your cosmic match with {{ explode(' ', $user->name)[0] }}
@endif
@endif
{{-- .ch-wall-sidebar --}}
{{-- ─────────────────────── VIDEOS TAB ──────────────── --}}
@if($videos->count() > 0)
@foreach($videos as $video) @include('components.video-card', ['video' => $video]) @endforeach
No videos match your search
@else

No videos yet

This channel hasn't uploaded any videos.

@auth @if(Auth::id() === $user->id) @endif @endauth
@endif
{{-- ─────────────────────── SHORTS TAB ──────────────── --}} @if($shorts->count() > 0)
@foreach($shorts as $short)
{{ $short->title }} @if($short->duration) {{ gmdate('i:s', $short->duration) }} @endif @if($isOwner && $short->visibility === 'private') Private @elseif($isOwner && $short->visibility === 'unlisted') Unlisted @endif
{{ $short->title }}
{{ number_format($short->view_count) }} views
@endforeach
@endif {{-- ─────────────────────── PLAYLISTS TAB ───────────── --}} @if(($playlists && $playlists->count() > 0) || $isOwner)
@if($isOwner)
@endif @if($playlists && $playlists->count() > 0)
@foreach($playlists as $playlist) @php $plFirstVid = $playlist->videos->first(); $plCardUrl = $plFirstVid ? route('videos.show', $plFirstVid) . '?playlist=' . $playlist->share_token : route('playlists.show', $playlist->id); @endphp
@if($playlist->thumbnail_url) {{ $playlist->name }} @else
@endif
{{ $playlist->video_count }} videos
{{ $playlist->name }}
@if($playlist->is_default) Watch Later @elseif($playlist->visibility === 'private') Private @elseif($playlist->visibility === 'unlisted') Unlisted @else Public @endif
@endforeach
@else

No playlists yet. Create your first one!

@endif
@endif {{-- ─── Create Playlist Modal (channel page) ─────────── --}} @if($isOwner) @endif {{-- ─────────────────────── ABOUT TAB ───────────────── --}}
{{-- Left column --}}
@if($user->bio)
About

{{ $user->bio }}

@endif @if(!$horoscope && $isOwner)
🔮
Unlock Your Horoscope

Add your birthday to see your zodiac sign, age, traits, and compatibility with visitors.

@elseif($horoscope) @php $hColor = \App\Helpers\Horoscope::elementColor($horoscope['element']); @endphp
Horoscope
{{ $horoscope['emoji'] }}
{{ $horoscope['name'] }} {{ $horoscope['symbol'] }}
{{ $horoscope['element'] }} sign
@foreach($horoscope['traits'] as $trait) {{ $trait }} @endforeach
@endif @if($socialLinks->isNotEmpty()) @php $chLinkMap = [ 'twitter' => ['icon' => 'bi-twitter-x', 'color' => '#1d9bf0', 'bg' => 'rgba(29,155,240,.15)', 'href' => fn($v) => "https://twitter.com/{$v}", 'label' => fn($v) => "@{$v}"], 'instagram' => ['icon' => 'bi-instagram', 'color' => '#e1306c', 'bg' => 'rgba(225,48,108,.15)', 'href' => fn($v) => "https://instagram.com/{$v}", 'label' => fn($v) => "@{$v}"], 'facebook' => ['icon' => 'bi-facebook', 'color' => '#1877f2', 'bg' => 'rgba(24,119,242,.15)', 'href' => fn($v) => "https://facebook.com/{$v}", 'label' => fn($v) => $v], 'youtube' => ['icon' => 'bi-youtube', 'color' => '#ff0000', 'bg' => 'rgba(255,0,0,.15)', 'href' => fn($v) => "https://youtube.com/@{$v}", 'label' => fn($v) => "@{$v}"], 'linkedin' => ['icon' => 'bi-linkedin', 'color' => '#0a66c2', 'bg' => 'rgba(10,102,194,.15)', 'href' => fn($v) => "https://linkedin.com/in/{$v}", 'label' => fn($v) => $v], 'tiktok' => ['icon' => 'bi-tiktok', 'color' => '#ff0050', 'bg' => 'rgba(255,0,80,.15)', 'href' => fn($v) => "https://tiktok.com/@{$v}", 'label' => fn($v) => "@{$v}"], 'whatsapp' => ['icon' => 'bi-whatsapp', 'color' => '#25d366', 'bg' => 'rgba(37,211,102,.15)', 'href' => fn($v) => "https://wa.me/" . preg_replace('/\D/','',$v), 'label' => fn($v) => $v], 'website' => ['icon' => 'bi-globe2', 'color' => '#a78bfa', 'bg' => 'rgba(167,139,250,.15)', 'href' => fn($v) => preg_match('/^https?:\/\//', $v) ? $v : "https://{$v}", 'label' => fn($v) => parse_url((str_starts_with($v,'http') ? $v : "https://{$v}"), PHP_URL_HOST) ?: $v], 'google_location' => ['icon' => 'bi-geo-alt-fill', 'color' => '#ea4335', 'bg' => 'rgba(234,67,53,.15)', 'href' => fn($v) => $v, 'label' => fn($v) => 'View on Maps'], 'social_phone' => ['icon' => 'bi-telephone-fill', 'color' => '#34d399', 'bg' => 'rgba(52,211,153,.15)', 'href' => fn($v) => "tel:{$v}", 'label' => fn($v) => $v], 'social_email' => ['icon' => 'bi-envelope-fill', 'color' => '#fb923c', 'bg' => 'rgba(251,146,60,.15)', 'href' => fn($v) => "mailto:{$v}", 'label' => fn($v) => $v], ]; @endphp
Links
@foreach($socialLinks as $link) @if(isset($chLinkMap[$link->platform])) @php $m = $chLinkMap[$link->platform]; @endphp {{ $m['label']($link->value) }} @endif @endforeach
@endif
{{-- Right column: Stats + Compatibility --}}
Stats
{{ \Illuminate\Support\Number::abbreviate($totalViews, precision: 1) }}
Total Views
{{ $videos->count() + $shorts->count() }}
Videos
Joined {{ $user->created_at->format('F j, Y') }}
@if($user->location)
{{ $user->location }}
@endif @if($playlists && $playlists->count() > 0)
{{ $playlists->count() }} playlists
@endif @if($shorts->count() > 0)
{{ $shorts->count() }} shorts
@endif
@if($compatibility !== null && $viewerSign) @php $pct = $compatibility; $compatColor = $pct >= 75 ? '#22c55e' : ($pct >= 55 ? '#eab308' : '#ef4444'); $compatLabel = $pct >= 85 ? 'Soulmates' : ($pct >= 70 ? 'Great match' : ($pct >= 55 ? 'Good vibes' : ($pct >= 40 ? 'Some friction' : 'Tough combo'))); @endphp
Compatibility
{{ $viewerSign['emoji'] }}
You
❤️
{{ $horoscope['emoji'] }}
{{ explode(' ', $user->name)[0] }}
{{ $pct }}%
{{ $compatLabel }}
@endif
{{-- ─────────────────────── SETTINGS TAB ────────────── --}} @if($isOwner) @php $oldLinks = old('slink'); if ($oldLinks) { $socialExisting = collect($oldLinks) ->filter(fn($e) => !empty($e['platform']) && !empty($e['value'])) ->map(fn($e) => ['platform' => $e['platform'], 'value' => $e['value'], 'visibility' => $e['visibility'] ?? 'public']) ->values()->all(); } else { $socialExisting = $user->socialLinks()->orderBy('sort_order')->get() ->map(fn($l) => ['platform' => $l->platform, 'value' => $l->value, 'visibility' => $l->visibility]) ->all(); } @endphp
{{-- Profile Edit Form --}}
Profile Info
@csrf @method('PUT') {{-- Avatar --}}
Profile Photo
JPG, PNG or WebP · Max 5 MB
Recommended: 200×200 px minimum
{{-- Social Links --}}
Social Links
@csrf @method('PUT') {{-- Must send name so the controller doesn't clear it --}}
{{-- Right: Security --}}
@if($isOwner)
Change Password
@csrf @method('PUT')
Minimum 8 characters
@endif @if($isOwner) {{-- 2FA Card --}}
Two-Factor Authentication
@if($user->two_factor_enabled) {{-- Enabled state --}}
Enabled Your account is protected.

To disable 2FA, confirm your password below.

@csrf
@else {{-- Disabled state --}}

Add an extra layer of security. Once enabled, you'll need your authenticator app each time you sign in.

{{-- Step 1: Show QR --}}
@endif
@endif @if($isOwner) @php $notifPrefs = $user->notification_preferences ?? []; $notifDefs = \App\Models\User::notifDefaults(); function notifVal(array $prefs, array $defs, string $key): bool { return isset($prefs[$key]) ? (bool)$prefs[$key] : ($defs[$key] ?? true); } @endphp
Notification Preferences
{{-- Bell (In-App) --}} @php $bellPrefs = [ ['notif_new_comment', 'New comment on my video'], ['notif_new_reply', 'Reply to my comment'], ['notif_comment_like', 'Someone liked my comment'], ['notif_video_like', 'Someone liked my video'], ['notif_new_subscriber', 'New subscriber'], ['notif_new_video_from_sub', 'New video from channels I follow'], ['notif_new_post_from_sub', 'New post from channels I follow'], ]; if ($user->isSuperAdmin()) { $bellPrefs[] = ['notif_new_user_reg', 'New user registration']; } @endphp @foreach($bellPrefs as [$key, $label])
{{ $label }}
@endforeach {{-- Email --}} @php $emailPrefs = [ ['email_new_comment', 'New comment on my video'], ['email_new_reply', 'Reply to my comment'], ['email_comment_like', 'Someone liked my comment'], ['email_video_like', 'Someone liked my video'], ['email_new_subscriber', 'New subscriber'], ['email_new_video_from_sub', 'New video from channels I follow'], ['email_new_post_from_sub', 'New post from channels I follow'], ['email_video_processed', 'My video finished processing'], ['email_weekly_digest', 'Weekly activity digest (every Monday)'], ]; if ($user->isSuperAdmin()) { $emailPrefs[] = ['email_new_user_reg', 'New user registration']; } @endphp @foreach($emailPrefs as [$key, $label])
{{ $label }}
@endforeach

Security emails (verification, password reset) are always sent and cannot be disabled.

@endif
Account
Email cannot be changed
@if($isOwner)
Active Sessions

Sign out of all other browsers and devices where your account is currently logged in. Your current session will remain active.

@csrf
@error('logout_password')
{{ $message }}
@enderror
@endif
@endif {{-- Video picker modal (wall composer) --}} @if(Auth::check() && Auth::id() === $user->id && $user->videos->count() > 0) @php $pickerVideos = $user->videos()->latest()->get(); @endphp @endif @endsection @section('scripts') @if($isOwner && !$preview)