feature: login and my page
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<div class="flex flex-col items-center justify-center h-full w-full text-center px-6 py-12 md:py-20">
|
||||
<!-- Illustration Wrapper -->
|
||||
<div class="relative w-full max-w-[280px] md:max-w-[340px] aspect-square mb-10 mx-auto flex items-center justify-center">
|
||||
<!-- Floating decorative elements -->
|
||||
<div class="absolute top-10 left-4 animate-[bounce_3s_infinite]">
|
||||
<x-icon-star class="w-8 h-8 text-yellow-400 opacity-80" />
|
||||
</div>
|
||||
<div class="absolute bottom-20 left-10 animate-[pulse_4s_infinite]">
|
||||
<x-icon-sparkle class="w-6 h-6 text-pink-400 opacity-60" />
|
||||
</div>
|
||||
<div class="absolute top-20 right-10 animate-[bounce_4s_infinite_reverse]">
|
||||
<x-icon-star class="w-10 h-10 text-blue-400 opacity-70" />
|
||||
</div>
|
||||
<div class="absolute bottom-16 right-4 animate-[pulse_3s_infinite]">
|
||||
<x-icon-sparkle class="w-8 h-8 text-purple-400 opacity-80" />
|
||||
</div>
|
||||
|
||||
<!-- Background blob glows -->
|
||||
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<div class="w-48 h-48 bg-blue-100/60 rounded-full blur-3xl absolute animate-blob"></div>
|
||||
<div class="w-40 h-40 bg-pink-100/50 rounded-full blur-3xl absolute translate-x-12 animate-blob animation-delay-2000"></div>
|
||||
</div>
|
||||
|
||||
<!-- Main Custom Rocket SVG -->
|
||||
<div class="relative z-10 animate-float">
|
||||
<x-icon-rocket class="w-64 h-64 md:w-72 md:h-72 drop-shadow-2xl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<h1 class="text-[28px] md:text-[34px] font-extrabold text-[#1a2b49] mb-4 tracking-tight">
|
||||
Tính năng đang phát triển
|
||||
</h1>
|
||||
<p class="text-gray-500 font-medium max-w-[420px] mx-auto mb-10 leading-relaxed text-[15px]">
|
||||
Chúng tôi đang nỗ lực để mang đến trải nghiệm tốt nhất cho bạn. Vui lòng quay lại sau nhé!
|
||||
</p>
|
||||
|
||||
<!-- Primary Button -->
|
||||
<a href="{{ route('user.dashboard') }}" class="inline-flex items-center justify-center gap-2.5 px-8 py-3.5 bg-[#3462f7] hover:bg-blue-700 text-white font-bold rounded-xl shadow-[0_8px_16px_-4px_rgba(52,98,247,0.4)] transition-all hover:-translate-y-1 active:translate-y-0 text-[15px]">
|
||||
<x-icon-arrow-left class="w-5 h-5 stroke-2" />
|
||||
Quay về trang chủ
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
50% { transform: translateY(-15px) rotate(2deg); }
|
||||
}
|
||||
.animate-float {
|
||||
animation: float 5s ease-in-out infinite;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,56 @@
|
||||
@props([
|
||||
'type' => 'text',
|
||||
'name',
|
||||
'id' => null,
|
||||
'label' => '',
|
||||
'required' => false,
|
||||
'value' => '',
|
||||
'autocomplete' => null,
|
||||
'icon' => null,
|
||||
'hasError' => false,
|
||||
])
|
||||
|
||||
@php
|
||||
$id = $id ?? $name;
|
||||
$isPassword = $type === 'password';
|
||||
@endphp
|
||||
|
||||
<div class="floating-group">
|
||||
<input
|
||||
type="{{ $type }}"
|
||||
name="{{ $name }}"
|
||||
id="{{ $id }}"
|
||||
placeholder=" "
|
||||
@if($required) required @endif
|
||||
value="{{ $value }}"
|
||||
@if($autocomplete) autocomplete="{{ $autocomplete }}" @endif
|
||||
{{ $attributes->merge(['class' => 'floating-input' . ($hasError ? ' border-red-500 focus:border-red-500 focus:ring-red-500/20' : '')]) }}
|
||||
@if($hasError)
|
||||
aria-invalid="true"
|
||||
aria-describedby="login-errors"
|
||||
@endif
|
||||
/>
|
||||
<label for="{{ $id }}" class="floating-label{{ $hasError ? ' text-red-500' : '' }}">
|
||||
{{ $label }}
|
||||
@if($required)
|
||||
<span class="text-red-500" aria-hidden="true">*</span>
|
||||
@endif
|
||||
</label>
|
||||
@if($icon)
|
||||
<span class="floating-icon{{ $hasError ? ' text-red-500' : '' }}">
|
||||
<x-icon :name="$icon" class="w-5 h-5" />
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if($isPassword)
|
||||
<button
|
||||
type="button"
|
||||
class="absolute right-3 top-1/2 -translate-y-1/2 text-text-muted hover:text-text-medium focus:text-primary focus:outline-none focus:ring-2 focus:ring-primary/20 rounded p-1 transition-colors duration-200 cursor-pointer"
|
||||
onclick="togglePasswordVisibility('{{ $id }}', this)"
|
||||
aria-label="Show password"
|
||||
>
|
||||
<x-icon name="eye" class="w-5 h-5 eye-icon-open" />
|
||||
<x-icon name="eye-slash" class="w-5 h-5 eye-icon-closed hidden" />
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<header class="bg-transparent sticky top-0 z-30 pt-6 pb-2 px-8 flex justify-between items-center w-full">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Menu hamburger -->
|
||||
<button id="sidebar-hamburger" class="p-2 text-gray-500 hover:text-gray-800 rounded-md focus:outline-none transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
|
||||
<!-- Primary Action Button -->
|
||||
<a href="{{ route('user.send') }}" class="hidden sm:flex items-center gap-2 px-5 py-2.5 bg-[#3462f7] hover:bg-blue-700 text-white text-[14px] font-bold rounded-xl shadow-md transition-all shadow-blue-500/20">
|
||||
<span class="text-lg leading-none">+</span>
|
||||
Gửi Thanks card
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,33 @@
|
||||
<div class="bg-gradient-to-r from-[#eff4ff] to-[#faeffa] rounded-[24px] p-10 flex flex-col md:flex-row items-center justify-between w-full h-full border border-white shadow-sm overflow-hidden relative">
|
||||
|
||||
<!-- Content Left -->
|
||||
<div class="flex-1 relative z-10 w-full md:pr-4">
|
||||
<h2 class="text-[42px] font-extrabold text-[#1a2b49] flex items-center gap-3 mb-3 leading-none tracking-tight">
|
||||
Thanks <span class="text-[#8b98e8] font-medium tracking-wider" style="font-family: 'Caveat', cursive, sans-serif; font-size: 52px; transform: translateY(-4px);">Card</span>
|
||||
<svg class="w-8 h-8 text-[#8b98e8]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||||
</svg>
|
||||
</h2>
|
||||
<p class="text-[16px] text-gray-600 font-medium mb-8 leading-relaxed max-w-[320px]">
|
||||
Một lời cảm ơn chân thành<br>có thể tạo nên ngày tuyệt vời của ai đó!
|
||||
</p>
|
||||
<a href="{{ route('user.send') }}" class="inline-flex items-center gap-2 px-8 py-3.5 bg-[#3462f7] hover:bg-blue-700 text-white font-semibold rounded-xl shadow-lg shadow-blue-500/25 transition-all text-[15px]">
|
||||
Gửi lời cảm ơn ngay
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Illustration Right -->
|
||||
<div class="w-[340px] shrink-0 relative flex justify-end">
|
||||
<img src="{{ asset('images/hero_banner_illustration.png') }}" alt="Illustration" class="w-full max-w-[320px] object-contain drop-shadow-xl z-10 mix-blend-multiply">
|
||||
</div>
|
||||
|
||||
<!-- Background Elements -->
|
||||
<div class="absolute inset-0 z-0 opacity-50 pointer-events-none overflow-hidden">
|
||||
<div class="absolute top-10 left-1/3 w-2 h-2 bg-pink-400 rounded-full blur-[1px]"></div>
|
||||
<div class="absolute bottom-12 left-[40%] w-3 h-3 bg-blue-400 rounded-full blur-[1px]"></div>
|
||||
<div class="absolute top-1/4 right-[45%] w-3 h-3 bg-yellow-400 rounded-full blur-[1px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg" {{ $attributes }}>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 212 B |
@@ -0,0 +1,27 @@
|
||||
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" {{ $attributes }}>
|
||||
<g transform="rotate(45, 100, 100)">
|
||||
<!-- Main Body Base -->
|
||||
<path d="M100 20 C150 70, 160 130, 140 160 L60 160 C40 130, 50 70, 100 20 Z" fill="#E2E8F0" />
|
||||
<path d="M100 20 C130 70, 120 130, 100 160 C80 130, 70 70, 100 20 Z" fill="#F8FAFC" />
|
||||
|
||||
<!-- Nose Cone -->
|
||||
<path d="M100 20 C120 40, 125 55, 125 70 L75 70 C75 55, 80 40, 100 20 Z" fill="#3462F7" />
|
||||
|
||||
<!-- Windows -->
|
||||
<circle cx="100" cy="95" r="22" fill="#94A3B8" />
|
||||
<circle cx="100" cy="95" r="16" fill="#1E293B" />
|
||||
<circle cx="104" cy="91" r="6" fill="#60A5FA" opacity="0.8" />
|
||||
|
||||
<!-- Fins -->
|
||||
<path d="M60 130 L10 180 L60 150 Z" fill="#2563EB" />
|
||||
<path d="M140 130 L190 180 L140 150 Z" fill="#2563EB" />
|
||||
<path d="M100 130 L95 180 L105 180 Z" fill="#1E3A8A" />
|
||||
|
||||
<!-- Exhaust base -->
|
||||
<path d="M80 160 L120 160 L110 175 L90 175 Z" fill="#475569" />
|
||||
|
||||
<!-- Flames -->
|
||||
<path d="M90 175 C 90 200, 100 230, 100 230 C 100 230, 110 200, 110 175 Z" fill="#F59E0B" />
|
||||
<path d="M95 175 C 95 190, 100 210, 100 210 C 100 210, 105 190, 105 175 Z" fill="#FEF08A" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" {{ $attributes }}>
|
||||
<path d="M12 2C12.5 7.5 16.5 11.5 22 12C16.5 12.5 12.5 16.5 12 22C11.5 16.5 7.5 12.5 2 12C7.5 11.5 11.5 7.5 12 2Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 228 B |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" {{ $attributes }}>
|
||||
<path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 220 B |
@@ -0,0 +1,11 @@
|
||||
<div class="w-full rounded-[20px] p-4 bg-[#F5F7FA] border border-[#E2E8F0] shadow-sm flex items-center gap-4">
|
||||
<div class="flex-1">
|
||||
<h4 class="font-bold text-[#1E293B] text-[14px] mb-1.5">Bạn có biết?</h4>
|
||||
<p class="text-[12px] text-[#475569] font-medium leading-relaxed">
|
||||
Một lời cảm ơn chân thành có thể nhân đôi động lực làm việc của đồng nghiệp!
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-6 h-6 bg-white rounded-full flex items-center justify-center shrink-0 shadow-sm border border-[#E2E8F0]">
|
||||
<span class="text-lg drop-shadow-sm">💡</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="absolute inset-0 pointer-events-none overflow-hidden z-0 select-none">
|
||||
<svg class="absolute bottom-0 left-0 w-[45%] h-[40%] min-w-[320px] max-w-[600px] text-primary/[0.04]" viewBox="0 0 100 100" preserveAspectRatio="none" fill="currentColor" aria-hidden="true">
|
||||
<path d="M 0,100 C 30,85 55,60 70,30 C 85,10 95,5 100,0 L 0,0 Z" transform="rotate(180, 50, 50)" />
|
||||
<path d="M 0,100 C 40,75 60,50 75,25 C 90,5 95,0 100,0 L 0,0 Z" transform="rotate(180, 50, 50)" opacity="0.5" />
|
||||
</svg>
|
||||
<svg class="absolute top-10 right-10 w-[180px] h-[180px] text-primary/[0.03]" viewBox="0 0 100 100" fill="currentColor" aria-hidden="true">
|
||||
<circle cx="10" cy="10" r="1.5" /> <circle cx="30" cy="10" r="1.5" /> <circle cx="50" cy="10" r="1.5" /> <circle cx="70" cy="10" r="1.5" /> <circle cx="90" cy="10" r="1.5" />
|
||||
<circle cx="10" cy="30" r="1.5" /> <circle cx="30" cy="30" r="1.5" /> <circle cx="50" cy="30" r="1.5" /> <circle cx="70" cy="30" r="1.5" /> <circle cx="90" cy="30" r="1.5" />
|
||||
<circle cx="10" cy="50" r="1.5" /> <circle cx="30" cy="50" r="1.5" /> <circle cx="50" cy="50" r="1.5" /> <circle cx="70" cy="50" r="1.5" /> <circle cx="90" cy="50" r="1.5" />
|
||||
<circle cx="10" cy="70" r="1.5" /> <circle cx="30" cy="70" r="1.5" /> <circle cx="50" cy="70" r="1.5" /> <circle cx="70" cy="70" r="1.5" /> <circle cx="90" cy="70" r="1.5" />
|
||||
<circle cx="10" cy="90" r="1.5" /> <circle cx="30" cy="90" r="1.5" /> <circle cx="50" cy="90" r="1.5" /> <circle cx="70" cy="90" r="1.5" /> <circle cx="90" cy="90" r="1.5" />
|
||||
</svg>
|
||||
</div>
|
||||
@@ -0,0 +1,68 @@
|
||||
<div class="flex-1 hidden lg:flex justify-center items-center relative min-h-[480px]">
|
||||
<div class="relative z-10 w-full max-w-[440px]">
|
||||
<svg viewBox="0 0 500 500" class="w-full h-auto" aria-hidden="true" role="img">
|
||||
<circle cx="250" cy="250" r="180" fill="none" stroke="#e2e8f0" stroke-width="2" stroke-dasharray="6,6" opacity="0.6" />
|
||||
|
||||
<rect x="60" y="80" width="120" height="70" rx="4" fill="none" stroke="#cbd5e1" stroke-width="2" />
|
||||
<line x1="60" y1="120" x2="180" y2="120" stroke="#cbd5e1" stroke-width="2" />
|
||||
<rect x="75" y="95" width="12" height="25" fill="#94a3b8" />
|
||||
<rect x="90" y="90" width="14" height="30" fill="#cbd5e1" />
|
||||
<rect x="110" y="100" width="14" height="20" fill="#94a3b8" transform="rotate(15, 110, 100)" />
|
||||
|
||||
<rect x="340" y="60" width="100" height="130" rx="6" fill="none" stroke="#cbd5e1" stroke-width="2" />
|
||||
<line x1="390" y1="60" x2="390" y2="190" stroke="#cbd5e1" stroke-width="1.5" />
|
||||
<line x1="340" y1="120" x2="440" y2="120" stroke="#cbd5e1" stroke-width="1.5" />
|
||||
|
||||
<ellipse cx="250" cy="455" rx="55" ry="9" fill="#cbd5e1" opacity="0.4" />
|
||||
|
||||
<line x1="230" y1="360" x2="215" y2="450" stroke="#d29a0f" stroke-width="4.5" stroke-linecap="round" />
|
||||
<line x1="270" y1="360" x2="285" y2="450" stroke="#d29a0f" stroke-width="4.5" stroke-linecap="round" />
|
||||
<line x1="250" y1="360" x2="250" y2="450" stroke="#9a6a00" stroke-width="3.5" stroke-linecap="round" />
|
||||
<ellipse cx="250" cy="415" rx="20" ry="4" fill="none" stroke="#d29a0f" stroke-width="2" />
|
||||
<ellipse cx="250" cy="435" rx="24" ry="5" fill="none" stroke="#d29a0f" stroke-width="2" />
|
||||
<rect x="220" y="348" width="60" height="12" rx="5" fill="#fbbf24" />
|
||||
|
||||
<polygon points="150,450 170,450 166,415 154,415" fill="#94a3b8" />
|
||||
<path d="M 160,415 Q 145,390 135,385" fill="none" stroke="#cbd5e1" stroke-width="2.5" stroke-linecap="round" />
|
||||
<path d="M 160,415 Q 165,380 175,370" fill="none" stroke="#cbd5e1" stroke-width="2.5" stroke-linecap="round" />
|
||||
<circle cx="135" cy="385" r="7" fill="#cbd5e1" />
|
||||
<circle cx="175" cy="370" r="9" fill="#94a3b8" />
|
||||
|
||||
<path d="M 230,358 Q 220,400 225,435" fill="none" stroke="#334155" stroke-width="12" stroke-linecap="round" />
|
||||
<path d="M 252,358 Q 262,400 258,435" fill="none" stroke="#334155" stroke-width="12" stroke-linecap="round" />
|
||||
<path d="M 225,435 L 218,443 L 230,443 Z" fill="#fbbf24" stroke="#fbbf24" stroke-width="3" stroke-linejoin="round" />
|
||||
<path d="M 258,435 L 265,443 L 253,443 Z" fill="#fbbf24" stroke="#fbbf24" stroke-width="3" stroke-linejoin="round" />
|
||||
|
||||
<path d="M 222,275 C 222,275 258,275 258,275 L 252,325 C 252,325 228,325 228,325 Z" fill="#ffffff" />
|
||||
<rect x="242" y="285" width="8" height="10" rx="1.5" fill="#ef222e" />
|
||||
|
||||
<rect x="235" y="260" width="10" height="16" fill="#fed7aa" />
|
||||
|
||||
<circle cx="240" cy="242" r="16" fill="#fed7aa" />
|
||||
<circle cx="236" cy="240" r="18" fill="#1e293b" />
|
||||
<path d="M 220,245 C 205,245 195,255 198,270 C 208,265 218,255 222,250 Z" fill="#1e293b" />
|
||||
<path d="M 226,232 Q 242,225 252,238 C 252,238 246,228 234,228 Z" fill="#1e293b" />
|
||||
<path d="M 228,230 Q 240,223 248,232" fill="none" stroke="#fbbf24" stroke-width="3.5" stroke-linecap="round" />
|
||||
|
||||
<polygon points="270,305 305,305 295,332 260,332" fill="#e2e8f0" />
|
||||
<polygon points="273,308 302,308 293,329 264,329" fill="#0f4c81" opacity="0.1" />
|
||||
<polygon points="252,332 295,332 290,338 247,338" fill="#cbd5e1" />
|
||||
|
||||
<path d="M 222,275 Q 240,312 265,315" fill="none" stroke="#fed7aa" stroke-width="7" stroke-linecap="round" />
|
||||
<path d="M 242,275 Q 255,295 272,300" fill="none" stroke="#fed7aa" stroke-width="7" stroke-linecap="round" />
|
||||
<circle cx="265" cy="315" r="4.5" fill="#fed7aa" />
|
||||
<circle cx="272" cy="300" r="4.5" fill="#fed7aa" />
|
||||
|
||||
<g transform="translate(45, -20)">
|
||||
<path d="M 266,160 C 266,120 305,100 335,120 C 355,130 365,150 365,170 C 365,190 345,210 325,205 L 312,222 L 309,204 C 282,198 266,180 266,160 Z" fill="#ffffff" filter="drop-shadow(0 4px 6px rgba(0,0,0,0.06))" />
|
||||
|
||||
<g transform="translate(302, 138)">
|
||||
<path d="M 8,10 L 8,6 C 8,2.5 18,2.5 18,6 L 18,10" stroke="#0f4c81" stroke-width="2.5" stroke-linecap="round" fill="none" />
|
||||
<rect x="3" y="10" width="20" height="15" rx="3.5" fill="#fbbf24" />
|
||||
<circle cx="13" cy="16.5" r="1.5" fill="#0f4c81" />
|
||||
<line x1="13" y1="18" x2="13" y2="21" stroke="#0f4c81" stroke-width="1.8" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="bg-white rounded-2xl p-6 border border-gray-100 shadow-[0_2px_10px_-4px_rgba(0,0,0,0.05)] h-full flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<h3 class="text-[16px] font-bold text-gray-900">Gửi nhanh</h3>
|
||||
<button class="text-gray-300 hover:text-gray-500">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-[12px] text-gray-400 font-medium mb-5">Chọn thiệp và gửi lời cảm ơn đến đồng nghiệp</p>
|
||||
|
||||
<!-- 3 Cards Grid -->
|
||||
<div class="grid grid-cols-3 gap-2.5 mb-5">
|
||||
<!-- Card 1 -->
|
||||
<button class="rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow border border-pink-50 relative group bg-gradient-to-b from-pink-50 to-pink-100/50 aspect-[2/3] flex items-center justify-center">
|
||||
<div class="w-12 h-12 bg-white rounded-full flex items-center justify-center text-pink-400 text-xl shadow-sm mb-2 group-hover:scale-110 transition-transform">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- Card 2 -->
|
||||
<button class="rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow border border-blue-50 relative group bg-gradient-to-b from-blue-50 to-blue-100/50 aspect-[2/3] flex items-center justify-center">
|
||||
<div class="w-12 h-12 bg-white rounded-full flex items-center justify-center text-blue-400 text-xl shadow-sm mb-2 group-hover:scale-110 transition-transform">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- Card 3 -->
|
||||
<button class="rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow border border-indigo-50 relative group bg-gradient-to-b from-indigo-50 to-indigo-100/50 aspect-[2/3] flex items-center justify-center">
|
||||
<div class="w-12 h-12 bg-white rounded-full flex items-center justify-center text-indigo-400 text-xl shadow-sm mb-2 group-hover:scale-110 transition-transform">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2L1 21h22L12 2zm0 3.83L19.17 19H4.83L12 5.83z"/></svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Link -->
|
||||
<a href="{{ route('user.send') }}" class="text-[13px] font-bold text-[#3462f7] hover:text-blue-800 flex items-center gap-1.5 group">
|
||||
Tạo thiệp của riêng bạn
|
||||
<svg class="w-3 h-3 transform group-hover:translate-x-1 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,34 @@
|
||||
@props(['rank', 'name', 'team', 'avatar', 'score', 'isCurrent' => false, 'unit' => 'điểm'])
|
||||
|
||||
<div class="flex items-center justify-between py-3 border-b border-gray-50 last:border-0 hover:bg-gray-50 rounded-xl px-3 transition-colors {{ $isCurrent ? 'bg-blue-50/50' : '' }}">
|
||||
<div class="flex items-center gap-3">
|
||||
<!-- Rank -->
|
||||
<div class="w-6 flex justify-center items-center">
|
||||
@if($rank == 1)
|
||||
<span class="text-xl">👑</span>
|
||||
<span class="absolute text-[10px] font-bold text-amber-500 translate-y-3">1</span>
|
||||
@elseif($rank == 2)
|
||||
<span class="text-[14px] text-gray-500 font-bold">2</span>
|
||||
@elseif($rank == 3)
|
||||
<span class="text-[14px] text-gray-500 font-bold">3</span>
|
||||
@else
|
||||
<span class="text-[14px] font-bold {{ $isCurrent ? 'text-blue-600' : 'text-gray-400' }}">{{ $rank }}</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Avatar & Info -->
|
||||
<div class="flex items-center gap-3 ml-1">
|
||||
<img src="{{ $avatar }}" alt="{{ $name }}" class="w-9 h-9 rounded-full object-cover shadow-sm">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[13px] font-bold {{ $isCurrent ? 'text-gray-900' : 'text-gray-800' }} leading-tight mb-0.5">{{ $name }}</span>
|
||||
<span class="text-[11px] text-gray-400 font-medium">{{ $team }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Score -->
|
||||
<div class="text-[13px]">
|
||||
<span class="font-extrabold {{ $isCurrent ? 'text-blue-600' : 'text-gray-700' }}">{{ number_format($score, 0, ',', '.') }}</span>
|
||||
<span class="text-gray-400 font-medium ml-0.5">{{ $unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
@props(['active' => false, 'icon' => 'home', 'href' => '#'])
|
||||
|
||||
@php
|
||||
$classes = $active
|
||||
? 'flex items-center gap-4 px-4 py-3 rounded-xl bg-[#eff4ff] text-[#3462f7] font-semibold transition-all duration-200'
|
||||
: 'flex items-center gap-4 px-4 py-3 rounded-xl text-gray-500 hover:bg-gray-50 hover:text-gray-900 font-medium transition-all duration-200';
|
||||
@endphp
|
||||
|
||||
<a href="{{ $href }}" {{ $attributes->merge(['class' => $classes]) }}>
|
||||
@if($icon == 'home')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" 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>
|
||||
@elseif($icon == 'paper-plane-send')
|
||||
<svg class="w-[22px] h-[22px] transform -rotate-45" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
|
||||
</svg>
|
||||
@elseif($icon == 'heart')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||||
</svg>
|
||||
@elseif($icon == 'paper-plane-outline')
|
||||
<svg class="w-[22px] h-[22px] transform -rotate-45" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
|
||||
</svg>
|
||||
@elseif($icon == 'trophy')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
@elseif($icon == 'folder')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
@elseif($icon == 'chart')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />
|
||||
</svg>
|
||||
@elseif($icon == 'users')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />
|
||||
</svg>
|
||||
@elseif($icon == 'gear')
|
||||
<svg class="w-[22px] h-[22px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
@endif
|
||||
<span class="text-[14px]">{{ $slot }}</span>
|
||||
</a>
|
||||
@@ -0,0 +1,68 @@
|
||||
@props(['active' => false])
|
||||
|
||||
<aside class="sidebar flex flex-col h-full bg-white border-r border-gray-100 shadow-sm transition-transform duration-300 w-64 fixed inset-y-0 left-0 z-40 lg:relative lg:translate-x-0 -translate-x-full" aria-label="Main navigation">
|
||||
<div class="p-6 flex items-center justify-between shrink-0">
|
||||
<img src="{{ asset('images/logo.png') }}" alt="GMO-Z.com RUNSYSTEM" class="h-6 w-auto object-contain">
|
||||
<!-- Mobile hamburger button/close -->
|
||||
<button id="sidebar-close" class="lg:hidden p-2 text-gray-500 hover:bg-gray-100 rounded-md focus:outline-none" aria-label="Close navigation">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav class="px-4 space-y-1.5 overflow-y-auto flex-1 pb-4">
|
||||
<!-- TABS CHUNG -->
|
||||
<x-sidebar-item href="{{ route('user.dashboard') }}" :active="request()->routeIs('user.dashboard')" icon="home">
|
||||
Trang chủ
|
||||
</x-sidebar-item>
|
||||
|
||||
<x-sidebar-item href="{{ route('user.send') }}" :active="request()->routeIs('user.send')" icon="paper-plane-send">
|
||||
Gửi Thanks card
|
||||
</x-sidebar-item>
|
||||
|
||||
<x-sidebar-item href="{{ route('user.received') }}" :active="request()->routeIs('user.received')" icon="heart">
|
||||
Thanks đã nhận
|
||||
</x-sidebar-item>
|
||||
|
||||
<x-sidebar-item href="{{ route('user.sent') }}" :active="request()->routeIs('user.sent')" icon="paper-plane-outline">
|
||||
Thanks đã gửi
|
||||
</x-sidebar-item>
|
||||
|
||||
<x-sidebar-item href="{{ route('user.ranking') }}" :active="request()->routeIs('user.ranking')" icon="trophy">
|
||||
Bảng xếp hạng
|
||||
</x-sidebar-item>
|
||||
|
||||
|
||||
@if(Auth::check() && Auth::user()->role == \App\Models\User::ROLE_ADMIN)
|
||||
<!-- ADMIN SIDEBAR -->
|
||||
<div class="pt-2 mt-2 border-t border-gray-100"></div>
|
||||
<x-sidebar-item href="{{ route('admin.users.index') }}" :active="request()->routeIs('admin.users.index')" icon="users">
|
||||
Quản lý User
|
||||
</x-sidebar-item>
|
||||
@endif
|
||||
|
||||
<x-sidebar-item href="{{ route('user.change_password') }}" :active="request()->routeIs('user.change_password')" icon="gear">
|
||||
Cài đặt
|
||||
</x-sidebar-item>
|
||||
</nav>
|
||||
|
||||
<!-- Illustration Box -->
|
||||
<div class="hidden xl:flex justify-center items-center px-6 py-2 mt-auto">
|
||||
<img src="{{ asset('images/sidebar_illustration.png') }}" class="w-full max-w-[200px] h-auto object-contain mix-blend-multiply" alt="Illustration" />
|
||||
</div>
|
||||
|
||||
<!-- User Profile Section -->
|
||||
<div class="p-5 border-t border-gray-100 flex items-center justify-between cursor-pointer hover:bg-gray-50 transition-colors shrink-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full overflow-hidden shrink-0 border border-gray-200">
|
||||
<img src="https://api.dicebear.com/7.x/notionists/svg?seed={{ Auth::id() ?? 'MinhAnh' }}&backgroundColor=e2e8f0" alt="Avatar" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[14px] font-bold text-[#1e293b] leading-tight truncate max-w-[130px]">{{ Auth::check() ? (Auth::user()->name ?? 'Nguyễn Minh Anh') : 'Nguyễn Minh Anh' }}</span>
|
||||
<span class="text-[12px] text-gray-500 font-medium">{{ Auth::check() ? (Auth::user()->role == \App\Models\User::ROLE_ADMIN ? 'Administrator' : 'Product Team') : 'Product Team' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<svg class="w-4 h-4 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</aside>
|
||||
@@ -1,14 +1,34 @@
|
||||
@props(['title', 'user', 'value', 'bgClass' => 'bg-[#0f4c81]', 'valueLabel' => 'Tổng thẻ đã nhận'])
|
||||
@props(['title' => '', 'value' => '', 'growth' => '', 'growthType' => 'up', 'iconBgClass' => '', 'iconColorClass' => '', 'subtitle' => ''])
|
||||
|
||||
<div class="card-stat-active {{ $bgClass }}">
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-white/90 text-xs font-bold uppercase tracking-wider">{{ $title }}</span>
|
||||
<span class="text-2xl font-black">{{ $user && $value > 0 ? $user : 'Chưa có' }}</span>
|
||||
<div class="bg-white rounded-2xl p-5 md:p-6 border border-gray-100 shadow-[0_2px_10px_-4px_rgba(0,0,0,0.05)] hover:shadow-md transition-shadow h-full flex flex-col justify-center">
|
||||
<div class="flex items-center gap-5">
|
||||
<!-- Icon -->
|
||||
<div class="w-[52px] h-[52px] rounded-2xl flex items-center justify-center shrink-0 {{ $iconBgClass }}">
|
||||
<div class="{{ $iconColorClass }}">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center pt-2 border-t border-white/20">
|
||||
<span class="text-white/80 text-[10px] font-bold">{{ $valueLabel }}</span>
|
||||
<span class="text-lg font-bold text-yellow-300">{{ $value }} thẻ</span>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[13px] font-semibold text-gray-500 mb-1.5">{{ $title }}</span>
|
||||
<div class="flex items-end gap-3 mb-1">
|
||||
<span class="text-[34px] font-bold text-[#1e293b] leading-none">{{ $value }}</span>
|
||||
</div>
|
||||
|
||||
@if($growth)
|
||||
<div class="flex items-center gap-1.5 mt-1">
|
||||
<span class="flex items-center text-[12px] font-bold {{ $growthType === 'up' ? 'text-[#10b981]' : 'text-[#ef4444]' }}">
|
||||
@if($growthType === 'up')
|
||||
<svg class="w-3.5 h-3.5 mr-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18"/></svg>
|
||||
@else
|
||||
<svg class="w-3.5 h-3.5 mr-0.5 transform rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18"/></svg>
|
||||
@endif
|
||||
{{ $growth }}
|
||||
</span>
|
||||
<span class="text-[11px] text-gray-400 font-medium">{{ $subtitle }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
@props(['title', 'message', 'isLiked' => false, 'bgClass', 'titleColorClass', 'textColorClass'])
|
||||
|
||||
<div class="rounded-[20px] p-5 border border-gray-100 shadow-sm {{ $bgClass }} transition-transform hover:-translate-y-1 hover:shadow-lg w-full">
|
||||
<h4 class="text-center font-black text-[18px] text-[#1E293B] uppercase tracking-wider mb-3">
|
||||
@if(str_contains($title, 'GREAT JOB'))
|
||||
✨ {{ $title }} ✨
|
||||
@elseif(str_contains($title, 'YOU ROCK'))
|
||||
🌟 {{ $title }} 🌟
|
||||
@else
|
||||
💖 {{ $title }} 💖
|
||||
@endif
|
||||
</h4>
|
||||
<p class="text-left text-[13px] text-[#475569] font-semibold leading-relaxed italic px-2">
|
||||
"{{ $message }}"
|
||||
</p>
|
||||
</div>
|
||||
Reference in New Issue
Block a user