Files
Virtnet.bond/extensions/Others/Onboarding/Livewire/Onboarding/Modal.php

199 lines
7.4 KiB
PHP

<?php
namespace Paymenter\Extensions\Others\Onboarding\Livewire\Onboarding;
use Livewire\Component;
use Paymenter\Extensions\Others\Onboarding\Models\OnboardingSlide;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Schema;
use App\Helpers\ExtensionHelper;
class Modal extends Component
{
public $currentSlide = 0;
public $slides = [];
public $showModal = false;
public function mount()
{
// Guard: ensure table exists before querying
if (!Schema::hasTable('ext_onboarding_slides')) {
$this->showModal = false;
return;
}
// Check if test mode and per session mode are enabled
$extension = ExtensionHelper::getExtension('other', 'Onboarding');
$testMode = $extension->config('test_mode', false);
$perSession = $extension->config('per_session', false);
$userId = Auth::id();
// Load slides first so we can validate currentSlide
try {
$this->slides = OnboardingSlide::where('enabled', true)
->orderBy('sort', 'asc')
->get()
->toArray();
} catch (\Exception $e) {
// If query fails (e.g., missing columns), don't show modal
$this->slides = [];
$this->showModal = false;
return;
}
// No slides configured, nothing to show
if (count($this->slides) === 0) {
$this->showModal = false;
return;
}
// Check if user has seen onboarding before
if ($perSession) {
// Use cookie for per-session tracking
$hasSeenOnboarding = $testMode ? false : \Illuminate\Support\Facades\Cookie::has('onboarding_completed');
$this->currentSlide = (int) \Illuminate\Support\Facades\Cookie::get('onboarding_current_slide', 0);
} else {
// Use database session for persistent tracking
$hasSeenOnboarding = $testMode ? false : session()->get("onboarding_seen_{$userId}", false);
$this->currentSlide = (int) session()->get("onboarding_current_slide_{$userId}", 0);
}
// Reset currentSlide if out of bounds (slides may have been deleted/disabled)
if ($this->currentSlide >= count($this->slides)) {
$this->currentSlide = 0;
// Clear the stored progress since it's invalid
if ($perSession) {
\Illuminate\Support\Facades\Cookie::queue(\Illuminate\Support\Facades\Cookie::forget('onboarding_current_slide'));
} else {
session()->forget("onboarding_current_slide_{$userId}");
}
}
$this->showModal = !$hasSeenOnboarding;
}
public function getShowBackdropProperty()
{
$extension = ExtensionHelper::getExtension('other', 'Onboarding');
return $extension->config('show_backdrop', false);
}
public function nextSlide()
{
$currentSlideData = $this->slides[$this->currentSlide] ?? null;
$extension = ExtensionHelper::getExtension('other', 'Onboarding');
$perSession = $extension->config('per_session', false);
// If current slide is guided, redirect to the page
if ($currentSlideData && $currentSlideData['is_guided'] && $currentSlideData['page_route']) {
// Save current slide progress before redirecting
$this->currentSlide++;
if ($perSession) {
\Illuminate\Support\Facades\Cookie::queue('onboarding_current_slide', $this->currentSlide, 60 * 24 * 7); // 7 days
} else {
$userId = Auth::id();
session()->put("onboarding_current_slide_{$userId}", $this->currentSlide);
}
$this->redirectToPage($currentSlideData['page_route']);
return;
}
if ($this->currentSlide < count($this->slides) - 1) {
$this->currentSlide++;
// Save progress
if ($perSession) {
\Illuminate\Support\Facades\Cookie::queue('onboarding_current_slide', $this->currentSlide, 60 * 24 * 7); // 7 days
} else {
$userId = Auth::id();
session()->put("onboarding_current_slide_{$userId}", $this->currentSlide);
}
} else {
$this->finish();
}
}
public function previousSlide()
{
if ($this->currentSlide > 0) {
$this->currentSlide--;
// Save progress
$extension = ExtensionHelper::getExtension('other', 'Onboarding');
$perSession = $extension->config('per_session', false);
if ($perSession) {
\Illuminate\Support\Facades\Cookie::queue('onboarding_current_slide', $this->currentSlide, 60 * 24 * 7); // 7 days
} else {
$userId = Auth::id();
session()->put("onboarding_current_slide_{$userId}", $this->currentSlide);
}
}
}
public function finish()
{
// Check if test mode and per session mode are enabled
$extension = ExtensionHelper::getExtension('other', 'Onboarding');
$testMode = $extension->config('test_mode', false);
$perSession = $extension->config('per_session', false);
if ($perSession) {
// Clear current slide progress cookie
\Illuminate\Support\Facades\Cookie::queue(\Illuminate\Support\Facades\Cookie::forget('onboarding_current_slide'));
// Only mark as completed if not in test mode (30 days expiration)
if (!$testMode) {
\Illuminate\Support\Facades\Cookie::queue('onboarding_completed', '1', 60 * 24 * 30);
}
} else {
$userId = Auth::id();
// Clear current slide progress
session()->forget("onboarding_current_slide_{$userId}");
// Only mark as seen if not in test mode
if (!$testMode) {
session()->put("onboarding_seen_{$userId}", true);
}
}
$this->showModal = false;
}
protected function redirectToPage($pageRoute)
{
$url = match ($pageRoute) {
'dashboard' => route('dashboard'),
'services' => route('services'),
'services.first' => $this->getFirstServiceUrl(),
'invoices' => route('invoices'),
'tickets' => route('tickets'),
'tickets.create' => route('tickets.create'),
'account' => route('account'),
'account.security' => route('account.security'),
'account.payment-methods' => route('account.payment-methods'),
'account.notifications' => route('account.notifications'),
'products' => route('home') . '#shop',
default => route('dashboard'),
};
if ($url) {
return $this->redirect($url, navigate: true);
}
}
protected function getFirstServiceUrl()
{
$service = Auth::user()->services()->where('status', 'active')->first();
return $service ? route('services.show', $service) : route('services');
}
public function render()
{
return view('onboarding::modal');
}
}