Commit 05f99d21 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Website Builder V2 Phase B: hero variants, multi-column layouts, navbar/footer builder

- 6 hero variants: fullscreen, split_right, split_left, centered_minimal, video_bg, slideshow
- 5 navbar styles: solid, transparent, floating, centered, minimal (with CTA, logo position, social toggle)
- 4 footer styles: dark, light, accent, transparent (with configurable blocks & columns)
- Multi-column layout selector (grid_2/3/4, list, carousel) for activities, programs, trainers, news, branches
- Visual variant picker in section editor with radio cards and mini previews
- Footer block builder with add/remove/reorder (about, links, contact, social, hours)
- Phase B migration adds navbar_cta_text, footer_blocks, footer_style, etc.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent e53700c2
......@@ -34,6 +34,10 @@ class WebsiteSetting extends Model
'animations_enabled',
'animation_speed',
'navbar_style',
'navbar_cta_text',
'navbar_cta_link',
'navbar_show_social',
'navbar_logo_position',
'site_title',
'site_title_en',
'site_description',
......@@ -43,14 +47,21 @@ class WebsiteSetting extends Model
'custom_css',
'google_analytics_id',
'facebook_pixel_id',
'footer_columns',
'footer_blocks',
'footer_bottom_text',
'footer_style',
'is_published',
'published_at',
];
protected $casts = [
'social_links' => 'array',
'footer_blocks' => 'array',
'is_published' => 'boolean',
'animations_enabled' => 'boolean',
'navbar_show_social' => 'boolean',
'footer_columns' => 'integer',
'published_at' => 'datetime',
];
}
......@@ -27,6 +27,10 @@ class SectionManager extends Component
public string $sectionContentEn = '';
public array $sectionSettings = [];
// Hero variant & layout
public string $heroVariant = 'fullscreen';
public string $sectionLayout = 'grid_3';
// Section visual controls
public string $sectionBgType = 'inherit';
public string $sectionBgColor = '#ffffff';
......@@ -109,6 +113,8 @@ public function editSection(string $key): void
$this->sectionContent = $section->content ?? '';
$this->sectionContentEn = $section->content_en ?? '';
$this->sectionSettings = $section->settings ?? [];
$this->heroVariant = $section->getSetting('variant', 'fullscreen');
$this->sectionLayout = $section->getSetting('layout', 'grid_3');
$this->sectionBgType = $section->bg_type ?? 'inherit';
$this->sectionBgColor = $section->bg_color ?? '#ffffff';
$this->sectionBgGradientFrom = $section->bg_gradient_from ?? '#1a1a2e';
......@@ -130,6 +136,17 @@ public function saveSection(): void
->first();
if ($section) {
$settings = $this->sectionSettings;
if ($this->editingSection === 'hero') {
$settings['variant'] = $this->heroVariant;
}
$layoutSections = ['activities', 'programs', 'trainers', 'news', 'branches', 'testimonials'];
if (in_array($this->editingSection, $layoutSections)) {
$settings['layout'] = $this->sectionLayout;
}
app(WebsiteSectionService::class)->updateContent($section, [
'title' => $this->sectionTitle,
'title_en' => $this->sectionTitleEn,
......@@ -137,7 +154,7 @@ public function saveSection(): void
'subtitle_en' => $this->sectionSubtitleEn,
'content' => $this->sectionContent,
'content_en' => $this->sectionContentEn,
'settings' => $this->sectionSettings,
'settings' => $settings,
]);
$section->update([
......
......@@ -46,6 +46,16 @@ class ThemeEditor extends Component
// Navbar
public string $navbar_style = 'transparent';
public string $navbar_cta_text = '';
public string $navbar_cta_link = '';
public bool $navbar_show_social = false;
public string $navbar_logo_position = 'start';
// Footer
public string $footer_style = 'dark';
public int $footer_columns = 4;
public array $footer_blocks = [];
public string $footer_bottom_text = '';
// General
public string $site_title = '';
......@@ -104,6 +114,14 @@ public function mount(): void
$this->animations_enabled = $settings->animations_enabled ?? true;
$this->animation_speed = $settings->animation_speed ?? 'normal';
$this->navbar_style = $settings->navbar_style;
$this->navbar_cta_text = $settings->navbar_cta_text ?? '';
$this->navbar_cta_link = $settings->navbar_cta_link ?? '';
$this->navbar_show_social = $settings->navbar_show_social ?? false;
$this->navbar_logo_position = $settings->navbar_logo_position ?? 'start';
$this->footer_style = $settings->footer_style ?? 'dark';
$this->footer_columns = $settings->footer_columns ?? 4;
$this->footer_blocks = $settings->footer_blocks ?? [];
$this->footer_bottom_text = $settings->footer_bottom_text ?? '';
$this->site_title = $settings->site_title ?? '';
$this->site_title_en = $settings->site_title_en ?? '';
$this->site_description = $settings->site_description ?? '';
......@@ -187,7 +205,15 @@ public function save(): void
'image_shape' => 'required|in:square,rounded,circle,blob',
'animations_enabled' => 'boolean',
'animation_speed' => 'required|in:slow,normal,fast',
'navbar_style' => 'required|in:solid,transparent,floating',
'navbar_style' => 'required|in:solid,transparent,floating,centered,minimal',
'navbar_cta_text' => 'nullable|string|max:50',
'navbar_cta_link' => 'nullable|string|max:255',
'navbar_show_social' => 'boolean',
'navbar_logo_position' => 'required|in:start,center,end',
'footer_style' => 'required|in:dark,light,accent,transparent',
'footer_columns' => 'required|integer|min:2|max:4',
'footer_blocks' => 'nullable|array',
'footer_bottom_text' => 'nullable|string|max:500',
'site_title' => 'nullable|string|max:255',
'site_description' => 'nullable|string|max:1000',
'whatsapp_number' => 'nullable|string|max:20',
......@@ -217,6 +243,14 @@ public function save(): void
'animations_enabled' => $this->animations_enabled,
'animation_speed' => $this->animation_speed,
'navbar_style' => $this->navbar_style,
'navbar_cta_text' => $this->navbar_cta_text,
'navbar_cta_link' => $this->navbar_cta_link,
'navbar_show_social' => $this->navbar_show_social,
'navbar_logo_position' => $this->navbar_logo_position,
'footer_style' => $this->footer_style,
'footer_columns' => $this->footer_columns,
'footer_blocks' => $this->footer_blocks,
'footer_bottom_text' => $this->footer_bottom_text,
'site_title' => $this->site_title,
'site_title_en' => $this->site_title_en,
'site_description' => $this->site_description,
......
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('website_settings', function (Blueprint $table) {
// Navbar enhancements
$table->string('navbar_cta_text', 100)->nullable()->after('navbar_style');
$table->string('navbar_cta_link', 500)->nullable()->after('navbar_cta_text');
$table->boolean('navbar_show_social')->default(false)->after('navbar_cta_link');
$table->string('navbar_logo_position', 10)->default('start')->after('navbar_show_social');
// Footer builder
$table->smallInteger('footer_columns')->default(4)->after('custom_css');
$table->jsonb('footer_blocks')->default('[]')->after('footer_columns');
$table->string('footer_bottom_text', 500)->nullable()->after('footer_blocks');
$table->string('footer_style', 20)->default('dark')->after('footer_bottom_text');
});
// Update navbar_style CHECK to support 8 variants
DB::statement("ALTER TABLE website_settings DROP CONSTRAINT IF EXISTS website_settings_navbar_style_check");
DB::statement("ALTER TABLE website_settings ADD CONSTRAINT website_settings_navbar_style_check CHECK (navbar_style IN ('solid', 'transparent', 'floating', 'centered', 'hamburger_always', 'side_drawer', 'minimal', 'mega'))");
DB::statement("ALTER TABLE website_settings ADD CONSTRAINT website_settings_navbar_logo_position_check CHECK (navbar_logo_position IN ('start', 'center', 'end'))");
DB::statement("ALTER TABLE website_settings ADD CONSTRAINT website_settings_footer_style_check CHECK (footer_style IN ('dark', 'light', 'accent', 'transparent'))");
}
public function down(): void
{
DB::statement("ALTER TABLE website_settings DROP CONSTRAINT IF EXISTS website_settings_navbar_logo_position_check");
DB::statement("ALTER TABLE website_settings DROP CONSTRAINT IF EXISTS website_settings_footer_style_check");
Schema::table('website_settings', function (Blueprint $table) {
$table->dropColumn([
'navbar_cta_text', 'navbar_cta_link', 'navbar_show_social', 'navbar_logo_position',
'footer_columns', 'footer_blocks', 'footer_bottom_text', 'footer_style',
]);
});
DB::statement("ALTER TABLE website_settings DROP CONSTRAINT IF EXISTS website_settings_navbar_style_check");
DB::statement("ALTER TABLE website_settings ADD CONSTRAINT website_settings_navbar_style_check CHECK (navbar_style IN ('solid', 'transparent', 'floating'))");
}
};
......@@ -152,6 +152,39 @@ class="relative shrink-0 w-9 h-5 rounded-full transition-colors {{ $section['is_
{{-- Section-Specific Settings --}}
@if($editingSection === 'hero')
{{-- Hero Variant Picker --}}
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">نمط القسم الرئيسي</label>
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3">
@foreach([
'fullscreen' => ['label' => 'ملء الشاشة', 'desc' => 'صورة كاملة مع نص فوقها', 'icon' => 'M4 5h16v14H4z'],
'split_right' => ['label' => 'منقسم (صورة يمين)', 'desc' => 'نص يسار وصورة يمين', 'icon' => 'M4 5h8v14H4zM12 5h8v14h-8z'],
'split_left' => ['label' => 'منقسم (صورة يسار)', 'desc' => 'صورة يسار ونص يمين', 'icon' => 'M4 5h8v14H4zM12 5h8v14h-8z'],
'centered_minimal' => ['label' => 'مركزي بسيط', 'desc' => 'نص كبير مركزي بدون صورة', 'icon' => 'M7 9h10M9 12h6M8 15h8'],
'video_bg' => ['label' => 'خلفية فيديو', 'desc' => 'فيديو خلفي مع محتوى', 'icon' => 'M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664zM21 12a9 9 0 11-18 0 9 9 0 0118 0z'],
'slideshow' => ['label' => 'عرض شرائح', 'desc' => 'صور متعاقبة تلقائياً', 'icon' => 'M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z'],
] as $variant => $info)
<label class="relative cursor-pointer group">
<input type="radio" wire:model="heroVariant" value="{{ $variant }}" class="peer sr-only">
<div class="p-3 rounded-xl border-2 transition-all
peer-checked:border-blue-500 peer-checked:bg-blue-50 dark:peer-checked:bg-blue-900/20
border-gray-200 dark:border-gray-600 hover:border-gray-300 dark:hover:border-gray-500">
<div class="w-full aspect-[16/9] mb-2 rounded-lg bg-gray-100 dark:bg-gray-700 flex items-center justify-center overflow-hidden">
<svg class="w-10 h-10 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="{{ $info['icon'] }}"/>
</svg>
</div>
<p class="text-xs font-semibold text-gray-800 dark:text-gray-200 text-center">{{ $info['label'] }}</p>
<p class="text-[10px] text-gray-500 dark:text-gray-400 text-center mt-0.5 leading-tight">{{ $info['desc'] }}</p>
</div>
<div class="absolute top-2 end-2 w-5 h-5 rounded-full bg-blue-500 text-white items-center justify-center hidden peer-checked:flex">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
</div>
</label>
@endforeach
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">نص الزر</label>
......@@ -163,13 +196,54 @@ class="relative shrink-0 w-9 h-5 rounded-full transition-colors {{ $section['is_
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">شفافية الطبقة المظلمة (%)</label>
<input type="range" wire:model="sectionSettings.overlay_opacity" min="20" max="90" class="w-full">
<span class="text-xs text-gray-500">{{ $sectionSettings['overlay_opacity'] ?? 70 }}%</span>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">شفافية الطبقة المظلمة ({{ $sectionSettings['overlay_opacity'] ?? 70 }}%)</label>
<input type="range" wire:model.live="sectionSettings.overlay_opacity" min="20" max="90" class="w-full">
</div>
@endif
@if($editingSection === 'activities' || $editingSection === 'programs')
{{-- Layout Picker for multi-column sections --}}
@if(in_array($editingSection, ['activities', 'programs', 'trainers', 'news', 'branches', 'testimonials']))
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">تخطيط العرض</label>
<div class="grid grid-cols-5 gap-2">
@foreach([
'grid_2' => ['label' => 'عمودين', 'cols' => 2],
'grid_3' => ['label' => '3 أعمدة', 'cols' => 3],
'grid_4' => ['label' => '4 أعمدة', 'cols' => 4],
'list' => ['label' => 'قائمة', 'cols' => 0],
'carousel' => ['label' => 'تمرير', 'cols' => -1],
] as $layoutKey => $layoutInfo)
<label class="cursor-pointer group">
<input type="radio" wire:model="sectionLayout" value="{{ $layoutKey }}" class="peer sr-only">
<div class="p-2 rounded-lg border-2 transition-all text-center
peer-checked:border-blue-500 peer-checked:bg-blue-50 dark:peer-checked:bg-blue-900/20
border-gray-200 dark:border-gray-600 hover:border-gray-300">
<div class="flex items-center justify-center gap-0.5 h-8 mb-1">
@if($layoutInfo['cols'] > 0)
@for($i = 0; $i < $layoutInfo['cols']; $i++)
<div class="w-3 h-6 bg-gray-300 dark:bg-gray-500 rounded-sm peer-checked:bg-blue-300"></div>
@endfor
@elseif($layoutInfo['cols'] === 0)
<div class="w-full space-y-1">
<div class="h-2 bg-gray-300 dark:bg-gray-500 rounded-sm"></div>
<div class="h-2 bg-gray-300 dark:bg-gray-500 rounded-sm"></div>
<div class="h-2 bg-gray-300 dark:bg-gray-500 rounded-sm"></div>
</div>
@else
<div class="flex items-center gap-0.5">
<div class="w-3 h-6 bg-gray-300 dark:bg-gray-500 rounded-sm"></div>
<div class="w-3 h-6 bg-gray-300 dark:bg-gray-500 rounded-sm"></div>
<svg class="w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
</div>
@endif
</div>
<span class="text-[10px] font-medium text-gray-600 dark:text-gray-400">{{ $layoutInfo['label'] }}</span>
</div>
</label>
@endforeach
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">عدد العناصر المعروضة</label>
<input type="number" wire:model="sectionSettings.max_items" min="3" max="12" class="w-full rounded-lg border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white" placeholder="6">
......
<footer class="site-footer">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10">
{{-- Academy Info --}}
<div class="lg:col-span-2">
<div class="flex items-center gap-3 mb-4">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}"
alt="{{ $academy->name_ar }}"
class="h-12 w-12 rounded-lg object-contain">
@endif
<span class="text-xl font-bold text-white">{{ $academy->name_ar }}</span>
</div>
@if($settings->site_description)
<p class="text-white/60 leading-relaxed max-w-md">
{{ Str::limit($settings->site_description, 200) }}
</p>
@endif
@if(is_array($settings->social_links ?? null) && count(array_filter($settings->social_links)))
<div class="flex items-center gap-3 mt-6">
@foreach(['facebook', 'instagram', 'twitter', 'youtube', 'tiktok'] as $platform)
@if(!empty($settings->social_links[$platform]))
<a href="{{ $settings->social_links[$platform] }}"
target="_blank"
rel="noopener"
class="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-white/60 hover:text-[var(--site-accent)] hover:border-[var(--site-accent)] transition-all"
aria-label="{{ $platform }}">
@include("website.icons.{$platform}")
</a>
@endif
@endforeach
</div>
@endif
</div>
{{-- Quick Links --}}
<div>
<h4 class="text-white font-bold mb-4">روابط سريعة</h4>
<ul class="space-y-2">
@foreach($sections->take(6) as $section)
<li>
<a href="#section-{{ $section->section_key->value }}"
class="text-white/60 hover:text-[var(--site-accent)] transition-colors text-sm">
{{ $section->title ?? $section->section_key->label() }}
</a>
</li>
@endforeach
</ul>
</div>
{{-- Contact Info --}}
<div>
<h4 class="text-white font-bold mb-4">تواصل معنا</h4>
<ul class="space-y-3 text-sm">
@if($academy->phone)
<li class="flex items-center gap-2 text-white/60">
<svg class="w-4 h-4 text-[var(--site-accent)]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/></svg>
<span dir="ltr">{{ $academy->phone }}</span>
</li>
@endif
@if($academy->email)
<li class="flex items-center gap-2 text-white/60">
<svg class="w-4 h-4 text-[var(--site-accent)]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
<span>{{ $academy->email }}</span>
</li>
@endif
@if($settings->whatsapp_number)
<li class="flex items-center gap-2 text-white/60">
<svg class="w-4 h-4 text-green-400" fill="currentColor" viewBox="0 0 24 24"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347z"/></svg>
<span dir="ltr">{{ $settings->whatsapp_number }}</span>
</li>
@endif
</ul>
</div>
</div>
{{-- Bottom Bar --}}
<div class="mt-12 pt-8 border-t border-white/10 flex flex-col sm:flex-row items-center justify-between gap-4">
<p class="text-white/40 text-sm">
&copy; {{ date('Y') }} {{ $academy->name_ar }}. جميع الحقوق محفوظة.
</p>
<p class="text-white/30 text-xs">
مدعوم بنظام El Captain
</p>
</div>
</div>
</footer>
@php
$footerStyle = $settings->footer_style ?? 'dark';
$validStyles = ['dark', 'light', 'accent', 'transparent'];
if (!in_array($footerStyle, $validStyles)) {
$footerStyle = 'dark';
}
@endphp
@include("website.footers.{$footerStyle}", [
'sections' => $sections,
'academy' => $academy,
'settings' => $settings,
])
This diff is collapsed.
<footer style="background: var(--site-accent)">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
@include('website.footers._blocks', ['textColor' => 'text-white', 'mutedColor' => 'text-white/70', 'borderColor' => 'border-white/20'])
</div>
</footer>
<footer class="site-footer" style="background: var(--site-primary)">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
@include('website.footers._blocks', ['textColor' => 'text-white', 'mutedColor' => 'text-white/60', 'borderColor' => 'border-white/10'])
</div>
</footer>
<footer class="border-t" style="background: var(--site-surface); border-color: var(--site-border)">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
@include('website.footers._blocks', ['textColor' => 'text-[var(--site-text)]', 'mutedColor' => 'text-[var(--site-muted)]', 'borderColor' => 'border-[var(--site-border)]'])
</div>
</footer>
<footer style="background: transparent">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
@include('website.footers._blocks', ['textColor' => 'text-[var(--site-text)]', 'mutedColor' => 'text-[var(--site-muted)]', 'borderColor' => 'border-[var(--site-border)]'])
</div>
</footer>
<nav class="site-nav {{ $settings->navbar_style === 'solid' ? 'site-nav--solid' : '' }}" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-20">
{{-- Logo + Name --}}
<a href="#section-hero" class="flex items-center gap-3 group">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}"
alt="{{ $academy->name_ar }}"
class="h-10 w-10 rounded-lg object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-lg font-bold text-white">{{ $academy->name_ar }}</span>
</a>
{{-- Desktop Navigation --}}
<div class="hidden lg:flex items-center gap-1">
@foreach($sections->take(7) as $section)
<a href="#section-{{ $section->section_key->value }}"
class="px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/5 transition-all">
{{ $section->title ?? $section->section_key->label() }}
</a>
@endforeach
</div>
{{-- CTA + Login + Mobile Toggle --}}
<div class="flex items-center gap-3">
@php
$heroSection = $sections->firstWhere('section_key', \App\Domain\Website\Enums\SectionKey::Cta);
$ctaText = $heroSection?->getSetting('cta_text') ?? 'سجّل الآن';
@endphp
<a href="#section-contact" class="hidden sm:inline-flex site-btn site-btn--primary text-sm !py-2 !px-4">
{{ $ctaText }}
</a>
@auth
<a href="{{ route('dashboard') }}" class="hidden sm:inline-flex items-center gap-1 px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-all">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
{{ __('لوحة التحكم') }}
</a>
@else
<a href="{{ route('login') }}" class="hidden sm:inline-flex items-center gap-1 px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-all">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"/></svg>
{{ __('تسجيل الدخول') }}
</a>
@endauth
{{-- Mobile Menu Button --}}
<button type="button"
class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors"
onclick="document.getElementById('mobile-menu').classList.toggle('hidden')"
aria-label="القائمة">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
</div>
</div>
</div>
{{-- Mobile Menu --}}
<div id="mobile-menu" class="hidden lg:hidden bg-black/95 backdrop-blur-lg border-t border-white/10">
<div class="px-4 py-4 space-y-1">
@foreach($sections as $section)
<a href="#section-{{ $section->section_key->value }}"
class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors"
onclick="document.getElementById('mobile-menu').classList.add('hidden')">
{{ $section->title ?? $section->section_key->label() }}
</a>
@endforeach
<div class="border-t border-white/10 pt-3 mt-3">
@auth
<a href="{{ route('dashboard') }}" class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors">
{{ __('لوحة التحكم') }}
</a>
@else
<a href="{{ route('login') }}" class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors">
{{ __('تسجيل الدخول') }}
</a>
@endauth
</div>
</div>
</div>
</nav>
@php
$navbarStyle = $settings->navbar_style ?? 'transparent';
$validStyles = ['solid', 'transparent', 'floating', 'centered', 'minimal'];
if (!in_array($navbarStyle, $validStyles)) {
$navbarStyle = 'solid';
}
@endphp
@include("website.navbars.{$navbarStyle}", [
'sections' => $sections,
'academy' => $academy,
'settings' => $settings,
])
{{-- Shared mobile menu, included by all navbar variants --}}
<div id="mobile-menu" class="hidden lg:hidden bg-black/95 backdrop-blur-lg border-t border-white/10">
<div class="px-4 py-4 space-y-1">
@foreach($sections as $section)
<a href="#section-{{ $section->section_key->value }}"
class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors"
onclick="document.getElementById('mobile-menu').classList.add('hidden')">
{{ $section->title ?? $section->section_key->label() }}
</a>
@endforeach
<div class="border-t border-white/10 pt-3 mt-3">
@auth
<a href="{{ route('dashboard') }}" class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors">
{{ __('لوحة التحكم') }}
</a>
@else
<a href="{{ route('login') }}" class="block px-4 py-3 text-white/80 hover:text-white hover:bg-white/5 rounded-lg transition-colors">
{{ __('تسجيل الدخول') }}
</a>
@endauth
</div>
</div>
</div>
<nav class="site-nav site-nav--solid" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-20">
{{-- Links Start --}}
<div class="hidden lg:flex items-center gap-1 flex-1 justify-end">
@foreach($sections->take(3) as $navSection)
<a href="#section-{{ $navSection->section_key->value }}" class="px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/5 transition-all">
{{ $navSection->title ?? $navSection->section_key->label() }}
</a>
@endforeach
</div>
{{-- Centered Logo --}}
<a href="#section-hero" class="flex items-center gap-3 group mx-8">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}" alt="{{ $academy->name_ar }}" class="h-12 w-12 rounded-xl object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-lg font-bold text-white hidden sm:block">{{ $academy->name_ar }}</span>
</a>
{{-- Links End --}}
<div class="hidden lg:flex items-center gap-1 flex-1">
@foreach($sections->skip(3)->take(3) as $navSection)
<a href="#section-{{ $navSection->section_key->value }}" class="px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/5 transition-all">
{{ $navSection->title ?? $navSection->section_key->label() }}
</a>
@endforeach
<a href="{{ $settings->navbar_cta_link ?? '#section-contact' }}" class="ms-2 site-btn site-btn--primary text-sm !py-1.5 !px-4">
{{ $settings->navbar_cta_text ?? 'سجّل الآن' }}
</a>
</div>
<button type="button" class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" aria-label="القائمة">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
@include('website.navbars._mobile_menu')
</nav>
<nav class="site-nav site-nav--floating" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6">
<div class="flex items-center justify-between h-16">
<a href="#section-hero" class="flex items-center gap-3 group">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}" alt="{{ $academy->name_ar }}" class="h-9 w-9 rounded-lg object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-base font-bold text-white">{{ $academy->name_ar }}</span>
</a>
<div class="hidden lg:flex items-center gap-1">
@foreach($sections->take(6) as $navSection)
<a href="#section-{{ $navSection->section_key->value }}" class="px-3 py-1.5 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-all">
{{ $navSection->title ?? $navSection->section_key->label() }}
</a>
@endforeach
</div>
<div class="flex items-center gap-2">
<a href="{{ $settings->navbar_cta_link ?? '#section-contact' }}" class="hidden sm:inline-flex site-btn site-btn--primary text-sm !py-1.5 !px-4 !rounded-full">
{{ $settings->navbar_cta_text ?? 'سجّل الآن' }}
</a>
<button type="button" class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" aria-label="القائمة">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
</div>
@include('website.navbars._mobile_menu')
</nav>
<nav class="site-nav site-nav--transparent" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-20">
<a href="#section-hero" class="flex items-center gap-3 group">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}" alt="{{ $academy->name_ar }}" class="h-10 w-10 rounded-lg object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-lg font-bold text-white">{{ $academy->name_ar }}</span>
</a>
<div class="flex items-center gap-3">
@auth
<a href="{{ route('dashboard') }}" class="hidden sm:inline-flex items-center gap-1 px-3 py-2 text-sm font-medium text-white/70 hover:text-white transition-colors">
{{ __('لوحة التحكم') }}
</a>
@endauth
<a href="{{ $settings->navbar_cta_link ?? '#section-contact' }}" class="site-btn site-btn--primary text-sm !py-2 !px-5">
{{ $settings->navbar_cta_text ?? 'سجّل الآن' }}
</a>
<button type="button" class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" aria-label="القائمة">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
</div>
@include('website.navbars._mobile_menu')
</nav>
<nav class="site-nav site-nav--solid" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-20">
<a href="#section-hero" class="flex items-center gap-3 group">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}" alt="{{ $academy->name_ar }}" class="h-10 w-10 rounded-lg object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-lg font-bold text-white">{{ $academy->name_ar }}</span>
</a>
<div class="hidden lg:flex items-center gap-1">
@foreach($sections->take(7) as $navSection)
<a href="#section-{{ $navSection->section_key->value }}" class="px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/5 transition-all">
{{ $navSection->title ?? $navSection->section_key->label() }}
</a>
@endforeach
</div>
<div class="flex items-center gap-3">
<a href="{{ $settings->navbar_cta_link ?? '#section-contact' }}" class="hidden sm:inline-flex site-btn site-btn--primary text-sm !py-2 !px-4">
{{ $settings->navbar_cta_text ?? 'سجّل الآن' }}
</a>
@auth
<a href="{{ route('dashboard') }}" class="hidden sm:inline-flex items-center gap-1 px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-all">
{{ __('لوحة التحكم') }}
</a>
@endauth
<button type="button" class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" aria-label="القائمة">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
</div>
@include('website.navbars._mobile_menu')
</nav>
<nav class="site-nav site-nav--transparent" id="site-navbar">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-20">
<a href="#section-hero" class="flex items-center gap-3 group">
@if($academy->logo_path)
<img src="{{ asset('storage/' . $academy->logo_path) }}" alt="{{ $academy->name_ar }}" class="h-10 w-10 rounded-lg object-contain transition-transform group-hover:scale-110">
@endif
<span class="text-lg font-bold text-white">{{ $academy->name_ar }}</span>
</a>
<div class="hidden lg:flex items-center gap-1">
@foreach($sections->take(7) as $navSection)
<a href="#section-{{ $navSection->section_key->value }}" class="px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/5 transition-all">
{{ $navSection->title ?? $navSection->section_key->label() }}
</a>
@endforeach
</div>
<div class="flex items-center gap-3">
<a href="{{ $settings->navbar_cta_link ?? '#section-contact' }}" class="hidden sm:inline-flex site-btn site-btn--primary text-sm !py-2 !px-4">
{{ $settings->navbar_cta_text ?? 'سجّل الآن' }}
</a>
@auth
<a href="{{ route('dashboard') }}" class="hidden sm:inline-flex items-center gap-1 px-3 py-2 text-sm font-medium text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-all">
{{ __('لوحة التحكم') }}
</a>
@endauth
<button type="button" class="lg:hidden p-2 rounded-lg text-white/80 hover:text-white hover:bg-white/10 transition-colors" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')" aria-label="القائمة">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
</div>
@include('website.navbars._mobile_menu')
</nav>
@php
$activities = $data['activities'] ?? collect();
$maxItems = $section->getSetting('max_items', 6);
$layout = $section->getSetting('layout', 'grid_3');
$gridClass = match($layout) {
'grid_2' => 'grid grid-cols-1 sm:grid-cols-2 gap-[var(--card-gap,1.5rem)]',
'grid_4' => 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[var(--card-gap,1.5rem)]',
'list' => 'flex flex-col gap-[var(--card-gap,1.5rem)]',
'carousel' => 'flex overflow-x-auto snap-x snap-mandatory gap-[var(--card-gap,1.5rem)] pb-4 -mx-4 px-4 scrollbar-hide',
default => 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-[var(--card-gap,1.5rem)]',
};
$cardExtraClass = $layout === 'carousel' ? 'min-w-[280px] sm:min-w-[320px] snap-start shrink-0' : '';
$listMode = $layout === 'list';
@endphp
<div class="site-section site-section--alt">
......@@ -13,7 +23,7 @@
</div>
@if($activities->count())
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="{{ $gridClass }}">
@foreach($activities->take($maxItems) as $activity)
@php
$activityImage = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
......@@ -23,8 +33,8 @@
->where('mediable_id', $activity->id)
->first();
@endphp
<div class="site-card reveal reveal--delay-{{ ($loop->index % 4) + 1 }}">
<div class="relative overflow-hidden aspect-[4/3]">
<div class="site-card {{ $cardExtraClass }} reveal reveal--delay-{{ ($loop->index % 4) + 1 }} {{ $listMode ? 'flex flex-row' : '' }}">
<div class="relative overflow-hidden {{ $listMode ? 'w-48 shrink-0' : 'aspect-[4/3]' }}">
@if($activityImage)
<img src="{{ $activityImage->url }}"
alt="{{ $activity->name_ar }}"
......
@php
$branches = $data['branches'] ?? collect();
$layout = $section->getSetting('layout', 'grid_3');
$gridClass = match($layout) {
'grid_2' => 'grid grid-cols-1 sm:grid-cols-2 gap-[var(--card-gap,1.5rem)]',
'grid_4' => 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[var(--card-gap,1.5rem)]',
'list' => 'flex flex-col gap-[var(--card-gap,1.5rem)]',
'carousel' => 'flex overflow-x-auto snap-x snap-mandatory gap-[var(--card-gap,1.5rem)] pb-4 -mx-4 px-4 scrollbar-hide',
default => 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[var(--card-gap,1.5rem)]',
};
$cardExtraClass = $layout === 'carousel' ? 'min-w-[300px] snap-start shrink-0' : '';
$listMode = $layout === 'list';
@endphp
<div class="site-section site-section--alt">
......@@ -12,7 +22,7 @@
</div>
@if($branches->count())
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="{{ $gridClass }}">
@foreach($branches as $branch)
@php
$branchImage = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
......@@ -22,9 +32,9 @@
->where('mediable_id', $branch->id)
->first();
@endphp
<div class="site-card reveal reveal--delay-{{ ($loop->index % 3) + 1 }}">
<div class="site-card {{ $cardExtraClass }} {{ $listMode ? 'flex flex-row' : '' }} reveal reveal--delay-{{ ($loop->index % 3) + 1 }}">
@if($branchImage)
<div class="relative overflow-hidden aspect-[3/2]">
<div class="relative overflow-hidden {{ $listMode ? 'w-48 shrink-0' : 'aspect-[3/2]' }}">
<img src="{{ $branchImage->url }}"
alt="{{ $branch->name_ar }}"
class="site-card__image">
......
@php
$coverMedia = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->where('collection', 'academy_cover')
->first();
$overlayOpacity = $section->getSetting('overlay_opacity', 70) / 100;
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
$variant = $section->getSetting('variant', 'fullscreen');
$validVariants = ['fullscreen', 'split_right', 'split_left', 'centered_minimal', 'video_bg', 'slideshow'];
if (!in_array($variant, $validVariants)) {
$variant = 'fullscreen';
}
@endphp
<div class="hero-section hero-clip">
{{-- Background Image --}}
@if($coverMedia)
<img src="{{ $coverMedia->url }}"
alt="{{ $academy->name_ar }}"
class="absolute inset-0 w-full h-full object-cover">
@else
<div class="absolute inset-0 bg-gradient-to-br from-[var(--site-primary)] via-[var(--site-secondary)] to-black"></div>
@endif
{{-- Overlay --}}
<div class="hero-overlay" style="--overlay-opacity: {{ $overlayOpacity }}"></div>
{{-- Diagonal Decorative Lines --}}
<div class="absolute inset-0 z-[2] pointer-events-none opacity-10">
<div class="absolute top-[20%] -start-20 w-[400px] h-[2px] bg-[var(--site-accent)] rotate-[-15deg]"></div>
<div class="absolute top-[40%] -end-10 w-[300px] h-[2px] bg-[var(--site-accent)] rotate-[-15deg]"></div>
<div class="absolute bottom-[30%] -start-10 w-[250px] h-[2px] bg-white rotate-[-15deg]"></div>
</div>
{{-- Content --}}
<div class="hero-content max-w-4xl mx-auto">
<h1 class="hero-title reveal">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="hero-accent-line"></div>
@if($section->subtitle)
<p class="text-xl md:text-2xl text-white/80 mt-4 reveal reveal--delay-1 max-w-2xl mx-auto leading-relaxed">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4 reveal reveal--delay-2">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary text-lg">
{{ $ctaText }}
<svg class="w-5 h-5 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
{{-- Scroll Indicator --}}
<div class="absolute bottom-10 left-1/2 -translate-x-1/2 z-10 animate-bounce">
<svg class="w-6 h-6 text-white/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"/>
</svg>
</div>
</div>
@include("website.sections.hero.{$variant}", [
'section' => $section,
'academy' => $academy,
'settings' => $settings,
'data' => $data,
])
@php
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
@endphp
<div class="hero-section !min-h-[75vh]" style="background: linear-gradient(160deg, var(--site-primary) 0%, var(--site-secondary) 100%)">
<div class="absolute inset-0 opacity-5">
<div class="absolute top-1/4 start-1/4 w-96 h-96 bg-[var(--site-accent)] rounded-full blur-[120px]"></div>
<div class="absolute bottom-1/4 end-1/4 w-64 h-64 bg-[var(--site-accent)] rounded-full blur-[100px]"></div>
</div>
<div class="hero-content max-w-3xl mx-auto relative z-10">
@if($academy->logo_path)
<div class="mb-8 reveal">
<img src="{{ asset('storage/' . $academy->logo_path) }}"
alt="{{ $academy->name_ar }}"
class="h-20 w-20 mx-auto rounded-2xl object-contain shadow-lg">
</div>
@endif
<h1 class="hero-title reveal reveal--delay-1" style="font-size: clamp(2.5rem, 7vw, 5rem); line-height: 1.1">
{{ $section->title ?? $academy->name_ar }}
</h1>
@if($section->subtitle)
<p class="text-xl md:text-2xl text-white/60 mt-8 reveal reveal--delay-2 max-w-xl mx-auto leading-relaxed font-light">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-12 flex flex-col sm:flex-row items-center justify-center gap-4 reveal reveal--delay-3">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary text-lg px-10">
{{ $ctaText }}
</a>
</div>
</div>
</div>
@php
$coverMedia = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->where('collection', 'academy_cover')
->first();
$overlayOpacity = $section->getSetting('overlay_opacity', 70) / 100;
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
@endphp
<div class="hero-section">
@if($coverMedia)
<img src="{{ $coverMedia->url }}"
alt="{{ $academy->name_ar }}"
loading="eager"
class="absolute inset-0 w-full h-full object-cover">
@else
<div class="absolute inset-0 bg-gradient-to-br from-[var(--site-primary)] via-[var(--site-secondary)] to-black"></div>
@endif
<div class="hero-overlay" style="--overlay-opacity: {{ $overlayOpacity }}"></div>
<div class="absolute inset-0 z-[2] pointer-events-none opacity-10">
<div class="absolute top-[20%] -start-20 w-[400px] h-[2px] bg-[var(--site-accent)] rotate-[-15deg]"></div>
<div class="absolute top-[40%] -end-10 w-[300px] h-[2px] bg-[var(--site-accent)] rotate-[-15deg]"></div>
<div class="absolute bottom-[30%] -start-10 w-[250px] h-[2px] bg-white rotate-[-15deg]"></div>
</div>
<div class="hero-content max-w-4xl mx-auto">
<h1 class="hero-title reveal">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="hero-accent-line"></div>
@if($section->subtitle)
<p class="text-xl md:text-2xl text-white/80 mt-4 reveal reveal--delay-1 max-w-2xl mx-auto leading-relaxed">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4 reveal reveal--delay-2">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary text-lg">
{{ $ctaText }}
<svg class="w-5 h-5 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
@if($section->getSetting('show_scroll_indicator', true))
<div class="absolute bottom-10 left-1/2 -translate-x-1/2 z-10 animate-bounce">
<svg class="w-6 h-6 text-white/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"/>
</svg>
</div>
@endif
</div>
@php
$galleryImages = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->whereIn('collection', ['academy_cover', 'academy_gallery'])
->orderBy('sort_order')
->take(5)
->get();
$overlayOpacity = $section->getSetting('overlay_opacity', 65) / 100;
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
@endphp
<div class="hero-section" x-data="{ current: 0, total: {{ $galleryImages->count() ?: 1 }} }" x-init="setInterval(() => current = (current + 1) % total, 5000)">
@if($galleryImages->count())
@foreach($galleryImages as $i => $img)
<img src="{{ $img->url }}"
alt="{{ $academy->name_ar }}"
loading="{{ $i === 0 ? 'eager' : 'lazy' }}"
class="absolute inset-0 w-full h-full object-cover transition-opacity duration-1000"
:class="current === {{ $i }} ? 'opacity-100' : 'opacity-0'">
@endforeach
@else
<div class="absolute inset-0 bg-gradient-to-br from-[var(--site-primary)] via-[var(--site-secondary)] to-black"></div>
@endif
<div class="absolute inset-0 bg-black" style="opacity: {{ $overlayOpacity }}"></div>
<div class="hero-content max-w-4xl mx-auto relative z-10">
<h1 class="hero-title reveal">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="hero-accent-line"></div>
@if($section->subtitle)
<p class="text-xl md:text-2xl text-white/80 mt-4 reveal reveal--delay-1 max-w-2xl mx-auto leading-relaxed">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4 reveal reveal--delay-2">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary text-lg">
{{ $ctaText }}
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
@if($galleryImages->count() > 1)
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 z-10 flex items-center gap-2">
@for($i = 0; $i < $galleryImages->count(); $i++)
<button @click="current = {{ $i }}"
class="w-2 h-2 rounded-full transition-all duration-300"
:class="current === {{ $i }} ? 'bg-[var(--site-accent)] w-6' : 'bg-white/40 hover:bg-white/60'"></button>
@endfor
</div>
@endif
</div>
@php
$coverMedia = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->where('collection', 'academy_cover')
->first();
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
@endphp
<div class="hero-section !min-h-[80vh]" style="background: var(--site-primary)">
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 items-center min-h-[80vh] py-24">
{{-- Image Side --}}
<div class="order-1 reveal">
@if($coverMedia)
<div class="relative">
<img src="{{ $coverMedia->url }}"
alt="{{ $academy->name_ar }}"
loading="eager"
class="w-full h-[400px] lg:h-[500px] object-cover site-img rounded-2xl shadow-2xl">
<div class="absolute -bottom-4 -end-4 w-24 h-24 bg-[var(--site-accent)] rounded-xl opacity-20"></div>
<div class="absolute -top-4 -start-4 w-16 h-16 bg-[var(--site-accent)] rounded-full opacity-10"></div>
</div>
@else
<div class="w-full h-[400px] lg:h-[500px] rounded-2xl bg-gradient-to-br from-[var(--site-secondary)] to-[var(--site-accent)] opacity-30"></div>
@endif
</div>
{{-- Text Side --}}
<div class="order-2">
<h1 class="hero-title !text-start reveal reveal--delay-1" style="font-size: clamp(2rem, 5vw, 3.5rem)">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="w-16 h-1 bg-[var(--site-accent)] rounded-full mt-6 mb-6"></div>
@if($section->subtitle)
<p class="text-lg md:text-xl text-white/70 leading-relaxed reveal reveal--delay-2 max-w-lg">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-8 flex flex-wrap items-center gap-4 reveal reveal--delay-3">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary">
{{ $ctaText }}
<svg class="w-5 h-5 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
</div>
</div>
</div>
@php
$coverMedia = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->where('collection', 'academy_cover')
->first();
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
@endphp
<div class="hero-section !min-h-[80vh]" style="background: var(--site-primary)">
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 items-center min-h-[80vh] py-24">
{{-- Text Side --}}
<div class="order-2 lg:order-1 text-{{ $section->getSetting('text_alignment', 'start') }}">
<h1 class="hero-title !text-start reveal" style="font-size: clamp(2rem, 5vw, 3.5rem)">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="w-16 h-1 bg-[var(--site-accent)] rounded-full mt-6 mb-6"></div>
@if($section->subtitle)
<p class="text-lg md:text-xl text-white/70 leading-relaxed reveal reveal--delay-1 max-w-lg">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-8 flex flex-wrap items-center gap-4 reveal reveal--delay-2">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary">
{{ $ctaText }}
<svg class="w-5 h-5 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
{{-- Image Side --}}
<div class="order-1 lg:order-2 reveal reveal--delay-1">
@if($coverMedia)
<div class="relative">
<img src="{{ $coverMedia->url }}"
alt="{{ $academy->name_ar }}"
loading="eager"
class="w-full h-[400px] lg:h-[500px] object-cover site-img rounded-2xl shadow-2xl">
<div class="absolute -bottom-4 -start-4 w-24 h-24 bg-[var(--site-accent)] rounded-xl opacity-20"></div>
<div class="absolute -top-4 -end-4 w-16 h-16 bg-[var(--site-accent)] rounded-full opacity-10"></div>
</div>
@else
<div class="w-full h-[400px] lg:h-[500px] rounded-2xl bg-gradient-to-br from-[var(--site-secondary)] to-[var(--site-accent)] opacity-30"></div>
@endif
</div>
</div>
</div>
</div>
@php
$coverMedia = \App\Domain\Website\Models\Media::withoutGlobalScope('academy')
->where('academy_id', $academy->id)
->where('collection', 'academy_cover')
->first();
$overlayOpacity = $section->getSetting('overlay_opacity', 70) / 100;
$ctaText = $section->getSetting('cta_text', 'سجّل الآن');
$ctaLink = $section->getSetting('cta_link', '#section-contact');
$videoUrl = $section->getSetting('video_url', '');
@endphp
<div class="hero-section">
@if($videoUrl)
<video autoplay muted loop playsinline class="absolute inset-0 w-full h-full object-cover">
<source src="{{ $videoUrl }}" type="video/mp4">
</video>
@elseif($coverMedia)
<img src="{{ $coverMedia->url }}"
alt="{{ $academy->name_ar }}"
loading="eager"
class="absolute inset-0 w-full h-full object-cover">
@else
<div class="absolute inset-0 bg-gradient-to-br from-[var(--site-primary)] via-[var(--site-secondary)] to-black"></div>
@endif
<div class="absolute inset-0 bg-black" style="opacity: {{ $overlayOpacity }}"></div>
<div class="hero-content max-w-4xl mx-auto relative z-10">
<h1 class="hero-title reveal" style="font-size: clamp(2.5rem, 6vw, 4.5rem)">
{{ $section->title ?? $academy->name_ar }}
</h1>
<div class="hero-accent-line"></div>
@if($section->subtitle)
<p class="text-xl md:text-2xl text-white/80 mt-4 reveal reveal--delay-1 max-w-2xl mx-auto leading-relaxed">
{{ $section->subtitle }}
</p>
@endif
<div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4 reveal reveal--delay-2">
<a href="{{ $ctaLink }}" class="site-btn site-btn--primary text-lg">
{{ $ctaText }}
<svg class="w-5 h-5 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
</a>
<a href="#section-about" class="site-btn site-btn--outline">
تعرف علينا
</a>
</div>
</div>
@if($section->getSetting('show_scroll_indicator', true))
<div class="absolute bottom-10 left-1/2 -translate-x-1/2 z-10 animate-bounce">
<svg class="w-6 h-6 text-white/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"/>
</svg>
</div>
@endif
</div>
@php
$news = $data['news'] ?? collect();
$layout = $section->getSetting('layout', 'grid_3');
$gridClass = match($layout) {
'grid_2' => 'grid grid-cols-1 sm:grid-cols-2 gap-[var(--card-gap,1.5rem)]',
'grid_4' => 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[var(--card-gap,1.5rem)]',
'list' => 'flex flex-col gap-[var(--card-gap,1.5rem)]',
'carousel' => 'flex overflow-x-auto snap-x snap-mandatory gap-[var(--card-gap,1.5rem)] pb-4 -mx-4 px-4 scrollbar-hide',
default => 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[var(--card-gap,1.5rem)]',
};
$cardExtraClass = $layout === 'carousel' ? 'min-w-[300px] snap-start shrink-0' : '';
$listMode = $layout === 'list';
@endphp
<div class="site-section site-section--alt">
......@@ -12,11 +22,11 @@
</div>
@if($news->count())
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="{{ $gridClass }}">
@foreach($news as $article)
<article class="site-card reveal reveal--delay-{{ ($loop->index % 3) + 1 }}">
<article class="site-card {{ $cardExtraClass }} {{ $listMode ? 'flex flex-row' : '' }} reveal reveal--delay-{{ ($loop->index % 3) + 1 }}">
@if($article->image)
<div class="relative overflow-hidden aspect-[16/9]">
<div class="relative overflow-hidden {{ $listMode ? 'w-48 shrink-0' : 'aspect-[16/9]' }}">
<img src="{{ $article->image->url }}"
alt="{{ $article->title }}"
class="site-card__image"
......
......@@ -5,6 +5,16 @@
->where('collection', 'team_photo')
->orderBy('sort_order')
->get();
$layout = $section->getSetting('layout', 'grid_4');
$gridClass = match($layout) {
'grid_2' => 'grid grid-cols-1 sm:grid-cols-2 gap-8',
'grid_3' => 'grid grid-cols-2 md:grid-cols-3 gap-6',
'carousel' => 'flex overflow-x-auto snap-x snap-mandatory gap-6 pb-4 -mx-4 px-4 scrollbar-hide',
'list' => 'flex flex-col gap-6',
default => 'grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6',
};
$cardExtraClass = $layout === 'carousel' ? 'min-w-[200px] snap-start shrink-0' : '';
$listMode = $layout === 'list';
@endphp
<div class="site-section site-section--alt">
......@@ -17,10 +27,10 @@
</div>
@if(count($trainers))
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
<div class="{{ $gridClass }}">
@foreach($trainers as $index => $trainer)
<div class="text-center reveal reveal--delay-{{ ($index % 4) + 1 }}">
<div class="relative mx-auto w-32 h-32 mb-4">
<div class="{{ $cardExtraClass }} {{ $listMode ? 'flex items-center gap-5 p-4 bg-white rounded-xl border border-gray-100 shadow-sm' : 'text-center' }} reveal reveal--delay-{{ ($index % 4) + 1 }}">
<div class="relative {{ $listMode ? '' : 'mx-auto' }} {{ $listMode ? 'w-20 h-20 shrink-0' : 'w-32 h-32 mb-4' }}">
@php $photo = $teamPhotos->get($index); @endphp
@if($photo)
<img src="{{ $photo->url }}"
......@@ -28,19 +38,21 @@
class="w-full h-full rounded-full object-cover border-3 border-[var(--site-accent)] shadow-lg shadow-[var(--site-accent)]/10">
@else
<div class="w-full h-full rounded-full bg-gradient-to-br from-[var(--site-accent)]/10 to-gray-100 border-3 border-gray-200 flex items-center justify-center">
<svg class="w-12 h-12 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="{{ $listMode ? 'w-8 h-8' : 'w-12 h-12' }} text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
@endif
</div>
<h4 class="text-gray-900 font-bold">{{ $trainer['name'] ?? '' }}</h4>
@if(!empty($trainer['role']))
<p class="text-[var(--site-accent)] text-sm mt-1">{{ $trainer['role'] }}</p>
@endif
@if(!empty($trainer['bio']))
<p class="text-gray-500 text-sm mt-1">{{ $trainer['bio'] }}</p>
@endif
<div class="{{ $listMode ? '' : '' }}">
<h4 class="text-gray-900 font-bold">{{ $trainer['name'] ?? '' }}</h4>
@if(!empty($trainer['role']))
<p class="text-[var(--site-accent)] text-sm mt-1">{{ $trainer['role'] }}</p>
@endif
@if(!empty($trainer['bio']))
<p class="text-gray-500 text-sm mt-1 {{ $listMode ? '' : 'line-clamp-2' }}">{{ $trainer['bio'] }}</p>
@endif
</div>
</div>
@endforeach
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment