mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 06:51:08 -05:00
346 lines
13 KiB
HTML
346 lines
13 KiB
HTML
<!-- Reusable Location Card Component -->
|
|
<div class="location-card {% if card_classes %}{{ card_classes }}{% endif %}"
|
|
{% if location.id %}data-location-id="{{ location.id }}"{% endif %}
|
|
{% if location.type %}data-location-type="{{ location.type }}"{% endif %}
|
|
{% if location.latitude and location.longitude %}data-lat="{{ location.latitude }}" data-lng="{{ location.longitude }}"{% endif %}
|
|
{% if clickable %}onclick="{{ onclick_action|default:'window.location.href=\''|add:location.get_absolute_url|add:'\'' }}"{% endif %}>
|
|
|
|
<!-- Card Header -->
|
|
<div class="flex items-start justify-between mb-3">
|
|
<div class="flex-1 min-w-0">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white truncate">
|
|
{% if location.name %}
|
|
{{ location.name }}
|
|
{% else %}
|
|
Unknown Location
|
|
{% endif %}
|
|
</h3>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 truncate">
|
|
{{ location.formatted_location|default:"Location not specified" }}
|
|
</p>
|
|
</div>
|
|
<div class="flex-shrink-0 ml-3">
|
|
<span class="location-type-badge location-type-{{ location.type|default:'unknown' }}">
|
|
{% if location.type == 'park' %}
|
|
<i class="mr-1 fas fa-tree"></i>Park
|
|
{% elif location.type == 'ride' %}
|
|
<i class="mr-1 fas fa-rocket"></i>Ride
|
|
{% elif location.type == 'company' %}
|
|
<i class="mr-1 fas fa-building"></i>Company
|
|
{% else %}
|
|
<i class="mr-1 fas fa-map-marker-alt"></i>Location
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Distance Badge (if applicable) -->
|
|
{% if location.distance %}
|
|
<div class="mb-3">
|
|
<span class="distance-badge">
|
|
<i class="mr-1 fas fa-route"></i>{{ location.distance|floatformat:1 }} miles away
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Type-specific Content -->
|
|
{% if location.type == 'park' %}
|
|
{% include 'maps/partials/park_card_content.html' with park=location %}
|
|
{% elif location.type == 'ride' %}
|
|
{% include 'maps/partials/ride_card_content.html' with ride=location %}
|
|
{% elif location.type == 'company' %}
|
|
{% include 'maps/partials/company_card_content.html' with company=location %}
|
|
{% endif %}
|
|
|
|
<!-- Action Buttons -->
|
|
{% if show_actions %}
|
|
<div class="flex gap-2 mt-4">
|
|
<a href="{{ location.get_absolute_url }}"
|
|
class="flex-1 px-3 py-2 text-sm text-center text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition-colors">
|
|
{{ primary_action_text|default:"View Details" }}
|
|
</a>
|
|
|
|
{% if location.latitude and location.longitude %}
|
|
<a href="{% url 'maps:nearby_locations' %}?lat={{ location.latitude }}&lng={{ location.longitude }}&radius=25"
|
|
class="px-3 py-2 text-sm text-blue-600 border border-blue-600 rounded-lg hover:bg-blue-50 dark:hover:bg-blue-900 transition-colors"
|
|
title="Find nearby locations">
|
|
<i class="fas fa-search-location"></i>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if show_map_action %}
|
|
<button onclick="showOnMap('{{ location.type }}', {{ location.id }})"
|
|
class="px-3 py-2 text-sm text-green-600 border border-green-600 rounded-lg hover:bg-green-50 dark:hover:bg-green-900 transition-colors"
|
|
title="Show on map">
|
|
<i class="fas fa-map-marker-alt"></i>
|
|
</button>
|
|
{% endif %}
|
|
|
|
{% if show_trip_action %}
|
|
<button onclick="addToTrip({{ location|safe }})"
|
|
class="px-3 py-2 text-sm text-purple-600 border border-purple-600 rounded-lg hover:bg-purple-50 dark:hover:bg-purple-900 transition-colors"
|
|
title="Add to trip">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Card Content Partials -->
|
|
|
|
<!-- Park Card Content -->
|
|
{% comment %}
|
|
This would be in templates/maps/partials/park_card_content.html
|
|
{% endcomment %}
|
|
<script type="text/template" id="park-card-content-template">
|
|
<div class="space-y-2">
|
|
{% if park.status %}
|
|
<div class="flex items-center">
|
|
<span class="status-badge {% if park.status == 'OPERATING' %}status-operating{% elif park.status == 'CLOSED_TEMP' or park.status == 'CLOSED_PERM' %}status-closed{% elif park.status == 'UNDER_CONSTRUCTION' %}status-construction{% else %}status-demolished{% endif %}">
|
|
{% if park.status == 'OPERATING' %}
|
|
<i class="mr-1 fas fa-check-circle"></i>Operating
|
|
{% elif park.status == 'CLOSED_TEMP' %}
|
|
<i class="mr-1 fas fa-clock"></i>Temporarily Closed
|
|
{% elif park.status == 'CLOSED_PERM' %}
|
|
<i class="mr-1 fas fa-times-circle"></i>Permanently Closed
|
|
{% elif park.status == 'UNDER_CONSTRUCTION' %}
|
|
<i class="mr-1 fas fa-hard-hat"></i>Under Construction
|
|
{% elif park.status == 'DEMOLISHED' %}
|
|
<i class="mr-1 fas fa-ban"></i>Demolished
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if park.operator %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-building"></i>
|
|
<span>{{ park.operator }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if park.ride_count %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-rocket"></i>
|
|
<span>{{ park.ride_count }} ride{{ park.ride_count|pluralize }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if park.average_rating %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-star text-yellow-500"></i>
|
|
<span>{{ park.average_rating|floatformat:1 }}/10</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if park.opening_date %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-calendar"></i>
|
|
<span>Opened {{ park.opening_date.year }}</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Ride Card Content -->
|
|
<script type="text/template" id="ride-card-content-template">
|
|
<div class="space-y-2">
|
|
{% if ride.park_name %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-tree"></i>
|
|
<span>{{ ride.park_name }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if ride.manufacturer %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-industry"></i>
|
|
<span>{{ ride.manufacturer }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if ride.designer %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-drafting-compass"></i>
|
|
<span>{{ ride.designer }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if ride.opening_date %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-calendar"></i>
|
|
<span>Opened {{ ride.opening_date.year }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if ride.status %}
|
|
<div class="flex items-center">
|
|
<span class="status-badge {% if ride.status == 'OPERATING' %}status-operating{% elif ride.status == 'CLOSED' %}status-closed{% elif ride.status == 'UNDER_CONSTRUCTION' %}status-construction{% else %}status-demolished{% endif %}">
|
|
{% if ride.status == 'OPERATING' %}
|
|
<i class="mr-1 fas fa-check-circle"></i>Operating
|
|
{% elif ride.status == 'CLOSED' %}
|
|
<i class="mr-1 fas fa-times-circle"></i>Closed
|
|
{% elif ride.status == 'UNDER_CONSTRUCTION' %}
|
|
<i class="mr-1 fas fa-hard-hat"></i>Under Construction
|
|
{% elif ride.status == 'DEMOLISHED' %}
|
|
<i class="mr-1 fas fa-ban"></i>Demolished
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Company Card Content -->
|
|
<script type="text/template" id="company-card-content-template">
|
|
<div class="space-y-2">
|
|
{% if company.company_type %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-tag"></i>
|
|
<span>{{ company.get_company_type_display }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if company.founded_year %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-calendar"></i>
|
|
<span>Founded {{ company.founded_year }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if company.website %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-globe"></i>
|
|
<a href="{{ company.website }}" target="_blank" class="text-blue-600 hover:text-blue-700 dark:text-blue-400">
|
|
Visit Website
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if company.parks_count %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-tree"></i>
|
|
<span>{{ company.parks_count }} park{{ company.parks_count|pluralize }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if company.rides_count %}
|
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<i class="mr-2 fas fa-rocket"></i>
|
|
<span>{{ company.rides_count }} ride{{ company.rides_count|pluralize }}</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Location Card Styles -->
|
|
<style>
|
|
.location-card {
|
|
@apply bg-white dark:bg-gray-800 rounded-lg p-4 shadow-sm hover:shadow-md transition-all border border-gray-200 dark:border-gray-700;
|
|
}
|
|
|
|
.location-card:hover {
|
|
@apply border-blue-300 dark:border-blue-600 shadow-lg;
|
|
}
|
|
|
|
.location-card.selected {
|
|
@apply ring-2 ring-blue-500 border-blue-500;
|
|
}
|
|
|
|
.location-card.clickable {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.location-type-badge {
|
|
@apply inline-flex items-center px-2 py-1 rounded-full text-xs font-medium;
|
|
}
|
|
|
|
.location-type-park {
|
|
@apply bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100;
|
|
}
|
|
|
|
.location-type-ride {
|
|
@apply bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100;
|
|
}
|
|
|
|
.location-type-company {
|
|
@apply bg-purple-100 text-purple-800 dark:bg-purple-800 dark:text-purple-100;
|
|
}
|
|
|
|
.location-type-unknown {
|
|
@apply bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-100;
|
|
}
|
|
|
|
.distance-badge {
|
|
@apply inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-100;
|
|
}
|
|
|
|
.status-badge {
|
|
@apply inline-flex items-center px-2 py-1 rounded-full text-xs font-medium;
|
|
}
|
|
|
|
.status-operating {
|
|
@apply bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100;
|
|
}
|
|
|
|
.status-closed {
|
|
@apply bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100;
|
|
}
|
|
|
|
.status-construction {
|
|
@apply bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100;
|
|
}
|
|
|
|
.status-demolished {
|
|
@apply bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-100;
|
|
}
|
|
</style>
|
|
|
|
<!-- Location Card JavaScript -->
|
|
<script>
|
|
// Global functions for location card actions
|
|
window.showOnMap = function(type, id) {
|
|
// Emit custom event for map integration
|
|
const event = new CustomEvent('showLocationOnMap', {
|
|
detail: { type, id }
|
|
});
|
|
document.dispatchEvent(event);
|
|
};
|
|
|
|
window.addToTrip = function(locationData) {
|
|
// Emit custom event for trip integration
|
|
const event = new CustomEvent('addLocationToTrip', {
|
|
detail: locationData
|
|
});
|
|
document.dispatchEvent(event);
|
|
};
|
|
|
|
// Handle location card selection
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.addEventListener('click', function(e) {
|
|
const card = e.target.closest('.location-card');
|
|
if (card && card.dataset.locationId) {
|
|
// Remove previous selections
|
|
document.querySelectorAll('.location-card.selected').forEach(c => {
|
|
c.classList.remove('selected');
|
|
});
|
|
|
|
// Add selection to clicked card
|
|
card.classList.add('selected');
|
|
|
|
// Emit selection event
|
|
const event = new CustomEvent('locationCardSelected', {
|
|
detail: {
|
|
id: card.dataset.locationId,
|
|
type: card.dataset.locationType,
|
|
lat: card.dataset.lat,
|
|
lng: card.dataset.lng,
|
|
element: card
|
|
}
|
|
});
|
|
document.dispatchEvent(event);
|
|
}
|
|
});
|
|
});
|
|
</script> |