feat: add resources and view components

This commit is contained in:
2026-05-21 16:05:19 +07:00
parent 28a06315b8
commit b2d60e680d
249 changed files with 37379 additions and 0 deletions
@@ -0,0 +1,146 @@
<x-guest-layout>
@push('styles')
<style>
.legal-container {
max-width: 1000px;
margin: 60px auto;
padding: 0 25px;
}
.legal-header {
margin-bottom: 50px;
text-align: center;
}
.legal-card {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px);
border-radius: 40px;
border: 1px solid rgba(255, 255, 255, 0.5);
box-shadow: 0 30px 60px rgba(0,0,0,0.1);
padding: 60px;
}
.last-revised-badge {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 50px;
padding: 8px 20px;
font-size: 0.85rem;
display: inline-block;
margin-bottom: 15px;
color: #6c757d;
}
.legal-content {
font-family: var(--adminuiux-content-font), "Open Sans", sans-serif;
line-height: 1.8;
color: #2c3e50;
}
.legal-content h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
line-height: 1.1;
margin-bottom: 30px;
}
.legal-content h2 {
font-size: clamp(1.5rem, 4vw, 2rem);
}
.legal-content h1, .legal-content h2, .legal-content h3 {
font-family: var(--adminuiux-title-font), "Outfit", sans-serif;
font-weight: 700;
margin-top: 45px;
margin-bottom: 25px;
color: #1a1a1a;
letter-spacing: -0.02em;
}
.legal-content p { margin-bottom: 20px; }
.legal-content ul, .legal-content ol { margin-bottom: 25px; padding-left: 20px; }
.legal-content li { margin-bottom: 10px; }
.legal-back-btn {
font-family: var(--adminuiux-title-font), "Outfit", sans-serif;
font-weight: 600;
color: #ffffff; /* High contrast on dark bg */
background: rgba(0,0,0,0.15);
padding: 10px 25px;
border-radius: 50px;
text-decoration: none;
display: inline-flex;
align-items: center;
margin-bottom: 30px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
backdrop-filter: blur(5px);
border: 1px solid rgba(255,255,255,0.1);
}
.legal-back-btn:hover {
transform: translateX(-5px);
background: rgba(0,0,0,0.3);
color: #fff;
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
.legal-footer {
margin-top: 40px;
text-align: center;
padding: 20px;
border-top: 1px solid #f1f3f5;
}
.toc-floating {
position: sticky;
top: 100px;
height: fit-content;
}
@media (max-width: 991px) {
.legal-card { padding: 40px; }
.legal-container { margin: 30px auto; padding: 0 15px; }
}
@media (max-width: 575px) {
.legal-card { padding: 30px 20px; border-radius: 30px; }
.legal-header { margin-bottom: 35px; }
}
</style>
@endpush
<div class="legal-container">
<a href="{{ route('login') }}" class="legal-back-btn">
<i class="bi bi-arrow-left me-2"></i> {{ __('Back to Login') }}
</a>
<div class="row">
<div class="col-12">
<div class="legal-card overflow-hidden">
<header class="legal-header">
<div class="last-revised-badge">
<i class="bi bi-clock-history me-2"></i>
{{ __('Version') }} {{ $version }} &bull;
{{ __('Last Updated') }}: {{ $lastUpdated ?? now()->format('Y-m-d') }}
</div>
<h1 class="display-5 fw-bold text-dark">{{ $title }}</h1>
</header>
<article class="legal-content">
@if(!empty($content))
{!! strip_tags($content, '<h1><h2><h3><h4><h5><h6><p><br><strong><em><u><s><ul><ol><li><a><blockquote><table><thead><tbody><tr><th><td><hr><span><div><img>') !!}
@else
<div class="text-center py-5 opacity-50">
<i class="bi bi-file-earmark-text fs-1 mb-3 d-block"></i>
<p>{{ __('Content for this page has not been published yet.') }}</p>
</div>
@endif
@if($type === 'privacy' && !empty($dpo_email))
<div class="alert alert-light border rounded-4 mt-5 p-4">
<h6 class="fw-bold"><i class="bi bi-shield-check text-success me-2"></i> {{ __('Data Protection Officer') }}</h6>
<p class="small mb-2">{{ __('If you have questions regarding your data privacy, please contact our DPO:') }}</p>
<a href="mailto:{{ $dpo_email }}" class="text-primary fw-bold">{{ $dpo_email }}</a>
@if(!empty($company_address))
<div class="mt-3 x-small text-muted">
<i class="bi bi-geo-alt me-1"></i> {{ $company_address }}
</div>
@endif
</div>
@endif
</article>
<footer class="legal-footer">
<p class="small text-muted mb-0">&copy; {{ date('Y') }} {{ config('app.name') }}. {{ __('All rights reserved.') }}</p>
</footer>
</div>
</div>
</div>
</div>
</x-guest-layout>
@@ -0,0 +1,150 @@
<x-guest-layout :maxWidthClass="'maxwidth-800'">
@push('styles')
<style>
.re-agree-container {
width: 100%;
margin: 40px auto;
}
.re-agree-card {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px) saturate(180%);
border-radius: 40px;
border: 1px solid rgba(255, 255, 255, 0.5);
box-shadow: 0 40px 80px rgba(0,0,0,0.1);
padding: 50px;
}
.legal-preview-box {
height: 250px;
overflow-y: auto;
background: rgba(248, 249, 250, 0.8);
border: 1px solid rgba(0,0,0,0.05);
border-radius: 20px;
padding: 25px;
font-size: 0.95rem;
line-height: 1.7;
margin-bottom: 20px;
color: #333;
font-family: var(--adminuiux-content-font), sans-serif;
}
.legal-preview-box h1, .legal-preview-box h2 {
font-family: var(--adminuiux-title-font);
font-weight: 700;
margin-bottom: 1rem;
color: #000;
}
.step-badge {
background: #1e1e1e;
color: #fff;
width: 32px;
height: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-weight: bold;
margin-right: 12px;
font-size: 0.9rem;
}
.maxwidth-800 {
max-width: 800px !important;
width: 100% !important;
}
.form-check.custom-check {
display: flex;
align-items: center; /* Center the checkbox vertically with the text */
padding-left: 1.5rem !important;
}
.form-check.custom-check .form-check-input {
margin-top: 0 !important;
margin-left: -0.75rem !important;
}
.btn-pill-primary {
white-space: normal !important; /* Allow text to wrap if very long */
min-height: 60px;
display: flex;
align-items: center;
justify-content: center;
line-height: 1.2;
}
</style>
@endpush
<div class="re-agree-container">
<div class="re-agree-card">
<div class="text-center mb-5">
<div class="avatar avatar-80 rounded-circle bg-primary-subtle text-primary mx-auto mb-4">
<i class="bi bi-shield-check fs-1"></i>
</div>
<h2 class="fw-bold text-dark mb-2" style="font-family: var(--adminuiux-title-font); font-size: clamp(1.5rem, 4vw, 2.25rem);">{{ __('Legal Update Required') }}</h2>
<p class="text-muted mx-auto" style="max-width: 500px;">{{ __('We have updated our legal documents to improve our services and compliance with UU PDP regulations. please review and accept the latest terms to continue.') }}</p>
</div>
<form action="{{ route('legal.re-agree.post') }}" method="POST">
@csrf
@if($missingTos)
<div class="mb-5">
<h5 class="fw-bold mb-4 d-flex align-items-center">
<span class="step-badge">1</span> {{ __('Terms of Use Update') }}
<span class="badge bg-light text-dark border ms-2 fw-normal fs-xs">v{{ $tosVersion }}</span>
</h5>
<div class="legal-preview-box">
@if(!empty($tosContent))
{!! strip_tags($tosContent, '<h1><h2><h3><h4><h5><h6><p><br><strong><em><u><s><ul><ol><li><a><blockquote><table><thead><tbody><tr><th><td><hr><span><div><img>') !!}
@else
<div class="text-center py-5 opacity-50 italic">
<i class="bi bi-file-earmark-text fs-2 mb-2 d-block"></i>
{{ __('Terms of Use content is being updated...') }}
</div>
@endif
</div>
<div class="form-check custom-check p-3 bg-light rounded-4 border">
<input type="checkbox" name="agree_tos" class="form-check-input flex-shrink-0" id="agree_tos" required>
<label class="form-check-label fw-bold ms-2 mb-0" for="agree_tos" style="cursor: pointer;">
{{ __('I have read and agree to the latest Terms of Use') }}
</label>
</div>
</div>
@endif
@if($missingPrivacy)
<div class="mb-5">
<h5 class="fw-bold mb-4 d-flex align-items-center">
<span class="step-badge">{{ $missingTos ? '2' : '1' }}</span> {{ __('Privacy Policy Update') }}
<span class="badge bg-light text-dark border ms-2 fw-normal fs-xs">v{{ $privacyVersion }}</span>
</h5>
<div class="legal-preview-box">
@if(!empty($privacyContent))
{!! strip_tags($privacyContent, '<h1><h2><h3><h4><h5><h6><p><br><strong><em><u><s><ul><ol><li><a><blockquote><table><thead><tbody><tr><th><td><hr><span><div><img>') !!}
@else
<div class="text-center py-5 opacity-50 italic">
<i class="bi bi-shield-lock fs-2 mb-2 d-block"></i>
{{ __('Privacy Policy content is being updated...') }}
</div>
@endif
</div>
<div class="form-check custom-check p-3 bg-light rounded-4 border">
<input type="checkbox" name="agree_privacy" class="form-check-input flex-shrink-0" id="agree_privacy" required>
<label class="form-check-label fw-bold ms-2 mb-0" for="agree_privacy" style="cursor: pointer;">
{{ __('I have read and agree to the latest Privacy Policy (UU PDP)') }}
</label>
</div>
</div>
@endif
<div class="mt-5">
<button type="submit" class="btn btn-pill-primary w-100 py-3 fs-5 shadow-sm">
{{ __('Update Agreements & Proceed') }} <i class="bi bi-arrow-right ms-2"></i>
</button>
<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();" class="btn btn-link text-muted small w-100 mt-4 text-decoration-none">
{{ __('Logout and review later') }}
</a>
</div>
</form>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</div>
</x-guest-layout>