{{ $video->title ?? $profile->screen_name . ' Video' }}
@if(!empty($video->description)){{ Str::limit($video->description, 180) }}
@endif@extends('layouts.app')
@php
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
$approvedImages = $profile->images
->where('is_approved', true)
->sortByDesc('is_primary')
->values();
$mainImage = $approvedImages->first();
$profileLocation = $profile->city;
if ($profile->location) {
$profileLocation .= ' ' . $profile->location;
}
$profileTitle = $profile->screen_name . ' - Trans Escort in ' . $profileLocation . ' | London Trans Girls';
$profileDescription = $profile->ad_heading
?: 'View ' . $profile->screen_name . '\'s profile, approved photos, services, tours and contact details in ' . $profileLocation . '.';
$activeTours = $profile->tours
->where('is_active', true)
->filter(fn ($tour) => $tour->end_date->gte(now()->startOfDay()))
->sortBy('start_date');
$approvedVideos = $profile->videos
->filter(function ($video) {
if (isset($video->status)) {
return $video->status === 'approved';
}
return (bool) ($video->approved ?? false) && ! (bool) ($video->rejected ?? false);
})
->sortBy('sort_order')
->values();
$approvedComments = $profile->comments
->filter(function ($comment) {
return ($comment->status ?? null) === 'approved'
|| (bool) ($comment->approved ?? false);
})
->sortByDesc(function ($comment) {
return $comment->approved_at ?? $comment->created_at;
})
->values();
$currentUser = auth()->user();
$canLeaveComment = $currentUser
&& (
(
method_exists($currentUser, 'isClient')
&& $currentUser->isClient()
)
|| (
method_exists($currentUser, 'isAdmin')
&& $currentUser->isAdmin()
)
|| ($currentUser->role ?? null) === 'client'
|| ($currentUser->role ?? null) === 'admin'
|| (bool) ($currentUser->is_admin ?? false)
);
$links = $profile->social_links ?? [];
$imageUrl = function ($image) {
if (! $image || empty($image->image_path)) {
return null;
}
return '/' . ltrim($image->image_path, '/');
};
$galleryImages = $approvedImages
->map(function ($image) use ($profile, $profileLocation, $imageUrl) {
return [
'src' => $imageUrl($image),
'alt' => $profile->screen_name . ' trans escort in ' . $profileLocation,
];
})
->filter(fn ($image) => ! empty($image['src']))
->values();
$profileUrl = function ($value, $type) {
if (! $value) {
return null;
}
$value = trim($value);
if (str_starts_with($value, 'http://') || str_starts_with($value, 'https://')) {
return $value;
}
if ($type === 'whatsapp') {
$number = preg_replace('/[^0-9]/', '', $value);
return $number ? 'https://wa.me/' . $number : null;
}
if ($type === 'telegram') {
return 'https://t.me/' . ltrim($value, '@');
}
if ($type === 'instagram') {
return 'https://instagram.com/' . ltrim($value, '@');
}
if ($type === 'snapchat') {
return 'https://snapchat.com/add/' . ltrim($value, '@');
}
if ($type === 'x') {
return 'https://x.com/' . ltrim($value, '@');
}
if ($type === 'onlyfans') {
return 'https://onlyfans.com/' . ltrim($value, '@');
}
if ($type === 'website') {
return 'https://' . ltrim($value, '/');
}
return null;
};
$videoMediaUrl = function ($path) {
if (! $path) {
return null;
}
$path = trim($path);
if (Str::startsWith($path, ['http://', 'https://'])) {
return $path;
}
if (Str::startsWith($path, ['/storage/'])) {
return url($path);
}
if (Str::startsWith($path, ['storage/'])) {
return asset($path);
}
return Storage::disk('public')->url($path);
};
$structuredData = [
'@context' => 'https://schema.org',
'@type' => 'ProfilePage',
'name' => $profileTitle,
'description' => $profileDescription,
'url' => route('profiles.show', $profile->slug),
'mainEntity' => [
'@type' => 'Person',
'name' => $profile->screen_name,
'description' => $profileDescription,
'url' => route('profiles.show', $profile->slug),
'address' => [
'@type' => 'PostalAddress',
'addressLocality' => $profile->city,
'addressCountry' => 'GB',
],
],
];
if ($mainImage) {
$structuredData['mainEntity']['image'] = url('/' . ltrim($mainImage->image_path, '/'));
}
@endphp
@section('title', $profileTitle)
@section('meta_description', $profileDescription)
@section('robots', $profile->status === 'approved' ? 'index, follow' : 'noindex, follow')
@section('canonical', route('profiles.show', $profile->slug))
@push('head')
@endpush
@section('content')
📍 {{ $tour->city->name }}
@if($tour->area)
• {{ $tour->area->name }}
@endif
📅 {{ $tour->start_date->format('j M') }} - {{ $tour->end_date->format('j M Y') }}
{{ $tour->notes }}
Watch approved videos from {{ $profile->screen_name }}.
{{ Str::limit($video->description, 180) }}
{{ $profile->about_me ?: 'This model has not added an about section yet.' }} Gender: {{ ucfirst($profile->gender ?? 'Trans') }} City: {{ $profile->city }} Location: {{ $profile->location }} ✔ {{ $service->name }} No services added yet.✈ Tours & Travel
{{ $tour->heading ?: $tour->city->name . ' Tour' }}
{{ $profile->screen_name }} Videos
@else
{{ $video->title ?? $profile->screen_name . ' Video' }}
@if(!empty($video->description))
About {{ $profile->screen_name }}
Details
Services
@forelse($profile->services as $service)
Comments
Approved client comments for {{ $profile->screen_name }} appear here. New comments are checked before being published.
@if(session('status')){{ $comment->comment }}
No approved comments yet. Be the first client to leave a respectful comment.
@endifLeave a comment
@guestYour comment will be reviewed before it appears publicly.
@else