mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 21:11:09 -05:00
Add autocomplete functionality for parks: implement URLs, views, and templates for real-time suggestions
This commit is contained in:
@@ -1,44 +1,37 @@
|
||||
/* 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;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 0.375rem;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@apply text-white bg-green-500;
|
||||
background-color: #E8F5E9;
|
||||
border: 1px solid #A5D6A7;
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@apply text-white bg-red-500;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
@apply text-white bg-blue-500;
|
||||
background-color: #FFEBEE;
|
||||
border: 1px solid #FFCDD2;
|
||||
color: #C62828;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
@apply text-white bg-yellow-500;
|
||||
background-color: #FFF3E0;
|
||||
border: 1px solid #FFCC80;
|
||||
color: #EF6C00;
|
||||
}
|
||||
|
||||
/* Animation keyframes */
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
.alert-info {
|
||||
background-color: #E3F2FD;
|
||||
border: 1px solid #90CAF9;
|
||||
color: #1565C0;
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
.alert.fade-out {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
21
static/js/alerts.js
Normal file
21
static/js/alerts.js
Normal file
@@ -0,0 +1,21 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const alerts = document.querySelectorAll('.alert');
|
||||
|
||||
alerts.forEach(alert => {
|
||||
// Auto-hide alerts after 5 seconds
|
||||
setTimeout(() => {
|
||||
alert.classList.add('fade-out');
|
||||
setTimeout(() => {
|
||||
alert.remove();
|
||||
}, 300); // Match CSS transition duration
|
||||
}, 5000);
|
||||
|
||||
// Add click-to-dismiss functionality
|
||||
alert.addEventListener('click', () => {
|
||||
alert.classList.add('fade-out');
|
||||
setTimeout(() => {
|
||||
alert.remove();
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
});
|
||||
50
static/js/location-autocomplete.js
Normal file
50
static/js/location-autocomplete.js
Normal file
@@ -0,0 +1,50 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const countryInput = document.querySelector('[name="country"]');
|
||||
const regionInput = document.querySelector('[name="region"]');
|
||||
const cityInput = document.querySelector('[name="city"]');
|
||||
|
||||
if (!countryInput || !regionInput || !cityInput) return;
|
||||
|
||||
// Update regions when country changes
|
||||
countryInput.addEventListener('change', () => {
|
||||
const country = countryInput.value;
|
||||
if (country) {
|
||||
updateRegions(country);
|
||||
// Clear city when country changes
|
||||
cityInput.innerHTML = '<option value="">Select a city</option>';
|
||||
}
|
||||
});
|
||||
|
||||
// Update cities when region changes
|
||||
regionInput.addEventListener('change', () => {
|
||||
const country = countryInput.value;
|
||||
const region = regionInput.value;
|
||||
if (country && region) {
|
||||
updateCities(country, region);
|
||||
}
|
||||
});
|
||||
|
||||
function updateRegions(country) {
|
||||
fetch(`/location/regions/?country=${encodeURIComponent(country)}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
regionInput.innerHTML = '<option value="">Select a region</option>';
|
||||
data.regions.forEach(region => {
|
||||
const option = new Option(region, region);
|
||||
regionInput.add(option);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateCities(country, region) {
|
||||
fetch(`/location/cities/?country=${encodeURIComponent(country)}®ion=${encodeURIComponent(region)}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
cityInput.innerHTML = '<option value="">Select a city</option>';
|
||||
data.cities.forEach(city => {
|
||||
const option = new Option(city, city);
|
||||
cityInput.add(option);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
40
static/js/main.js
Normal file
40
static/js/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// Theme Toggle
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
const themeIcon = themeToggle.nextElementSibling.querySelector('i');
|
||||
|
||||
// Set initial icon
|
||||
updateThemeIcon();
|
||||
|
||||
themeToggle.addEventListener('change', () => {
|
||||
if (document.documentElement.classList.contains('dark')) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.setItem('theme', 'light');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.setItem('theme', 'dark');
|
||||
}
|
||||
updateThemeIcon();
|
||||
});
|
||||
|
||||
function updateThemeIcon() {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
themeIcon.classList.remove('fa-sun', 'fa-moon');
|
||||
themeIcon.classList.add(isDark ? 'fa-sun' : 'fa-moon');
|
||||
}
|
||||
|
||||
// Mobile Menu Toggle
|
||||
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
||||
const mobileMenu = document.getElementById('mobileMenu');
|
||||
const menuIcon = mobileMenuBtn.querySelector('i');
|
||||
|
||||
mobileMenu.style.display = 'none';
|
||||
let isMenuOpen = false;
|
||||
|
||||
mobileMenuBtn.addEventListener('click', () => {
|
||||
isMenuOpen = !isMenuOpen;
|
||||
mobileMenu.style.display = isMenuOpen ? 'block' : 'none';
|
||||
menuIcon.classList.remove('fa-bars', 'fa-times');
|
||||
menuIcon.classList.add(isMenuOpen ? 'fa-times' : 'fa-bars');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user