Spaces:
Running
Running
Add 3 files
Browse files- README.md +7 -5
- index.html +285 -19
- prompts.txt +1 -0
README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
---
|
| 2 |
+
title: sdds
|
| 3 |
+
emoji: 🐳
|
| 4 |
+
colorFrom: gray
|
| 5 |
+
colorTo: gray
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite
|
| 10 |
---
|
| 11 |
|
| 12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
|
@@ -1,19 +1,285 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Danh sách sự kiện</title>
|
| 7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
| 9 |
+
<style>
|
| 10 |
+
.tiptap-content {
|
| 11 |
+
line-height: 1.6;
|
| 12 |
+
color: #374151;
|
| 13 |
+
font-family: 'Inter', sans-serif;
|
| 14 |
+
}
|
| 15 |
+
.tiptap-content p {
|
| 16 |
+
margin-bottom: 1rem;
|
| 17 |
+
}
|
| 18 |
+
.tiptap-content ul,
|
| 19 |
+
.tiptap-content ol {
|
| 20 |
+
padding-left: 1.5rem;
|
| 21 |
+
margin-bottom: 1rem;
|
| 22 |
+
}
|
| 23 |
+
.tiptap-content ul {
|
| 24 |
+
list-style-type: disc;
|
| 25 |
+
}
|
| 26 |
+
.tiptap-content ol {
|
| 27 |
+
list-style-type: decimal;
|
| 28 |
+
}
|
| 29 |
+
.tiptap-content h1 {
|
| 30 |
+
font-size: 1.5rem;
|
| 31 |
+
font-weight: bold;
|
| 32 |
+
margin: 1.5rem 0 1rem;
|
| 33 |
+
}
|
| 34 |
+
.tiptap-content h2 {
|
| 35 |
+
font-size: 1.25rem;
|
| 36 |
+
font-weight: bold;
|
| 37 |
+
margin: 1.25rem 0 0.75rem;
|
| 38 |
+
}
|
| 39 |
+
.tiptap-content h3 {
|
| 40 |
+
font-size: 1.125rem;
|
| 41 |
+
font-weight: bold;
|
| 42 |
+
margin: 1rem 0 0.5rem;
|
| 43 |
+
}
|
| 44 |
+
.tiptap-content a {
|
| 45 |
+
color: #3b82f6;
|
| 46 |
+
text-decoration: underline;
|
| 47 |
+
}
|
| 48 |
+
.tiptap-content blockquote {
|
| 49 |
+
padding-left: 1rem;
|
| 50 |
+
border-left: 3px solid #e5e7eb;
|
| 51 |
+
color: #6b7280;
|
| 52 |
+
margin: 1rem 0;
|
| 53 |
+
}
|
| 54 |
+
.tiptap-content pre {
|
| 55 |
+
background: #f3f4f6;
|
| 56 |
+
padding: 1rem;
|
| 57 |
+
border-radius: 0.5rem;
|
| 58 |
+
overflow-x: auto;
|
| 59 |
+
margin: 1rem 0;
|
| 60 |
+
}
|
| 61 |
+
.tiptap-content code {
|
| 62 |
+
background: #f3f4f6;
|
| 63 |
+
padding: 0.2rem 0.4rem;
|
| 64 |
+
border-radius: 0.25rem;
|
| 65 |
+
font-family: monospace;
|
| 66 |
+
}
|
| 67 |
+
/* Vietnam time badge */
|
| 68 |
+
.time-badge {
|
| 69 |
+
display: inline-flex;
|
| 70 |
+
align-items: center;
|
| 71 |
+
gap: 0.25rem;
|
| 72 |
+
background-color: #f0f9ff;
|
| 73 |
+
color: #0369a1;
|
| 74 |
+
padding: 0.25rem 0.5rem;
|
| 75 |
+
border-radius: 9999px;
|
| 76 |
+
font-size: 0.75rem;
|
| 77 |
+
font-weight: 500;
|
| 78 |
+
}
|
| 79 |
+
.time-badge i {
|
| 80 |
+
font-size: 0.65rem;
|
| 81 |
+
}
|
| 82 |
+
/* Creator badge */
|
| 83 |
+
.creator-badge {
|
| 84 |
+
display: inline-flex;
|
| 85 |
+
align-items: center;
|
| 86 |
+
gap: 0.25rem;
|
| 87 |
+
background-color: #f5f3ff;
|
| 88 |
+
color: #7c3aed;
|
| 89 |
+
padding: 0.25rem 0.5rem;
|
| 90 |
+
border-radius: 9999px;
|
| 91 |
+
font-size: 0.75rem;
|
| 92 |
+
font-weight: 500;
|
| 93 |
+
}
|
| 94 |
+
.admin-badge {
|
| 95 |
+
background-color: #fef2f2;
|
| 96 |
+
color: #dc2626;
|
| 97 |
+
}
|
| 98 |
+
</style>
|
| 99 |
+
</head>
|
| 100 |
+
<body class="bg-gray-50">
|
| 101 |
+
<div class="max-w-4xl mx-auto p-4 sm:p-6">
|
| 102 |
+
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 sm:mb-8 gap-4">
|
| 103 |
+
<div>
|
| 104 |
+
<h1 class="text-2xl sm:text-3xl font-bold text-gray-800">Danh sách sự kiện</h1>
|
| 105 |
+
<div class="time-badge mt-1">
|
| 106 |
+
<i class="fas fa-clock"></i>
|
| 107 |
+
<span>Giờ Việt Nam (UTC+7)</span>
|
| 108 |
+
</div>
|
| 109 |
+
</div>
|
| 110 |
+
<a href="/su-kien/create" class="inline-flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition shadow hover:shadow-md w-full sm:w-auto justify-center">
|
| 111 |
+
<i class="fas fa-plus"></i>
|
| 112 |
+
<span>Tạo sự kiện mới</span>
|
| 113 |
+
</a>
|
| 114 |
+
</div>
|
| 115 |
+
|
| 116 |
+
@if($posts->isEmpty())
|
| 117 |
+
<div class="text-center py-12 bg-white rounded-xl shadow-sm">
|
| 118 |
+
<div class="mx-auto w-24 h-24 bg-blue-100 rounded-full flex items-center justify-center mb-6">
|
| 119 |
+
<i class="fas fa-calendar-alt text-blue-500 text-4xl"></i>
|
| 120 |
+
</div>
|
| 121 |
+
<h3 class="text-xl font-medium text-gray-700 mb-2">Chưa có sự kiện nào</h3>
|
| 122 |
+
<p class="text-gray-500 mb-6">Hãy tạo sự kiện đầu tiên của bạn</p>
|
| 123 |
+
<a href="/su-kien/create" class="inline-flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition">
|
| 124 |
+
<i class="fas fa-plus"></i>
|
| 125 |
+
<span>Tạo sự kiện mới</span>
|
| 126 |
+
</a>
|
| 127 |
+
</div>
|
| 128 |
+
@else
|
| 129 |
+
<div class="space-y-4">
|
| 130 |
+
@foreach($posts as $post)
|
| 131 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300">
|
| 132 |
+
<!-- Post Header -->
|
| 133 |
+
<div class="border-b border-gray-100 p-4 flex justify-between items-start">
|
| 134 |
+
<div class="space-y-2">
|
| 135 |
+
<div class="flex flex-wrap items-center gap-2">
|
| 136 |
+
<div class="creator-badge {{ $post->user->is_admin ? 'admin-badge' : '' }}">
|
| 137 |
+
<i class="fas {{ $post->user->is_admin ? 'fa-shield-alt' : 'fa-user' }}"></i>
|
| 138 |
+
<span>{{ $post->user->name }}</span>
|
| 139 |
+
@if($post->user->is_admin)
|
| 140 |
+
<span class="ml-1">(Admin)</span>
|
| 141 |
+
@endif
|
| 142 |
+
</div>
|
| 143 |
+
|
| 144 |
+
<div class="flex items-center gap-2 text-sm text-gray-600">
|
| 145 |
+
<i class="fas fa-map-marker-alt text-blue-500"></i>
|
| 146 |
+
<span>
|
| 147 |
+
{{ $post->area->name ?? '---' }} /
|
| 148 |
+
{{ $post->propertyStreet->full_name ?? '---' }} /
|
| 149 |
+
Căn hộ {{ $post->propertyUnit->number ?? '---' }}
|
| 150 |
+
</span>
|
| 151 |
+
</div>
|
| 152 |
+
</div>
|
| 153 |
+
|
| 154 |
+
<div class="flex items-center gap-2 text-sm text-gray-600">
|
| 155 |
+
<i class="far fa-clock text-blue-500"></i>
|
| 156 |
+
<span>
|
| 157 |
+
{{ $post->created_at->setTimezone('Asia/Ho_Chi_Minh')->format('H:i d/m/Y') }}
|
| 158 |
+
<span class="time-badge ml-2">ICT</span>
|
| 159 |
+
</span>
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
|
| 163 |
+
<!-- Dropdown Menu -->
|
| 164 |
+
<div class="relative">
|
| 165 |
+
<button class="text-gray-400 hover:text-gray-600 transition-colors" onclick="toggleDropdown('dropdown-{{ $post->id }}')">
|
| 166 |
+
<i class="fas fa-ellipsis-v"></i>
|
| 167 |
+
</button>
|
| 168 |
+
<div id="dropdown-{{ $post->id }}" class="hidden absolute right-0 mt-2 w-40 bg-white rounded-md shadow-lg z-10 border border-gray-100">
|
| 169 |
+
<a href="/su-kien/{{ $post->id }}/edit" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2">
|
| 170 |
+
<i class="fas fa-edit text-blue-500"></i>
|
| 171 |
+
<span>Sửa</span>
|
| 172 |
+
</a>
|
| 173 |
+
<form method="POST" action="/su-kien/{{ $post->id }}">
|
| 174 |
+
@csrf
|
| 175 |
+
@method('DELETE')
|
| 176 |
+
<button type="submit" onclick="return confirm('Bạn có chắc muốn xoá?')" class="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-50 flex items-center gap-2">
|
| 177 |
+
<i class="fas fa-trash-alt text-red-500"></i>
|
| 178 |
+
<span>Xoá</span>
|
| 179 |
+
</button>
|
| 180 |
+
</form>
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
</div>
|
| 184 |
+
|
| 185 |
+
<!-- Post Content -->
|
| 186 |
+
<div class="p-4">
|
| 187 |
+
<div class="tiptap-content">
|
| 188 |
+
{!! $post->content !!}
|
| 189 |
+
</div>
|
| 190 |
+
|
| 191 |
+
@if($post->images)
|
| 192 |
+
<div class="flex flex-wrap gap-3 mt-4">
|
| 193 |
+
@foreach($post->images as $img)
|
| 194 |
+
<div class="relative group">
|
| 195 |
+
<img src="{{ asset('storage/' . $img) }}"
|
| 196 |
+
class="w-24 h-24 object-cover rounded-lg border cursor-pointer hover:ring-2 hover:ring-blue-400 transition-all"
|
| 197 |
+
onclick="openImageModal('{{ asset('storage/' . $img) }}')">
|
| 198 |
+
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-20 rounded-lg transition-all duration-300 flex items-center justify-center opacity-0 group-hover:opacity-100">
|
| 199 |
+
<i class="fas fa-search-plus text-white text-xl"></i>
|
| 200 |
+
</div>
|
| 201 |
+
</div>
|
| 202 |
+
@endforeach
|
| 203 |
+
</div>
|
| 204 |
+
@endif
|
| 205 |
+
</div>
|
| 206 |
+
</div>
|
| 207 |
+
@endforeach
|
| 208 |
+
</div>
|
| 209 |
+
@endif
|
| 210 |
+
</div>
|
| 211 |
+
|
| 212 |
+
<!-- Image Modal -->
|
| 213 |
+
<div id="imageModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden">
|
| 214 |
+
<div class="relative max-w-4xl max-h-screen">
|
| 215 |
+
<button onclick="closeImageModal()" class="absolute -top-10 right-0 text-white hover:text-gray-300">
|
| 216 |
+
<i class="fas fa-times text-2xl"></i>
|
| 217 |
+
</button>
|
| 218 |
+
<img id="modalImage" src="" class="max-w-full max-h-screen">
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
|
| 222 |
+
<script>
|
| 223 |
+
// Toggle dropdown
|
| 224 |
+
function toggleDropdown(id) {
|
| 225 |
+
const dropdown = document.getElementById(id);
|
| 226 |
+
dropdown.classList.toggle('hidden');
|
| 227 |
+
|
| 228 |
+
// Close other dropdowns
|
| 229 |
+
document.querySelectorAll('[id^="dropdown-"]').forEach(el => {
|
| 230 |
+
if (el.id !== id) el.classList.add('hidden');
|
| 231 |
+
});
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
// Close dropdowns when clicking outside
|
| 235 |
+
document.addEventListener('click', function(e) {
|
| 236 |
+
if (!e.target.closest('.relative')) {
|
| 237 |
+
document.querySelectorAll('[id^="dropdown-"]').forEach(el => {
|
| 238 |
+
el.classList.add('hidden');
|
| 239 |
+
});
|
| 240 |
+
}
|
| 241 |
+
});
|
| 242 |
+
|
| 243 |
+
// Image modal functions
|
| 244 |
+
function openImageModal(src) {
|
| 245 |
+
document.getElementById('modalImage').src = src;
|
| 246 |
+
document.getElementById('imageModal').classList.remove('hidden');
|
| 247 |
+
document.body.style.overflow = 'hidden';
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
function closeImageModal() {
|
| 251 |
+
document.getElementById('imageModal').classList.add('hidden');
|
| 252 |
+
document.body.style.overflow = 'auto';
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
// Close modal when clicking outside image
|
| 256 |
+
document.getElementById('imageModal').addEventListener('click', function(e) {
|
| 257 |
+
if (e.target.id === 'imageModal') {
|
| 258 |
+
closeImageModal();
|
| 259 |
+
}
|
| 260 |
+
});
|
| 261 |
+
|
| 262 |
+
// Format content on page load
|
| 263 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 264 |
+
document.querySelectorAll('.tiptap-content').forEach(content => {
|
| 265 |
+
// Convert line breaks to paragraphs if content is plain text
|
| 266 |
+
if (!content.innerHTML.includes('<p>') && !content.innerHTML.includes('<div>')) {
|
| 267 |
+
content.innerHTML = content.innerHTML
|
| 268 |
+
.split('\n')
|
| 269 |
+
.filter(para => para.trim() !== '')
|
| 270 |
+
.map(para => `<p>${para}</p>`)
|
| 271 |
+
.join('');
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
// Add responsive styling to tables if they exist
|
| 275 |
+
const tables = content.querySelectorAll('table');
|
| 276 |
+
tables.forEach(table => {
|
| 277 |
+
const wrapper = document.createElement('div');
|
| 278 |
+
wrapper.className = 'overflow-x-auto';
|
| 279 |
+
table.parentNode.insertBefore(wrapper, table);
|
| 280 |
+
wrapper.appendChild(table);
|
| 281 |
+
table.className = 'min-w-full divide-y divide-gray-200';
|
| 282 |
+
|
| 283 |
+
// Style table headers and cells
|
| 284 |
+
const ths = table.querySelectorAll('
|
| 285 |
+
</html>
|
prompts.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
you should add the logic to display who created the post and is it admin or not. And remember remain my code logics since I'm using laravel, don't add your fake data in here:@extends('layouts.app') @section('content') <style> <style> .tiptap-content { line-height: 1.6; color: #374151; font-family: 'Inter', sans-serif; } .tiptap-content p { margin-bottom: 1rem; } .tiptap-content ul, .tiptap-content ol { padding-left: 1.5rem; margin-bottom: 1rem; } .tiptap-content ul { list-style-type: disc; } .tiptap-content ol { list-style-type: decimal; } .tiptap-content h1 { font-size: 1.5rem; font-weight: bold; margin: 1.5rem 0 1rem; } .tiptap-content h2 { font-size: 1.25rem; font-weight: bold; margin: 1.25rem 0 0.75rem; } .tiptap-content h3 { font-size: 1.125rem; font-weight: bold; margin: 1rem 0 0.5rem; } .tiptap-content a { color: #3b82f6; text-decoration: underline; } .tiptap-content blockquote { padding-left: 1rem; border-left: 3px solid #e5e7eb; color: #6b7280; margin: 1rem 0; } .tiptap-content pre { background: #f3f4f6; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin: 1rem 0; } .tiptap-content code { background: #f3f4f6; padding: 0.2rem 0.4rem; border-radius: 0.25rem; font-family: monospace; } /* Vietnam time badge */ .time-badge { display: inline-flex; align-items: center; gap: 0.25rem; background-color: #f0f9ff; color: #0369a1; padding: 0.25rem 0.5rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 500; } .time-badge i { font-size: 0.65rem; } </style> <div class="max-w-4xl mx-auto p-4 sm:p-6"> <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 sm:mb-8 gap-4"> <div> <h1 class="text-2xl sm:text-3xl font-bold text-gray-800">Danh sách sự kiện</h1> <div class="time-badge mt-1"> <i class="fas fa-clock"></i> <span>Giờ Việt Nam (UTC+7)</span> </div> </div> <a href="/su-kien/create" class="inline-flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition shadow hover:shadow-md w-full sm:w-auto justify-center"> <i class="fas fa-plus"></i> <span>Tạo sự kiện mới</span> </a> </div> @if($posts->isEmpty()) <div class="text-center py-12 bg-white rounded-xl shadow-sm"> <div class="mx-auto w-24 h-24 bg-blue-100 rounded-full flex items-center justify-center mb-6"> <i class="fas fa-calendar-alt text-blue-500 text-4xl"></i> </div> <h3 class="text-xl font-medium text-gray-700 mb-2">Chưa có sự kiện nào</h3> <p class="text-gray-500 mb-6">Hãy tạo sự kiện đầu tiên của bạn</p> <a href="/su-kien/create" class="inline-flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition"> <i class="fas fa-plus"></i> <span>Tạo sự kiện mới</span> </a> </div> @else <div class="space-y-4"> @foreach($posts as $post) <div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300"> <!-- Post Header --> <div class="border-b border-gray-100 p-4 flex justify-between items-start"> <div> <div class="flex items-center gap-2 text-sm text-gray-600 mb-1"> <i class="fas fa-map-marker-alt text-blue-500"></i> <span> {{ $post->area->name ?? '---' }} / {{ $post->propertyStreet->full_name ?? '---' }} / Căn hộ {{ $post->propertyUnit->number ?? '---' }} </span> </div> <div class="flex items-center gap-2 text-sm text-gray-600"> <i class="far fa-clock text-blue-500"></i> <span> {{ $post->created_at->setTimezone('Asia/Ho_Chi_Minh')->format('H:i d/m/Y') }} <span class="time-badge ml-2">ICT</span> </span> </div> </div> <!-- Dropdown Menu --> <div class="relative"> <button class="text-gray-400 hover:text-gray-600 transition-colors" onclick="toggleDropdown('dropdown-{{ $post->id }}')"> <i class="fas fa-ellipsis-v"></i> </button> <div id="dropdown-{{ $post->id }}" class="hidden absolute right-0 mt-2 w-40 bg-white rounded-md shadow-lg z-10 border border-gray-100"> <a href="/su-kien/{{ $post->id }}/edit" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"> <i class="fas fa-edit text-blue-500"></i> <span>Sửa</span> </a> <form method="POST" action="/su-kien/{{ $post->id }}"> @csrf @method('DELETE') <button type="submit" onclick="return confirm('Bạn có chắc muốn xoá?')" class="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-50 flex items-center gap-2"> <i class="fas fa-trash-alt text-red-500"></i> <span>Xoá</span> </button> </form> </div> </div> </div> <!-- Post Content --> <div class="p-4"> <div class="tiptap-content"> {!! $post->content !!} </div> @if($post->images) <div class="flex flex-wrap gap-3 mt-4"> @foreach($post->images as $img) <div class="relative group"> <img src="{{ asset('storage/' . $img) }}" class="w-24 h-24 object-cover rounded-lg border cursor-pointer hover:ring-2 hover:ring-blue-400 transition-all" onclick="openImageModal('{{ asset('storage/' . $img) }}')"> <div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-20 rounded-lg transition-all duration-300 flex items-center justify-center opacity-0 group-hover:opacity-100"> <i class="fas fa-search-plus text-white text-xl"></i> </div> </div> @endforeach </div> @endif </div> </div> @endforeach </div> @endif </div> <!-- Image Modal --> <div id="imageModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden"> <div class="relative max-w-4xl max-h-screen"> <button onclick="closeImageModal()" class="absolute -top-10 right-0 text-white hover:text-gray-300"> <i class="fas fa-times text-2xl"></i> </button> <img id="modalImage" src="" class="max-w-full max-h-screen"> </div> </div> <script> // Toggle dropdown function toggleDropdown(id) { const dropdown = document.getElementById(id); dropdown.classList.toggle('hidden'); // Close other dropdowns document.querySelectorAll('[id^="dropdown-"]').forEach(el => { if (el.id !== id) el.classList.add('hidden'); }); } // Close dropdowns when clicking outside document.addEventListener('click', function(e) { if (!e.target.closest('.relative')) { document.querySelectorAll('[id^="dropdown-"]').forEach(el => { el.classList.add('hidden'); }); } }); // Image modal functions function openImageModal(src) { document.getElementById('modalImage').src = src; document.getElementById('imageModal').classList.remove('hidden'); document.body.style.overflow = 'hidden'; } function closeImageModal() { document.getElementById('imageModal').classList.add('hidden'); document.body.style.overflow = 'auto'; } // Close modal when clicking outside image document.getElementById('imageModal').addEventListener('click', function(e) { if (e.target.id === 'imageModal') { closeImageModal(); } }); // Format content on page load document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.tiptap-content').forEach(content => { // Convert line breaks to paragraphs if content is plain text if (!content.innerHTML.includes('<p>') && !content.innerHTML.includes('<div>')) { content.innerHTML = content.innerHTML .split('\n') .filter(para => para.trim() !== '') .map(para => `<p>${para}</p>`) .join(''); } // Add responsive styling to tables if they exist const tables = content.querySelectorAll('table'); tables.forEach(table => { const wrapper = document.createElement('div'); wrapper.className = 'overflow-x-auto'; table.parentNode.insertBefore(wrapper, table); wrapper.appendChild(table); table.className = 'min-w-full divide-y divide-gray-200'; // Style table headers and cells const ths = table.querySelectorAll('th'); ths.forEach(th => { th.className = 'px-4 py-2 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider'; }); const tds = table.querySelectorAll('td'); tds.forEach(td => { td.className = 'px-4 py-2 whitespace-nowrap text-sm text-gray-500 border-t border-gray-200'; }); }); }); }); </script> @endsection
|