weird header stuff

This commit is contained in:
pacnpal
2024-11-03 22:03:56 +00:00
parent ed585e6a56
commit 07526dcba8
34 changed files with 5047 additions and 185 deletions

View File

@@ -0,0 +1,44 @@
/* Alert Styles */
.alert {
@apply fixed z-50 px-4 py-3 transition-all duration-500 transform rounded-lg shadow-lg right-4 top-4;
animation: slideIn 0.5s ease-out forwards;
}
.alert-success {
@apply text-white bg-green-500;
}
.alert-error {
@apply text-white bg-red-500;
}
.alert-info {
@apply text-white bg-blue-500;
}
.alert-warning {
@apply text-white bg-yellow-500;
}
/* Animation keyframes */
@keyframes slideIn {
0% {
transform: translateX(100%);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOut {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(100%);
opacity: 0;
}
}

View File

@@ -0,0 +1,282 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
/* Button Styles */
.btn-primary {
@apply inline-flex items-center px-6 py-2.5 border border-transparent rounded-full shadow-md text-sm font-medium text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
}
.btn-secondary {
@apply inline-flex items-center px-6 py-2.5 border border-gray-200 dark:border-gray-700 rounded-full shadow-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
}
/* [Previous styles remain unchanged until mobile menu section...] */
/* Mobile Menu */
#mobileMenu {
@apply overflow-hidden transition-all duration-300 ease-in-out opacity-0 max-h-0;
}
#mobileMenu.show {
@apply max-h-[300px] opacity-100;
}
#mobileMenu .space-y-4 {
@apply pb-6;
}
.mobile-nav-link {
@apply flex items-center justify-center px-6 py-3 text-gray-700 transition-all border border-transparent rounded-lg dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary hover:border-primary/20 dark:hover:border-primary/30;
}
.mobile-nav-link i {
@apply text-xl transition-colors;
}
@media (max-width: 540px) {
.mobile-nav-link i {
@apply text-lg;
}
}
.mobile-nav-link.primary {
@apply text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90;
}
.mobile-nav-link.primary i {
@apply mr-3 text-white;
}
.mobile-nav-link.secondary {
@apply text-gray-700 bg-gray-100 dark:bg-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600;
}
.mobile-nav-link.secondary i {
@apply mr-3 text-gray-500 dark:text-gray-400;
}
/* Theme Toggle */
#theme-toggle+.theme-toggle-btn i::before {
content: "\f186";
font-family: "Font Awesome 5 Free";
font-weight: 900;
}
#theme-toggle:checked+.theme-toggle-btn i::before {
content: "\f185";
color: theme('colors.yellow.400');
}
/* Navigation Components */
.nav-link {
@apply flex items-center text-gray-700 transition-all dark:text-gray-200;
}
/* Extra small screens (540px and below) */
@media (max-width: 540px) {
.nav-link {
@apply px-2 py-2 text-sm;
}
.nav-link i {
@apply mr-1 text-base;
}
.nav-link span {
@apply text-sm;
}
.site-logo {
@apply px-1 text-lg;
}
.nav-container {
@apply px-2;
}
}
/* Small screens (541px to 767px) */
@media (min-width: 541px) and (max-width: 767px) {
.nav-link {
@apply px-3 py-2;
}
.nav-link i {
@apply mr-2;
}
.site-logo {
@apply px-2 text-xl;
}
.nav-container {
@apply px-4;
}
}
/* Medium screens and up */
@media (min-width: 768px) {
.nav-link {
@apply px-6 py-2.5 rounded-lg font-medium border border-transparent hover:border-primary/20 dark:hover:border-primary/30;
}
.nav-link i {
@apply mr-3 text-lg;
}
.site-logo {
@apply px-3 text-2xl;
}
.nav-container {
@apply px-6;
}
}
.nav-link:hover {
@apply text-primary dark:text-primary bg-primary/10 dark:bg-primary/20;
}
.nav-link i {
@apply text-gray-500 transition-colors dark:text-gray-400;
}
.nav-link:hover i {
@apply text-primary;
}
@media (min-width: 1024px) {
#mobileMenu {
@apply hidden !important;
}
}
/* Menu Items */
.menu-item {
@apply flex items-center w-full px-4 py-3 text-sm text-gray-700 transition-all dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary first:rounded-t-lg last:rounded-b-lg;
}
.menu-item i {
@apply mr-3 text-base text-gray-500 dark:text-gray-400;
}
/* Form Components */
.form-input {
@apply w-full px-4 py-3 text-gray-900 transition-all border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm dark:text-white focus:ring-2 focus:ring-primary/50 focus:border-primary;
}
.form-label {
@apply block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5;
}
.form-hint {
@apply mt-2 space-y-1 text-sm text-gray-500 dark:text-gray-400;
}
.form-error {
@apply mt-2 text-sm text-red-600 dark:text-red-400;
}
/* Status Badges */
.status-badge {
@apply inline-flex items-center px-3 py-1 text-sm font-medium rounded-full;
}
.status-operating {
@apply text-green-800 bg-green-100 dark:bg-green-700 dark:text-green-50;
}
.status-closed {
@apply text-red-800 bg-red-100 dark:bg-red-700 dark:text-red-50;
}
.status-construction {
@apply text-yellow-800 bg-yellow-100 dark:bg-yellow-600 dark:text-yellow-50;
}
/* Auth Components */
.auth-card {
@apply w-full max-w-md p-8 mx-auto border shadow-xl bg-white/90 dark:bg-gray-800/90 rounded-2xl backdrop-blur-sm border-gray-200/50 dark:border-gray-700/50;
}
.auth-title {
@apply mb-8 text-2xl font-bold text-center text-transparent bg-gradient-to-r from-primary to-secondary bg-clip-text;
}
.auth-divider {
@apply relative my-6 text-center;
}
.auth-divider::before,
.auth-divider::after {
@apply absolute top-1/2 w-1/3 border-t border-gray-200 dark:border-gray-700 content-[''];
}
.auth-divider::before {
@apply left-0;
}
.auth-divider::after {
@apply right-0;
}
.auth-divider span {
@apply px-4 text-sm text-gray-500 dark:text-gray-400 bg-white/90 dark:bg-gray-800/90;
}
/* Social Login Buttons */
.btn-social {
@apply w-full flex items-center justify-center px-6 py-3 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-[1.02] transition-all mb-3;
}
.btn-discord {
@apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
}
.btn-google {
@apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
}
/* Alert Components */
.alert {
@apply p-4 mb-4 shadow-lg rounded-xl backdrop-blur-sm;
}
.alert-success {
@apply text-green-800 border border-green-200 bg-green-100/90 dark:bg-green-800/30 dark:text-green-100 dark:border-green-700;
}
.alert-error {
@apply text-red-800 border border-red-200 bg-red-100/90 dark:bg-red-800/30 dark:text-red-100 dark:border-red-700;
}
.alert-warning {
@apply text-yellow-800 border border-yellow-200 bg-yellow-100/90 dark:bg-yellow-800/30 dark:text-yellow-100 dark:border-yellow-700;
}
.alert-info {
@apply text-blue-800 border border-blue-200 bg-blue-100/90 dark:bg-blue-800/30 dark:text-blue-100 dark:border-blue-700;
}
/* Layout Components */
.card {
@apply p-6 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50;
}
.card-hover {
@apply transition-transform transform hover:-translate-y-1;
}
.grid-cards {
@apply grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3;
}
/* Typography */
.heading-1 {
@apply mb-6 text-3xl font-bold text-gray-900 dark:text-white;
}
.heading-2 {
@apply mb-4 text-2xl font-bold text-gray-900 dark:text-white;
}
.text-body {
@apply text-gray-600 dark:text-gray-300;
}
/* Turnstile Widget */
.turnstile {
@apply flex items-center justify-center my-4;
}
}

3867
staticfiles/css/tailwind.css Normal file

File diff suppressed because it is too large Load Diff

18
staticfiles/js/alerts.js Normal file
View File

@@ -0,0 +1,18 @@
document.addEventListener('DOMContentLoaded', function() {
// Get all alert elements
const alerts = document.querySelectorAll('.alert');
// For each alert
alerts.forEach(alert => {
// After 5 seconds
setTimeout(() => {
// Add slideOut animation
alert.style.animation = 'slideOut 0.5s ease-out forwards';
// Remove the alert after animation completes
setTimeout(() => {
alert.remove();
}, 500);
}, 5000);
});
});

5
staticfiles/js/alpine.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
function locationAutocomplete(field, filterParks = false) {
return {
query: '',
suggestions: [],
fetchSuggestions() {
let url;
const params = new URLSearchParams({
q: this.query,
filter_parks: filterParks
});
switch (field) {
case 'country':
url = '/parks/ajax/countries/';
break;
case 'region':
url = '/parks/ajax/regions/';
// Add country parameter if we're fetching regions
const countryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
if (countryInput && countryInput.value) {
params.append('country', countryInput.value);
}
break;
case 'city':
url = '/parks/ajax/cities/';
// Add country and region parameters if we're fetching cities
const regionInput = document.getElementById(filterParks ? 'region' : 'id_region_name');
const cityCountryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
if (regionInput && regionInput.value && cityCountryInput && cityCountryInput.value) {
params.append('country', cityCountryInput.value);
params.append('region', regionInput.value);
}
break;
}
if (url) {
fetch(`${url}?${params}`)
.then(response => response.json())
.then(data => {
this.suggestions = data;
});
}
},
selectSuggestion(suggestion) {
this.query = suggestion.name;
this.suggestions = [];
// If this is a form field (not filter), update hidden fields
if (!filterParks) {
const hiddenField = document.getElementById(`id_${field}`);
if (hiddenField) {
hiddenField.value = suggestion.id;
}
// Clear dependent fields when parent field changes
if (field === 'country') {
const regionInput = document.getElementById('id_region_name');
const cityInput = document.getElementById('id_city_name');
const regionHidden = document.getElementById('id_region');
const cityHidden = document.getElementById('id_city');
if (regionInput) regionInput.value = '';
if (cityInput) cityInput.value = '';
if (regionHidden) regionHidden.value = '';
if (cityHidden) cityHidden.value = '';
} else if (field === 'region') {
const cityInput = document.getElementById('id_city_name');
const cityHidden = document.getElementById('id_city');
if (cityInput) cityInput.value = '';
if (cityHidden) cityHidden.value = '';
}
}
// Trigger form submission for filters
if (filterParks) {
htmx.trigger('#park-filters', 'change');
}
}
};
}

View File

@@ -0,0 +1,28 @@
let parkMap = null;
function initParkMap(latitude, longitude, name) {
const mapContainer = document.getElementById('park-map');
// Only initialize if container exists and map hasn't been initialized
if (mapContainer && !parkMap) {
const width = mapContainer.offsetWidth;
mapContainer.style.height = width + 'px';
parkMap = L.map('park-map').setView([latitude, longitude], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(parkMap);
L.marker([latitude, longitude])
.addTo(parkMap)
.bindPopup(name);
// Update map size when window is resized
window.addEventListener('resize', function() {
const width = mapContainer.offsetWidth;
mapContainer.style.height = width + 'px';
parkMap.invalidateSize();
});
}
}