feat: implement comprehensive deployment script for Laravel with progress indicators and rollback functionality, enhancing deployment reliability and user experience
This commit is contained in:
@@ -43,9 +43,7 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<!-- Logo and app name -->
|
||||
<div class="flex flex-row items-center">
|
||||
<a href="{{ route('home') }}" class="flex flex-row items-center h-10 gap-2" wire:navigate>
|
||||
@if (config('settings.logo'))
|
||||
<img src="{{ \Storage::url(config('settings.logo')) }}" alt="{{ config('app.name') }}" class="h-10 w-auto inline-block mr-2 rtl:ml-2">
|
||||
@endif
|
||||
{!! $creditsLogoHtml ?? '' !!}
|
||||
<span class="text-xl font-bold leading-none flex items-center text-flow-effect">
|
||||
{{ config('app.name') }}
|
||||
</span>
|
||||
|
||||
@@ -11,16 +11,16 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<div class="flex flex-col gap-2">
|
||||
@foreach (\App\Classes\Navigation::getLinks() as $nav)
|
||||
@if (!empty($nav['children']))
|
||||
<div x-data="{ activeAccordion: {{ $nav['active'] ? 'true' : 'false' }} }"
|
||||
<div x-data="{ activeAccordion: {{ ($nav['active'] ?? false) ? 'true' : 'false' }} }"
|
||||
class="relative w-full overflow-hidden text-sm font-medium">
|
||||
<div class="cursor-pointer">
|
||||
<button @click="activeAccordion = !activeAccordion"
|
||||
class="flex items-center justify-between w-full p-3 text-sm font-semibold whitespace-nowrap rounded-lg
|
||||
hover:bg-primary/10 transition-colors duration-200 {{ $nav['active'] ? 'text-primary bg-primary/5' : 'text-color-base' }}">
|
||||
hover:bg-primary/10 transition-colors duration-200 {{ ($nav['active'] ?? false) ? 'text-primary bg-primary/5' : 'text-color-base' }}">
|
||||
<div class="flex items-center gap-3">
|
||||
@isset($nav['icon'])
|
||||
<x-dynamic-component :component="$nav['icon']"
|
||||
class="size-5 {{ $nav['active'] ? 'text-primary' : 'text-color-muted' }}" />
|
||||
class="size-5 {{ ($nav['active'] ?? false) ? 'text-primary' : 'text-color-muted' }}" />
|
||||
@endisset
|
||||
<span>{{ $nav['name'] }}</span>
|
||||
</div>
|
||||
@@ -34,7 +34,7 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<x-navigation.link :href="route($child['route'], $child['params'] ?? [])"
|
||||
:spa="$child['spa'] ?? true"
|
||||
class="block w-full p-2 rounded-md transition-colors duration-200
|
||||
{{ $child['active'] ? 'text-primary font-bold bg-primary/10' : 'text-color-muted hover:bg-primary/5' }}">
|
||||
{{ ($child['active'] ?? false) ? 'text-primary font-bold bg-primary/10' : 'text-color-muted hover:bg-primary/5' }}">
|
||||
{{ $child['name'] }}
|
||||
</x-navigation.link>
|
||||
</div>
|
||||
@@ -47,10 +47,10 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<x-navigation.link :href="route($nav['route'], $nav['params'] ?? [])"
|
||||
:spa="$nav['spa'] ?? true"
|
||||
class="flex items-center gap-3 p-3 rounded-lg transition-colors duration-200 w-full
|
||||
{{ $nav['active'] ? 'bg-primary/10 text-primary font-semibold' : 'hover:bg-primary/5 text-color-base' }}">
|
||||
{{ ($nav['active'] ?? false) ? 'bg-primary/10 text-primary font-semibold' : 'hover:bg-primary/5 text-color-base' }}">
|
||||
@isset($nav['icon'])
|
||||
<x-dynamic-component :component="$nav['icon']"
|
||||
class="size-5 {{ $nav['active'] ? 'text-primary' : 'text-color-muted' }}" />
|
||||
class="size-5 {{ ($nav['active'] ?? false) ? 'text-primary' : 'text-color-muted' }}" />
|
||||
@endisset
|
||||
<span>{{ $nav['name'] }}</span>
|
||||
</x-navigation.link>
|
||||
@@ -70,16 +70,16 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<div class="flex flex-col gap-2 flex-grow">
|
||||
@foreach (\App\Classes\Navigation::getDashboardLinks() as $nav)
|
||||
@if (!empty($nav['children']))
|
||||
<div x-data="{ activeAccordion: {{ $nav['active'] ? 'true' : 'false' }} }"
|
||||
<div x-data="{ activeAccordion: {{ ($nav['active'] ?? false) ? 'true' : 'false' }} }"
|
||||
class="relative w-full overflow-hidden text-sm font-medium">
|
||||
<div class="cursor-pointer">
|
||||
<button @click="activeAccordion = !activeAccordion"
|
||||
class="flex items-center justify-between w-full p-3 text-sm font-semibold whitespace-nowrap rounded-lg
|
||||
hover:bg-primary/10 transition-colors duration-200 {{ $nav['active'] ? 'text-primary bg-primary/5' : 'text-color-base' }}">
|
||||
hover:bg-primary/10 transition-colors duration-200 {{ ($nav['active'] ?? false) ? 'text-primary bg-primary/5' : 'text-color-base' }}">
|
||||
<div class="flex items-center gap-3">
|
||||
@isset($nav['icon'])
|
||||
<x-dynamic-component :component="$nav['icon']"
|
||||
class="size-5 {{ $nav['active'] ? 'text-primary' : 'text-color-muted' }}" />
|
||||
class="size-5 {{ ($nav['active'] ?? false) ? 'text-primary' : 'text-color-muted' }}" />
|
||||
@endisset
|
||||
<span>{{ $nav['name'] }}</span>
|
||||
</div>
|
||||
@@ -94,7 +94,7 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<x-navigation.link :href="route($child['route'], $child['params'] ?? [])"
|
||||
:spa="$child['spa'] ?? true"
|
||||
class="block w-full p-2 rounded-md transition-colors duration-200
|
||||
{{ $child['active'] ? 'text-primary font-bold bg-primary/10' : 'text-color-muted hover:bg-primary/5' }}">
|
||||
{{ ($child['active'] ?? false) ? 'text-primary font-bold bg-primary/10' : 'text-color-muted hover:bg-primary/5' }}">
|
||||
{{ $child['name'] }}
|
||||
</x-navigation.link>
|
||||
</div>
|
||||
@@ -108,10 +108,10 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
<x-navigation.link :href="route($nav['route'], $nav['params'] ?? [])"
|
||||
:spa="$nav['spa'] ?? true"
|
||||
class="flex items-center gap-3 p-3 rounded-lg transition-colors duration-200 w-full
|
||||
{{ $nav['active'] ? 'bg-primary/10 text-primary font-semibold' : 'hover:bg-primary/5 text-color-base' }}">
|
||||
{{ ($nav['active'] ?? false) ? 'bg-primary/10 text-primary font-semibold' : 'hover:bg-primary/5 text-color-base' }}">
|
||||
@isset($nav['icon'])
|
||||
<x-dynamic-component :component="$nav['icon']"
|
||||
class="size-5 {{ $nav['active'] ? 'text-primary' : 'text-color-muted' }}" />
|
||||
class="size-5 {{ ($nav['active'] ?? false) ? 'text-primary' : 'text-color-muted' }}" />
|
||||
@endisset
|
||||
<span>{{ $nav['name'] }}</span>
|
||||
</x-navigation.link>
|
||||
@@ -152,57 +152,7 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
@if(auth()->check())
|
||||
<div class="border-t border-neutral/50 pt-4 mt-auto">
|
||||
{{-- Credits Display for Mobile --}}
|
||||
@php
|
||||
try {
|
||||
$user = auth()->user();
|
||||
$credits = $user->credits()->with('currency')->get();
|
||||
|
||||
if ($credits->isEmpty()) {
|
||||
$currencyCode = session('currency', config('settings.default_currency', 'USD'));
|
||||
$currency = \App\Models\Currency::where('code', $currencyCode)->first();
|
||||
if ($currency) {
|
||||
$creditsDisplay = $currency->prefix . '0.00' . $currency->suffix;
|
||||
} else {
|
||||
$creditsDisplay = '0.00 ' . $currencyCode;
|
||||
}
|
||||
} else {
|
||||
$creditsByCurrency = $credits->groupBy('currency_code');
|
||||
$maxAmount = null;
|
||||
$maxCurrencyCode = null;
|
||||
$maxCurrency = null;
|
||||
|
||||
foreach ($creditsByCurrency as $currencyCode => $userCredits) {
|
||||
$totalAmount = $userCredits->sum('amount');
|
||||
if ($totalAmount <= 0) continue;
|
||||
if ($maxAmount === null || $totalAmount > $maxAmount) {
|
||||
$maxAmount = $totalAmount;
|
||||
$maxCurrencyCode = $currencyCode;
|
||||
$maxCurrency = $userCredits->first()->currency;
|
||||
}
|
||||
}
|
||||
|
||||
if ($maxAmount === null) {
|
||||
$currencyCode = session('currency', config('settings.default_currency', 'USD'));
|
||||
$currency = \App\Models\Currency::where('code', $currencyCode)->first();
|
||||
if ($currency) {
|
||||
$creditsDisplay = $currency->prefix . '0.00' . $currency->suffix;
|
||||
} else {
|
||||
$creditsDisplay = '0.00 ' . $currencyCode;
|
||||
}
|
||||
} else {
|
||||
if ($maxCurrency) {
|
||||
$creditsDisplay = $maxCurrency->prefix . number_format($maxAmount, 2) . $maxCurrency->suffix;
|
||||
} else {
|
||||
$creditsDisplay = number_format($maxAmount, 2) . ' ' . $maxCurrencyCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$creditsDisplay = '0.00';
|
||||
}
|
||||
@endphp
|
||||
|
||||
@if(isset($creditsDisplay))
|
||||
@if(isset($userCreditsDisplay))
|
||||
<a href="{{ route('account.credits') }}" wire:navigate
|
||||
class="flex items-center justify-between p-3 mb-3 bg-gradient-to-r from-primary/10 to-secondary/10 hover:from-primary/20 hover:to-secondary/20 border border-primary/30 rounded-xl transition-all duration-200">
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -211,7 +161,7 @@ Unauthorized copying, modification, or distribution is prohibited.
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xs text-color-muted">Account Credits</span>
|
||||
<span class="text-sm font-bold text-primary">{{ $creditsDisplay }}</span>
|
||||
<span class="text-sm font-bold text-primary">{{ $userCreditsDisplay }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<x-ri-arrow-right-line class="size-5 text-color-muted" />
|
||||
|
||||
Reference in New Issue
Block a user