mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 23:51:09 -05:00
- Updated the filtered_list.html template to extend from base/base.html and improved layout and styling. - Removed the park_list.html template as its functionality is now integrated into the filtered list. - Added a new migration to create indexes for improved filtering performance on the parks model. - Merged migrations to maintain a clean migration history. - Implemented a ParkFilterService to handle complex filtering logic, aggregations, and caching for park filters. - Enhanced filter suggestions and popular filters retrieval methods. - Improved the overall structure and efficiency of the filtering system.
411 lines
9.2 KiB
CSS
411 lines
9.2 KiB
CSS
/* Enhanced Loading states */
|
|
.htmx-request .htmx-indicator {
|
|
opacity: 1;
|
|
}
|
|
.htmx-request.htmx-indicator {
|
|
opacity: 1;
|
|
}
|
|
.htmx-indicator {
|
|
opacity: 0;
|
|
transition: opacity 200ms ease-in-out;
|
|
}
|
|
|
|
/* Loading pulse animation */
|
|
@keyframes loading-pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.htmx-request {
|
|
animation: loading-pulse 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
/* Results container transitions */
|
|
#park-results {
|
|
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
.htmx-request #park-results {
|
|
opacity: 0.7;
|
|
transform: scale(0.98);
|
|
}
|
|
.htmx-settling #park-results {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
|
|
/* Filter UI Enhancements */
|
|
.quick-filter-btn {
|
|
@apply inline-flex items-center px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200 ease-in-out;
|
|
@apply focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500;
|
|
@apply transform hover:scale-105 active:scale-95;
|
|
@apply border border-transparent;
|
|
}
|
|
|
|
.quick-filter-btn:hover {
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
}
|
|
|
|
.filter-count {
|
|
@apply text-xs opacity-75 ml-1;
|
|
}
|
|
|
|
/* Filter Chips Styling */
|
|
.filter-chip {
|
|
@apply inline-flex items-center px-3 py-1 rounded-full text-sm bg-blue-100 text-blue-800;
|
|
@apply dark:bg-blue-800 dark:text-blue-100 transition-all duration-200;
|
|
animation: slideIn 0.3s ease-out;
|
|
}
|
|
|
|
.filter-chip:hover {
|
|
@apply bg-blue-200 dark:bg-blue-700;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.filter-chip .remove-btn {
|
|
@apply ml-2 inline-flex items-center justify-center w-4 h-4;
|
|
@apply text-blue-600 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-100;
|
|
@apply focus:outline-none transition-colors duration-150;
|
|
}
|
|
|
|
.filter-chip .remove-btn:hover {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
@keyframes slideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
/* Enhanced Search Input */
|
|
.search-input {
|
|
@apply transition-all duration-200 ease-in-out;
|
|
}
|
|
|
|
.search-input:focus {
|
|
@apply ring-2 ring-blue-500 border-blue-500;
|
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
}
|
|
|
|
/* Enhanced Form Controls */
|
|
.filter-field select,
|
|
.filter-field input[type="text"],
|
|
.filter-field input[type="number"],
|
|
.filter-field input[type="search"],
|
|
.form-field-wrapper input,
|
|
.form-field-wrapper select {
|
|
@apply transition-all duration-200 ease-in-out;
|
|
@apply border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white;
|
|
@apply focus:border-blue-500 focus:ring-blue-500;
|
|
@apply rounded-md shadow-sm;
|
|
}
|
|
|
|
.filter-field select:focus,
|
|
.filter-field input:focus,
|
|
.form-field-wrapper input:focus,
|
|
.form-field-wrapper select:focus {
|
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
}
|
|
|
|
.filter-field input[type="checkbox"],
|
|
.form-field-wrapper input[type="checkbox"] {
|
|
@apply rounded transition-colors duration-200;
|
|
@apply text-blue-600 focus:ring-blue-500;
|
|
@apply border-gray-300 dark:border-gray-600;
|
|
}
|
|
|
|
/* Enhanced Status Indicators */
|
|
.status-indicator {
|
|
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
|
|
animation: fadeIn 0.3s ease-out;
|
|
}
|
|
|
|
.status-indicator.filtered {
|
|
@apply bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100;
|
|
}
|
|
|
|
.status-indicator.loading {
|
|
@apply bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
/* Grid/List transitions */
|
|
.park-card {
|
|
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
position: relative;
|
|
background-color: white;
|
|
border-radius: 0.75rem;
|
|
border: 1px solid #e5e7eb;
|
|
}
|
|
|
|
/* Grid view styles */
|
|
.park-card[data-view-mode="grid"] {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.park-card[data-view-mode="grid"]:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
}
|
|
|
|
/* List view styles */
|
|
.park-card[data-view-mode="list"] {
|
|
display: flex;
|
|
gap: 1rem;
|
|
padding: 1rem;
|
|
}
|
|
.park-card[data-view-mode="list"]:hover {
|
|
background-color: #f9fafb;
|
|
transform: translateX(4px);
|
|
}
|
|
|
|
/* Image containers */
|
|
.park-card .image-container {
|
|
position: relative;
|
|
overflow: hidden;
|
|
border-radius: 0.5rem;
|
|
}
|
|
.park-card[data-view-mode="grid"] .image-container {
|
|
aspect-ratio: 16 / 9;
|
|
width: 100%;
|
|
}
|
|
.park-card[data-view-mode="list"] .image-container {
|
|
width: 6rem;
|
|
height: 6rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Content */
|
|
.park-card .content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-width: 0; /* Enables text truncation in flex child */
|
|
}
|
|
|
|
/* Enhanced Status badges */
|
|
.park-card .status-badge {
|
|
transition: all 200ms ease-in-out;
|
|
border-radius: 9999px;
|
|
font-weight: 500;
|
|
}
|
|
.park-card:hover .status-badge {
|
|
transform: scale(1.05);
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
/* Images */
|
|
.park-card img {
|
|
transition: transform 300ms ease-in-out;
|
|
object-fit: cover;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.park-card:hover img {
|
|
transform: scale(1.08);
|
|
}
|
|
|
|
/* Placeholders for missing images */
|
|
.park-card .placeholder {
|
|
background: linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%);
|
|
background-size: 200% 100%;
|
|
animation: shimmer 1.5s linear infinite;
|
|
border-radius: 0.5rem;
|
|
}
|
|
|
|
@keyframes shimmer {
|
|
to {
|
|
background-position: 200% center;
|
|
}
|
|
}
|
|
|
|
/* Enhanced No Results State */
|
|
.no-results {
|
|
@apply text-center py-12;
|
|
animation: fadeInUp 0.5s ease-out;
|
|
}
|
|
|
|
.no-results-icon {
|
|
@apply mx-auto w-24 h-24 text-gray-400 dark:text-gray-500 mb-6;
|
|
animation: float 3s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes float {
|
|
0%, 100% { transform: translateY(0px); }
|
|
50% { transform: translateY(-10px); }
|
|
}
|
|
|
|
/* Enhanced Buttons */
|
|
.btn-enhanced {
|
|
@apply transition-all duration-200 ease-in-out;
|
|
@apply transform hover:scale-105 active:scale-95;
|
|
@apply focus:outline-none focus:ring-2 focus:ring-offset-2;
|
|
}
|
|
|
|
.btn-enhanced:hover {
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
}
|
|
|
|
/* Tooltip Styles */
|
|
.tooltip {
|
|
@apply absolute z-50 px-2 py-1 text-xs font-medium text-white bg-gray-900 rounded shadow-lg;
|
|
@apply dark:bg-gray-700 dark:text-gray-200;
|
|
animation: tooltipFadeIn 0.2s ease-out;
|
|
}
|
|
|
|
@keyframes tooltipFadeIn {
|
|
from { opacity: 0; transform: scale(0.8); }
|
|
to { opacity: 1; transform: scale(1); }
|
|
}
|
|
|
|
/* Enhanced Dark mode */
|
|
@media (prefers-color-scheme: dark) {
|
|
.park-card {
|
|
background-color: #1f2937;
|
|
border-color: #374151;
|
|
}
|
|
|
|
.park-card[data-view-mode="list"]:hover {
|
|
background-color: #374151;
|
|
}
|
|
|
|
.park-card .text-gray-900 {
|
|
color: #f3f4f6;
|
|
}
|
|
|
|
.park-card .text-gray-500 {
|
|
color: #9ca3af;
|
|
}
|
|
|
|
.park-card .placeholder {
|
|
background: linear-gradient(110deg, #2d3748 8%, #374151 18%, #2d3748 33%);
|
|
}
|
|
|
|
.search-input {
|
|
@apply dark:bg-gray-700 dark:border-gray-600 dark:text-white;
|
|
}
|
|
|
|
.quick-filter-btn:not(.active) {
|
|
@apply dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600;
|
|
}
|
|
|
|
/* Enhanced filter panel styling */
|
|
.filter-container {
|
|
@apply dark:text-gray-200;
|
|
}
|
|
|
|
.filter-field label {
|
|
@apply dark:text-gray-300;
|
|
}
|
|
}
|
|
|
|
/* Additional enhancements for better visual hierarchy */
|
|
.filter-container h3 {
|
|
@apply font-semibold tracking-wide;
|
|
}
|
|
|
|
.filter-field {
|
|
@apply mb-4;
|
|
}
|
|
|
|
.filter-field label {
|
|
@apply font-medium text-sm;
|
|
}
|
|
|
|
/* Status badge improvements */
|
|
.status-badge {
|
|
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
|
|
@apply transition-all duration-200;
|
|
}
|
|
|
|
/* Loading state improvements */
|
|
.htmx-request .filter-container {
|
|
@apply pointer-events-none;
|
|
}
|
|
|
|
.htmx-request .quick-filter-btn {
|
|
@apply opacity-75;
|
|
}
|
|
|
|
/* Mobile Responsive Enhancements */
|
|
@media (max-width: 768px) {
|
|
.quick-filter-btn {
|
|
@apply text-xs px-2 py-1;
|
|
}
|
|
|
|
.filter-chip {
|
|
@apply text-xs px-2 py-1;
|
|
}
|
|
|
|
.park-card[data-view-mode="grid"]:hover {
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.park-card[data-view-mode="list"]:hover {
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
/* Accessibility Enhancements */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.park-card,
|
|
.quick-filter-btn,
|
|
.filter-chip,
|
|
.btn-enhanced {
|
|
transition: none;
|
|
animation: none;
|
|
}
|
|
|
|
.park-card:hover {
|
|
transform: none;
|
|
}
|
|
|
|
.no-results-icon {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/* Focus States for Keyboard Navigation */
|
|
.park-card:focus-within {
|
|
@apply ring-2 ring-blue-500 ring-offset-2;
|
|
}
|
|
|
|
.quick-filter-btn:focus,
|
|
.filter-chip .remove-btn:focus {
|
|
@apply ring-2 ring-blue-500 ring-offset-2;
|
|
}
|
|
|
|
/* High Contrast Mode Support */
|
|
@media (prefers-contrast: high) {
|
|
.park-card {
|
|
border-width: 2px;
|
|
}
|
|
|
|
.filter-chip {
|
|
border: 2px solid currentColor;
|
|
}
|
|
|
|
.quick-filter-btn {
|
|
border: 2px solid currentColor;
|
|
}
|
|
} |