Compare commits
9 Commits
aa15b6e1ee
...
a00d595ebb
Author | SHA1 | Date | |
---|---|---|---|
|
a00d595ebb | ||
|
e726441285 | ||
|
531d4627da | ||
|
0284db2568 | ||
|
ac5a66b054 | ||
|
bf6d441812 | ||
|
cbbf46bdb9 | ||
|
ac388a6e5b | ||
|
0abd71d498 |
@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.1.5 on 2023-11-06 20:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mainapp', '0003_waters'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='venue',
|
||||
name='active',
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='venue',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, max_length=500),
|
||||
),
|
||||
]
|
@ -14,7 +14,7 @@ class Venue(models.Model):
|
||||
)
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
description = models.TextField(blank=True)
|
||||
description = models.TextField(blank=True, max_length=500)
|
||||
extra_notes = models.TextField(blank=True)
|
||||
venue_type = models.CharField(choices=VENUE_TYPES, max_length=50)
|
||||
|
||||
@ -37,9 +37,17 @@ class Venue(models.Model):
|
||||
instagram_url = models.URLField(blank=True)
|
||||
facebook_url = models.URLField(blank=True)
|
||||
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def waters(self):
|
||||
"""Returns all waters linked to this venue."""
|
||||
|
||||
waters = Waters.objects.filter(venue=self)
|
||||
return waters
|
||||
|
||||
|
||||
class Waters(models.Model):
|
||||
"""Represents the waters of a Venue"""
|
||||
|
31
src/mainapp/templates/_index.html
Normal file
31
src/mainapp/templates/_index.html
Normal file
@ -0,0 +1,31 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{% static 'css/ocean.css' %}">
|
||||
{% endblock style %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="flex-grow-1 overflow-hidden">
|
||||
<div id="ocean">
|
||||
<div class="bubble bubble--1"></div>
|
||||
<div class="bubble bubble--2"></div>
|
||||
<div class="bubble bubble--3"></div>
|
||||
<div class="bubble bubble--4"></div>
|
||||
<div class="bubble bubble--5"></div>
|
||||
<div class="bubble bubble--6"></div>
|
||||
<div class="bubble bubble--7"></div>
|
||||
<div class="bubble bubble--8"></div>
|
||||
<div class="bubble bubble--9"></div>
|
||||
<div class="bubble bubble--10"></div>
|
||||
<div class="bubble bubble--11"></div>
|
||||
<div class="bubble bubble--12"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{% static 'js/ocean.js' %}"></script>
|
||||
{% endblock scripts %}
|
@ -1,31 +1,478 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}
|
||||
Venues |
|
||||
{% endblock title %}
|
||||
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{% static 'css/ocean.css' %}">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
|
||||
{% endblock style %}
|
||||
|
||||
{% block content %}
|
||||
{% block header_buttons %}
|
||||
{% endblock header_buttons %}
|
||||
|
||||
<div class="flex-grow-1 overflow-hidden">
|
||||
<div id="ocean">
|
||||
<div class="bubble bubble--1"></div>
|
||||
<div class="bubble bubble--2"></div>
|
||||
<div class="bubble bubble--3"></div>
|
||||
<div class="bubble bubble--4"></div>
|
||||
<div class="bubble bubble--5"></div>
|
||||
<div class="bubble bubble--6"></div>
|
||||
<div class="bubble bubble--7"></div>
|
||||
<div class="bubble bubble--8"></div>
|
||||
<div class="bubble bubble--9"></div>
|
||||
<div class="bubble bubble--10"></div>
|
||||
<div class="bubble bubble--11"></div>
|
||||
<div class="bubble bubble--12"></div>
|
||||
</div>
|
||||
{% block content %}
|
||||
<div class="px-4 bg-body shadow mb-5">
|
||||
<div class="d-flex justify-content-between align-items-center p-2 flex-wrap">
|
||||
<h1 class="fw-bold h4 mb-0 ms-2">Venues & Waters</h1>
|
||||
<div class="input-group w-auto">
|
||||
<div class="input-group-text bg-body pe-0">
|
||||
<i class="bi bi-search"></i>
|
||||
</div>
|
||||
<input type="search" class="form-control border-start-0" placeholder="Search Venues">
|
||||
</div>
|
||||
<div class="d-flex flex-row align-items-center">
|
||||
<button class="btn btn-primary rounded-2 me-3" onclick="openVenueModal(-1);">
|
||||
<i class="bi bi-plus-lg me-1"></i>
|
||||
New
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary border-secondary-subtle rounded-2 me-3">
|
||||
<i class="bi bi-upload me-1"></i>
|
||||
Import
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary border-secondary-subtle rounded-2 me-3">
|
||||
<i class="bi bi-sort-alpha-up me-sm-1"></i>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary border-secondary-subtle rounded-2">
|
||||
<i class="bi bi-filter-right me-sm-1"></i>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row flex-row-reverse my-4 mx-lg-4">
|
||||
<div class="col-lg-3 d-flex flex-column">
|
||||
<div id="locationMapContainer" class="w-100 position-relative shadow mb-4 bg-body rounded-3 overflow-hidden" style="height: 300px;">
|
||||
<div id="allLocationsMap" class="w-100 h-100"></div>
|
||||
</div>
|
||||
<div class="bg-body rounded-3 p-4 flex-grow-1 shadow mb-3">
|
||||
<div class="text-body small">
|
||||
placeholder<br>
|
||||
maybe a graph here?
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<div class="row gx-3 px-2 mt-0">
|
||||
{% for venue in venues %}
|
||||
<div class="col-xxl-4 col-xl-6 col-md-6 col-sm-12 mb-3">
|
||||
<div class="rounded-2 h-100 p-4 bg-body shadow d-flex flex-column">
|
||||
<header class="d-flex justify-content-between align-items-start mb-3 dropend">
|
||||
<div class="text-truncate">
|
||||
<h4 class="h6 mb-1 text-body-secondary small">
|
||||
{% if venue.venue_type == "FISHERY" %}
|
||||
Fishery
|
||||
{% elif venue.venue_type == "PRIVATE" %}
|
||||
Private
|
||||
{% elif venue.venue_type == "CLUB" %}
|
||||
Club
|
||||
{% endif %}
|
||||
</h4>
|
||||
<h4 class="h6 mb-0 me-2 text-truncate fw-bold">{{ venue.name }}</h4>
|
||||
</div>
|
||||
<button class="border-0 bg-transparent" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-three-dots fs-4 d-flex"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu rounded-4 overflow-hidden py-0 shadow-sm" style="width: fit-content; min-width: fit-content;">
|
||||
<li>
|
||||
<button class="dropdown-item hover-fill-primary py-2">
|
||||
<i class="bi bi-eye"></i>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="dropdown-divider my-0">
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item py-2" onclick="openVenueModal({{ venue.id }});">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="dropdown-divider my-0">
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item py-2 hover-fill-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<p class="text-body-secondary venue-description mb-4">{{ venue.description }}</p>
|
||||
<div class="d-flex align-items-center fs-6 mt-auto ">
|
||||
{% if venue.email_address %}
|
||||
<a href="mailto:{{ venue.email_address }}" class="text-reset text-hover-primary me-3" data-bs-toggle="tooltip" data-bs-title="{{ venue.email_address }}">
|
||||
<i class="bi bi-envelope-at"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if venue.phone_number %}
|
||||
<a href="tel:{{ venue.phone_number }}" class="text-reset text-hover-primary me-3" data-bs-toggle="tooltip" data-bs-title="{{ venue.phone_number }}">
|
||||
<i class="bi bi-telephone"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if venue.latitude and venue.longitude %}
|
||||
<a href="https://www.openstreetmap.org/?mlat={{ venue.latitude }}&mlon={{ venue.longitude }}" target="_blank" class="text-reset text-hover-primary me-3" data-bs-toggle="tooltip" data-bs-html="true" data-bs-title="{{ venue.street_address }}<br>{{ venue.city }}, {{ venue.provence }}<br>{{ venue.postal_code }}">
|
||||
<i class="bi bi-geo-alt"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if venue.website_url %}
|
||||
<a href="{{ venue.website_url }}" class="text-reset text-hover-primary me-3" target="_blank" data-bs-toggle="tooltip" data-bs-title="{{ venue.website_url }}">
|
||||
<i class="bi bi-globe2"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="d-inline mx-auto"></div>
|
||||
{% if venue.waters %}
|
||||
<div class="badge bg-info-subtle text-info-emphasis ms-2" data-bs-toggle="tooltip" data-bs-title="There are {{ venue.waters|length }} waters in this venue">
|
||||
{{ venue.waters|length }}
|
||||
<i class="bi bi-droplet-half "></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not venue.latitude or not venue.longitude or not venue.phone_number or not venue.website_url or not venue.email_address %}
|
||||
<div class="badge bg-warning-subtle text-warning-emphasis ms-2" data-bs-toggle="tooltip" data-bs-title="There are missing details for this venue">
|
||||
<i class="bi bi-exclamation-triangle"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not venue.active %}
|
||||
<div class="badge bg-danger-subtle text-danger-emphasis ms-2" data-bs-toggle="tooltip" data-bs-title="This venue is inactive">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="col-xxl-4 col-xl-6 col-md-6 col-sm-12">
|
||||
<div class="fluid-hover-zoom h-100 d-flex flex-column justify-content-center align-items-center" role="button" onclick="openVenueModal(-1);">
|
||||
<i class="bi bi-plus-lg fs-1"></i>
|
||||
<span class="fw-bold">
|
||||
Create new
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="venueModal" class="modal fade" data-venue-id="-1" data-bs-backdrop="static">
|
||||
<div class="modal-dialog modal-dialog-centered modal-fullscreen-lg-down modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title text-truncate me-5">New Venue</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="row g-0 flex-md-grow-1">
|
||||
<div class="col-md-1">
|
||||
<div id="sidebarNavigation" class="bg-body-tertiary">
|
||||
<div class="modal-sidebar flex-row flex-md-column align-items-start text-center" role="tablist">
|
||||
<button id="detailsTab" class="modal-sidebar-btn active" type="button" data-bs-toggle="tab" data-bs-target="#detailsContent" role="tab" aria-controls="detailsContent" aria-selected="true">
|
||||
<i class="bi bi-file-earmark-text"></i>
|
||||
</button>
|
||||
<button id="addressTab" class="modal-sidebar-btn" type="button" data-bs-toggle="tab" data-bs-target="#addressContent" role="tab" aria-controls="addressContent" aria-selected="false">
|
||||
<i class="bi bi-geo-alt"></i>
|
||||
</button>
|
||||
<button id="contactTab" class="modal-sidebar-btn" type="button" data-bs-toggle="tab" data-bs-target="#contactContent" role="tab" aria-controls="contactContent" aria-selected="false">
|
||||
<i class="bi bi-telephone"></i>
|
||||
</button>
|
||||
<button id="watersTab" class="modal-sidebar-btn" type="button" data-bs-toggle="tab" data-bs-target="#watersContent" role="tab" aria-controls="watersContent" aria-selected="false">
|
||||
<i class="bi bi-droplet-half"></i>
|
||||
</button>
|
||||
<button id="confirmTab" class="modal-sidebar-btn mt-md-auto" type="button" data-bs-toggle="tab" data-bs-target="#confirmContent" role="tab" aria-controls="confirmContent" aria-selected="false">
|
||||
<i class="bi bi-check-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-11 overflow-auto">
|
||||
<div class="tab-content d-inline-block w-100 h-100 py-3 px-4">
|
||||
<div id="detailsContent" class="tab-pane fade flex-column h-100 show active">
|
||||
<div class="form-floating mb-4">
|
||||
<input type="text" name="venueName" id="venueName" class="form-control" placeholder="">
|
||||
<label for="venueName" class="form-label">Venue Name</label>
|
||||
</div>
|
||||
<div class="form-floating mb-4">
|
||||
<textarea class="form-control" style="height: 150px; resize: none;" placeholder=""></textarea>
|
||||
<label for="" class="form-label">Description</label>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" name="venueType" id="venueFishery" class="form-check-input">
|
||||
<label for="venueFishery" class="form-check-label">Fishery</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" name="venueType" id="venueClub" class="form-check-input">
|
||||
<label for="venueClub" class="form-check-label">Club</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" name="venueType" id="venuePrivate" class="form-check-input">
|
||||
<label for="venuePrivate" class="form-check-label">Private</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input type="checkbox" name="venueActive" id="venueActive" class="form-check-input">
|
||||
<label for="venueActive" class="form-check-label">Venue is active?</label>
|
||||
</div>
|
||||
<div class="mt-5 mt-md-auto d-flex justify-content-end">
|
||||
<button class="btn btn-primary px-3" type="button" onclick="$('#addressTab').click();">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="addressContent" class="tab-pane fade flex-column h-100">
|
||||
<div class="form-floating mb-4">
|
||||
<input type="text" name="venueSearch" id="venueSearch" class="form-control" placeholder="">
|
||||
<label for="venueSearch" class="form-label">
|
||||
<i class="bi bi-search me-1"></i>
|
||||
Post Code or Street Address
|
||||
</label>
|
||||
</div>
|
||||
<div id="venueSearchResults" style="display: none">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueStreetNum" id="venueStreetNum" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueStreetNum" class="form-label">Street Number</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueStreet" id="venueStreet" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueStreet" class="form-label">Street Address</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueCity" id="venueCity" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueCity" class="form-label">Town/City</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueCounty" id="venueCounty" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueCounty" class="form-label">County/Region</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venuePost" id="venuePost" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venuePost" class="form-label">Post Code</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueCountry" id="venueCountry" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueCountry" class="form-label">Country</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueLat" id="venueLat" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueLat" class="form-label">Latitude</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="venueLng" id="venueLng" class="form-control-plaintext" placeholder="" readonly>
|
||||
<label for="venueLng" class="form-label">Longitude</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="venueSearchHelper" class="my-auto text-center">
|
||||
<label for="venueSearch" class="fs-4 mx-lg-4 text-body-secondary">Use the search to find your venue.</label>
|
||||
</div>
|
||||
<div class="mt-5 mt-md-auto d-flex justify-content-end">
|
||||
<button class="btn btn-outline-secondary me-3" type="button" onclick="$('#detailsTab').click();">Back</button>
|
||||
<button class="btn btn-primary px-3" type="button" onclick="$('#contactTab').click();">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="contactContent" class="tab-pane fade flex-column h-100">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-floating mb-4">
|
||||
<input type="tel" name="venuePhone" id="venuePhone" class="form-control" placeholder="">
|
||||
<label for="venuePhone" class="form-label">Phone Number</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-floating mb-4">
|
||||
<input type="email" name="venueEmail" id="venueEmail" class="form-control" placeholder="">
|
||||
<label for="venueEmail" class="form-label">Email Address</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating mb-4">
|
||||
<input type="url" name="venueWebsite" id="venueWebsite" class="form-control" placeholder="">
|
||||
<label for="venueWebsite" class="form-label">Website URL</label>
|
||||
</div>
|
||||
<div class="form-floating mb-4">
|
||||
<input type="url" name="venueFacebook" id="venueFacebook" class="form-control" placeholder="">
|
||||
<label for="" class="form-label">Facebook URL</label>
|
||||
</div>
|
||||
<div class="form-floating mb-4">
|
||||
<input type="url" name="venueInstagram" id="venueInstagram" class="form-control" placeholder="">
|
||||
<label for="venueInstagram" class="form-label">Instagram URL</label>
|
||||
</div>
|
||||
<div class="form-floating mb-4">
|
||||
<input type="url" name="venueTwitter" id="venueTwitter" class="form-control" placeholder="">
|
||||
<label for="venueTwitter" class="form-label">Twitter URL</label>
|
||||
</div>
|
||||
<div class="mt-5 mt-md-auto d-flex justify-content-end">
|
||||
<button class="btn btn-outline-secondary me-3" type="button" onclick="$('#addressTab').click();">Back</button>
|
||||
<button class="btn btn-primary px-3" type="button" onclick="$('#watersTab').click();">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="watersContent" class="tab-pane fade flex-column h-100">
|
||||
waters
|
||||
<div class="mt-5 mt-md-auto d-flex justify-content-end">
|
||||
<button class="btn btn-outline-secondary me-3" type="button" onclick="$('#contactTab').click();">Back</button>
|
||||
<button class="btn btn-primary px-3" type="button" onclick="$('#confirmTab').click();">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirmContent" class="tab-pane fade flex-column h-100">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="" id="" class="form-control-plaintext" placeholder="" readonly value="Chequered Lake">
|
||||
<label for="" class="form-label">Venue Name</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="" id="" class="form-control-plaintext" placeholder="" readonly value="Some description...">
|
||||
<label for="" class="form-label">Description</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" name="" id="" class="form-control-plaintext" placeholder="" readonly value="Fishery">
|
||||
<label for="" class="form-label">Venue Type</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 mt-md-auto d-flex justify-content-end">
|
||||
<button class="btn btn-outline-secondary me-3" type="button" onclick="$('#watersTab').click();">Back</button>
|
||||
<button class="btn btn-primary" type="button" onclick="alert('not implemented')">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div id="venueModal" class="modal fade" data-venue-id="-1" data-bs-backdrop="static">
|
||||
<div class="modal-dialog modal-dialog-centered modal-fullscreen-sm-down ">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">New Venue</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div id="newVenuePages" class="modal-body">
|
||||
<div id="detailsPage" class="page active">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" placeholder="">
|
||||
<label for="" class="form-label">Name</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<textarea class="form-control venue-textarea" placeholder=""></textarea>
|
||||
<label for="" class="form-label">Description</label>
|
||||
</div>
|
||||
<label class="form-label">Type</label>
|
||||
<div class="mb-3 group-radio-btns">
|
||||
<input type="radio" name="vType" id="vtFishery" class="btn-check">
|
||||
<label for="vtFishery" class="btn btn-outline-primary">Fishery</label>
|
||||
<input type="radio" name="vType" id="vtClub" class="btn-check">
|
||||
<label for="vtClub" class="btn btn-outline-primary">Club</label>
|
||||
<input type="radio" name="vType" id="vtPrivate" class="btn-check">
|
||||
<label for="vtPrivate" class="btn btn-outline-primary">Private</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="addressPage" class="page">
|
||||
<label class="form-label">Type part of the address or postcode to begin</label>
|
||||
<input type="text" class="form-control" placeholder="E.g. 'CR0 3RL' or '36 Factory Lane'">
|
||||
</div>
|
||||
<div id="contactPage" class="page">
|
||||
<div class="row mb-3">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating">
|
||||
<input type="tel" class="form-control" placeholder="">
|
||||
<label for="">Phone Number</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" placeholder="">
|
||||
<label for="">Email Address</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="url" class="form-control" placeholder="">
|
||||
<label for="">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
Website
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="url" class="form-control" placeholder="">
|
||||
<label for="">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
Facebook
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="url" class="form-control" placeholder="">
|
||||
<label for="">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
Instagram
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="url" class="form-control" placeholder="">
|
||||
<label for="">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
Twitter
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="watersPage" class="page">
|
||||
Waters
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary me-auto" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="button" id="newVenueBack" class="btn btn-secondary" style="display: none">
|
||||
<i class="bi bi-arrow-left me-1"></i>
|
||||
Back
|
||||
</button>
|
||||
<button type="button" id="newVenueNext" class="btn btn-primary">
|
||||
Next
|
||||
<i class="bi bi-arrow-right ms-1"></i>
|
||||
</button>
|
||||
<button type="button" id="newVenueFinished" class="btn btn-primary" style="display: none;">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{% static 'js/ocean.js' %}"></script>
|
||||
{% endblock scripts %}
|
||||
<script>
|
||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
||||
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl, {trigger : 'hover'}))
|
||||
</script>
|
||||
<script>
|
||||
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r, "places"]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
|
||||
key: "AIzaSyDFR2xw2LhMPb6FC8OrfiLrJZRMRLMocvw",
|
||||
v: "weekly",
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||
<script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
|
||||
<script src="{% static 'js/mainapp/venues.js' %}" data-csrfmiddlewaretoken="{{ csrf_token }}"></script>
|
||||
{% endblock scripts %}+
|
||||
|
@ -6,6 +6,7 @@
|
||||
{% endblock title %}
|
||||
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
|
||||
{% endblock style %}
|
||||
|
||||
{% block header_buttons %}
|
||||
@ -15,7 +16,7 @@
|
||||
|
||||
<div class="d-flex flex-column flex-grow-1">
|
||||
|
||||
<div class="m-4 mb-0 row">
|
||||
<div class="m-1 m-sm-4 mb-0 mt-4 row">
|
||||
<div class="col-xl-4 col-md-8 mb-md-0 mb-4">
|
||||
<div class="input-group">
|
||||
<button type="button" data-bs-toggle="dropdown" class="btn btn-outline-company border-secondary-subtle">
|
||||
@ -45,16 +46,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mx-4 my-2">
|
||||
<div class="row m-1 mx-sm-4 my-2">
|
||||
<div class="col-xl-7">
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-4 mt-0 row">
|
||||
<div class="m-1 m-sm-4 mt-0 row row-cols-xxl-5 row-cols-xl-4 row-cols-lg-3 g-3">
|
||||
{% for venue in venues %}
|
||||
<div class="col-xl-3 col-lg-4 col-sm-6 mb-4">
|
||||
<div class="card w-100 h-100 fluid-hover-zoom shadow-sm md-shadow-on-hover overflow-hidden flex-row">
|
||||
<div class="">
|
||||
<div class="card w-100 h-100 border-0 rounded-3 overflow-hidden">
|
||||
<div class="card-body bg-body-tertiary position-relative">
|
||||
<div class="d-flex justify-content-between align-items-stretch h-100">
|
||||
<div>
|
||||
<h5 class="card-title fw-semibold">{{ venue.name }}</h5>
|
||||
<p class="card-text mb-0">{{ venue.street_address }}</p>
|
||||
<p class="card-text mb-0">{{ venue.city }}, {{ venue.provence }}</p>
|
||||
<p class="card-text mb-3">{{ venue.postal_code }}</p>
|
||||
<div class="text-body-secondary">
|
||||
<p class="card-text mb-0">{{ venue.phone_number }}</p>
|
||||
<p class="card-text mb-0">{{ venue.email_address }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column justify-content-end align-items-end">
|
||||
<div class="badge company-bg rounded-pill end-0 top-0">
|
||||
6 Waters
|
||||
</div>
|
||||
<button class="mt-auto btn btn-outline-company rounded-circle" style="width: fit-content;" onclick="openVenueModal({{ venue.id }});">
|
||||
<i class="bi bi-gear"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="card w-100 h-100 shadow-sm overflow-hidden flex-row fluid-hover-zoom md-shadow-on-hover" data-venue-id="{{ venue.id }}">
|
||||
<div class="card-body d-flex">
|
||||
<div class="d-flex flex-column">
|
||||
<h5 class="card-title text-company mb-0">{{ venue.name }}</h5>
|
||||
@ -73,241 +98,382 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="card-badge-container">
|
||||
<div class="card-badge"></div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-vertical m-3 mt-auto">
|
||||
<a class="btn btn-outline-company rounded-top-4" href="{{ venue.id }}">
|
||||
<i class="bi bi-eye-fill"></i>
|
||||
</a>
|
||||
<button class="btn btn-outline-secondary rounded-bottom-4 ms-0" onclick="openVenueModal({{ venue.id }});">
|
||||
<button class="btn btn-outline-company rounded-bottom-4 ms-0" onclick="openVenueModal({{ venue.id }});">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="venueModal" class="modal fade">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content overflow-hidden rounded-4">
|
||||
<div class="modal-body border-bottom-0 p-0">
|
||||
<div class="card-badge-container">
|
||||
<div class="card-badge"></div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<h4 class="card-title text-company fw-bold mb-4">
|
||||
<span class="create" style="display: none">New Venue</span>
|
||||
<span class="edit" style="display: none">Edit Venue</span>
|
||||
</h4>
|
||||
<ul id="newVenueTabBtns" class="nav nav-pills mb-4 border d-flex" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueDetailsTabBtn" class="nav-link active" data-bs-toggle="pill" data-bs-target="#newVenueDetailsTab" type="button" role="tab" aria-controls="newVenueDetailsTab" aria-selected="true">Details</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueAddressTabBtn" class="nav-link" data-bs-toggle="pill" data-bs-target="#newVenueAddressTab" type="button" role="tab" aria-controls="newVenueAddressTab" aria-selected="false">Address</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueContactTabBtn" class="nav-link" data-bs-toggle="pill" data-bs-target="#newVenueContactTab" type="button" role="tab" aria-controls="newVenueContactTab" aria-selected="false">Contact</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueSocialsTabBtn" class="nav-link" data-bs-toggle="pill" data-bs-target="#newVenueSocialsTab" type="button" role="tab" aria-controls="newVenueSocialsTab" aria-selected="false">Socials</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueWatersTabBtn" class="nav-link" data-bs-toggle="pill" data-bs-target="#newVenueWatersTab" type="button" role="tab" aria-controls="newVenueWatersTab" aria-selected="false">Waters</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="newVenueTabs" class="tab-content">
|
||||
<div id="newVenueDetailsTab" class="tab-pane fade show active" role="tabpanel" aria-labelledby="newVenueDetailsTabBtn" tabindex="0">
|
||||
<div class="row g-4 align-items-center mb-3">
|
||||
<div class="col-12">
|
||||
<label for="venueName" class="form-label">Name</label>
|
||||
<input name="venueName" id="venueName" type="text" class="form-control" placeholder="Venue and Waters">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="venueType" class="form-label">Type</label>
|
||||
<select name="venueType" id="venueType" class="form-select">
|
||||
{% for type in venue_types %}
|
||||
<option value="{{ type.0 }}">{{ type.1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div id="venueModal" class="modal fade" data-venue-id="-1">
|
||||
<div class="modal-dialog modal-dialog-centered modal-fullscreen-sm-down">
|
||||
<div class="modal-content overflow-hidden rounded-4" style="min-height: 760px;">
|
||||
<div class="modal-header company-bg justify-content-center">
|
||||
<h4 class="card-title text-light fw-bold mb-0">
|
||||
<span class="create" style="display: none">New Venue</span>
|
||||
<span class="edit" style="display: none">Edit Venue</span>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body border-bottom-0 p-0 overflow-hidden">
|
||||
<ul id="newVenueTabBtns" class="nav nav-pills mb-4 d-flex w-100 justify-content-center py-2 bg-light" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueDetailsTabBtn" class="nav-link rounded-4 active" data-bs-toggle="pill" data-bs-target="#newVenueDetailsTab" type="button" role="tab" aria-controls="newVenueDetailsTab" aria-selected="true">Details</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueAddressTabBtn" class="nav-link rounded-4" data-bs-toggle="pill" data-bs-target="#newVenueAddressTab" type="button" role="tab" aria-controls="newVenueAddressTab" aria-selected="false">Address</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueContactTabBtn" class="nav-link rounded-4" data-bs-toggle="pill" data-bs-target="#newVenueContactTab" type="button" role="tab" aria-controls="newVenueContactTab" aria-selected="false">Contact</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button id="newVenueWatersTabBtn" class="nav-link rounded-4" data-bs-toggle="pill" data-bs-target="#newVenueWatersTab" type="button" role="tab" aria-controls="newVenueWatersTab" aria-selected="false">Waters</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="px-2 px-sm-4 pb-0">
|
||||
<form id="venueForm" n class="needs-validation" novalidate>
|
||||
<div id="newVenueTabs" class="tab-content">
|
||||
<div id="newVenueDetailsTab" class="tab-pane fade show active" role="tabpanel" aria-labelledby="newVenueDetailsTabBtn" tabindex="0">
|
||||
<div class="row g-4 align-items-start mb-3">
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<input name="venueName" id="venueName" type="text" class="form-control" placeholder="" minlength="3" maxlength="100" required>
|
||||
<label for="venueName" class="form-label">
|
||||
Name <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter the Venue's name</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-7">
|
||||
<div class="form-floating">
|
||||
<select name="venueType" id="venueType" class="form-select" placeholder="" required>
|
||||
<option disabled value="">Choose one ...</option>
|
||||
{% for type in venue_types %}
|
||||
<option value="{{ type.0 }}">{{ type.1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="venueType" class="form-label">
|
||||
Type of Venue <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please select a Venue type</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<textarea name="venueDescription" id="venueDescription" type="text" class="form-control venue-textarea" placeholder="" maxlength="500"></textarea>
|
||||
<label for="venueDescription" class="form-label">
|
||||
Description
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a brief description of the Venue</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<textarea name="venueExtraNotes" id="venueExtraNotes" type="text" class="form-control venue-textarea" placeholder="" maxlength="500"></textarea>
|
||||
<label for="venueExtraNotes" class="form-label">Extra Notes</label>
|
||||
<div class="invalid-feedback">Please enter any additional notes regarding the Venue</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="venueDescription" class="form-label">Description</label>
|
||||
<textarea name="venueDescription" id="venueDescription" type="text" class="form-control" rows="3" placeholder="A brief description of the Venues and Waters ..." style="max-height: 150px"></textarea>
|
||||
<div id="newVenueAddressTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueAddressTabBtn" tabindex="0">
|
||||
<div class="mb-3">
|
||||
<div class="form-floating">
|
||||
<input name="venueStreetAddress" id="venueStreetAddress" type="text" class="form-control" placeholder="" required>
|
||||
<label for="venueStreetAddress" class="form-label">
|
||||
Street Address <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a valid Street Address</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-4 align-items-start mb-3">
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<input name="venueCity" id="venueCity" type="text" class="form-control" placeholder="" required>
|
||||
<label for="venueCity" class="form-label">
|
||||
Town or City <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a Town or City</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<input name="venueProvence" id="venueProvence" type="text" class="form-control" placeholder="" required>
|
||||
<label for="venueProvence" class="form-label">
|
||||
Provence <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a Provence</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<input name="venuePostCode" id="venuePostCode" type="text" class="form-control" placeholder="" required>
|
||||
<label for="venuePostCode" class="form-label">
|
||||
Postal Code <strong class="text-danger">*</strong>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a Postal Code</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<!-- <input name="venueCountry" id="venueCountry" type="text" class="form-control" placeholder="" required> -->
|
||||
<select name="venueCountry" id="venueCountry" class="form-select" placeholder="" disabled required>
|
||||
<option value="UK">United Kingdom</option>
|
||||
</select>
|
||||
<label for="venueCountry" class="form-label">
|
||||
Country <i class="bi bi-lock-fill text-warning-emphasis"></i>
|
||||
</label>
|
||||
<div class="invalid-feedback">Please enter a Country</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-none">
|
||||
<input type="hidden" name="venueLatitude" id="venueLatitude">
|
||||
<input type="hidden" name="venueLongitude" id="venueLongitude">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div id="locationMapContainer" class="w-100 position-relative" style="height: 225px;">
|
||||
<div id="locationMap" class="rounded-2 w-100 h-100"></div>
|
||||
<div id="locationMapOverlay" style="display: none;">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="form-text">(<strong>Disclaimer:</strong> results fetched from clicking the map may be inaccurate)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueContactTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueContactTabBtn" tabindex="0">
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<input name="venuePhone" id="venuePhone" type="tel" class="form-control" placeholder="">
|
||||
<label for="venuePhone" class="form-label">Phone Number</label>
|
||||
<div class="invalid-feedback">Bad phone number</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-floating">
|
||||
<input name="venueEmail" id="venueEmail" type="email" class="form-control" placeholder="">
|
||||
<label for="venueEmail" class="form-label">Email Address</label>
|
||||
<div class="invalid-feedback"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<input name="venueWebsite" id="venueWebsite" type="url" class="form-control" placeholder="">
|
||||
<label for="venueWebsite" class="form-label">Website Address</label>
|
||||
<div class="invalid-feedback"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">
|
||||
<i class="bi bi-twitter" style="color: #1DA1F2"></i>
|
||||
</span>
|
||||
<div class="form-floating">
|
||||
<input name="venueTwitter" id="venueTwitter" type="url" class="form-control" placeholder="">
|
||||
<label for="venueTwitter" class="form-label d-flex align-items-center">
|
||||
Twitter Profile Address
|
||||
</label>
|
||||
<div class="invalid-feedback"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">
|
||||
<i class="bi bi-facebook" style="color: #4267B2"></i>
|
||||
</span>
|
||||
<div class="form-floating">
|
||||
<input name="venueFacebook" id="venueFacebook" type="url" class="form-control" placeholder="">
|
||||
<label for="venueFacebook" class="form-label d-flex align-items-center">
|
||||
Facebook Profile Address
|
||||
</label>
|
||||
<div class="invalid-feedback"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">
|
||||
<i class="bi bi-instagram" style="color: #D62976;"></i>
|
||||
</span>
|
||||
<div class="form-floating">
|
||||
<input name="venueInstagram" id="venueInstagram" type="url" class="form-control" placeholder="">
|
||||
<label for="venueInstagram" class="form-label d-flex align-items-center">
|
||||
Instagram Profile Address
|
||||
</label>
|
||||
<div class="invalid-feedback"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueWatersTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueWatersTabBtn" tabindex="0">
|
||||
<div class="pb-5 pt-0 d-flex justify-content-between align-items-center">
|
||||
<button class="btn btn-outline-secondary rounded-4 d-flex align-items-center">
|
||||
<i class="bi bi-info-lg"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-company rounded-4 d-flex align-items-center">
|
||||
<span>Add Waters</span>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="list-unstyled overflow-y-auto" style="max-height: 450px;">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start mb-4">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueAddressTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueAddressTabBtn" tabindex="0">
|
||||
<div class="mb-3">
|
||||
<label for="venueStreetAddress" class="form-label">Street Address</label>
|
||||
<input name="venueStreetAddress" id="venueStreetAddress" type="text" class="form-control" placeholder="Wharncliffe Rd">
|
||||
</div>
|
||||
<div class="row g-4 align-items-center mb-3">
|
||||
<div class="col-6">
|
||||
<label for="venueCity" class="form-label">City/Town</label>
|
||||
<input name="venueCity" id="venueCity" type="text" class="form-control" placeholder="Ilkeston">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="venueProvence" class="form-label">Provence</label>
|
||||
<input name="venueProvence" id="venueProvence" type="text" class="form-control" placeholder="Derbyshire">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="venuePostCode" class="form-label">Postal Code</label>
|
||||
<input name="venuePostCode" id="venuePostCode" type="text" class="form-control" placeholder="DE7 5GF">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueContactTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueContactTabBtn" tabindex="0">
|
||||
<div class="row g-4 align-items-center">
|
||||
<div class="col-6">
|
||||
<label for="venuePhone" class="form-label">Phone Number</label>
|
||||
<input name="venuePhone" id="venuePhone" type="tel" class="form-control" placeholder="0343 507 7006">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="venueEmail" class="form-label">Email Address</label>
|
||||
<input name="venueEmail" id="venueEmail" type="email" class="form-control" placeholder="admin@anglingtrust.net">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="venueWebsite" class="form-label">Website Address</label>
|
||||
<input name="venueWebsite" id="venueWebsite" type="url" class="form-control" placeholder="https://anglingtrust.net/">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueSocialsTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueSocialsTabBtn" tabindex="0">
|
||||
<div class="row g-4 align-items-center">
|
||||
<div class="col-12">
|
||||
<label for="venueTwitter" class="form-label d-flex align-items-center">
|
||||
<i class="bi bi-twitter me-2" style="color: #1DA1F2"></i>
|
||||
Twitter Link
|
||||
</label>
|
||||
<input name="venueTwitter" id="venueTwitter" type="url" class="form-control" placeholder="https://twitter.com/anglingtrust">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="venueFacebook" class="form-label d-flex align-items-center">
|
||||
<i class="bi bi-facebook me-2" style="color: #4267B2"></i>
|
||||
Facebook Link
|
||||
</label>
|
||||
<input name="venueFacebook" id="venueFacebook" type="url" class="form-control" placeholder="https://www.facebook.com/AnglingTrust">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="venueInstagram" class="form-label d-flex align-items-center">
|
||||
<i class="bi bi-instagram me-2" style="color: #D62976;"></i>
|
||||
Instagram Link
|
||||
</label>
|
||||
<input name="venueInstagram" id="venueInstagram" type="url" class="form-control" placeholder="https://www.instagram.com/angling_trust">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newVenueWatersTab" class="tab-pane fade" role="tabpanel" aria-labelledby="newVenueWatersTabBtn" tabindex="0">
|
||||
<div class="pb-4 px-3 pt-0 d-flex justify-content-between align-items-center border-bottom">
|
||||
<button class="btn btn-outline-secondary rounded-4 d-flex align-items-center">
|
||||
<i class="bi bi-info-lg"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-company rounded-4 d-flex align-items-center">
|
||||
<span>Add Waters</span>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush overflow-y-auto" style="max-height: 450px;">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">Section A · Coal Wharf, Market Drayton</div>
|
||||
<p class="mb-0">Commercial Water</p>
|
||||
<p class="mb-0 text-body-secondary">Specimen Carp</p>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-self-stretch">
|
||||
<span class="badge company-bg rounded-pill mb-4">1 · 36</span>
|
||||
<button class="btn btn-outline-secondary small rounded-4 mt-auto">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-top-0 p-4 pt-2">
|
||||
<button class="btn btn-secondary px-4 me-3 btn-facing-left" data-bs-dismiss="modal">Cancel</button>
|
||||
<button class="btn btn-company btn-facing-right">
|
||||
<div class="modal-footer bg-light border-top-0 px-4 py-3">
|
||||
<!-- <button type="button" class="btn btn-outline-danger rounded-4 me-auto px-3 edit" style="display: none">Delete</button>
|
||||
<button type="button" class="btn btn-outline-secondary me-3 rounded-4 px-3" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" id="saveVenue" class="btn btn-company rounded-4 px-3" form="venueForm">
|
||||
<span class="edit" style="display: none;">Save Edit</span>
|
||||
<span class="create" style="display: none;">Save New</span>
|
||||
</button> -->
|
||||
<button type="button" class="btn btn-outline-danger rounded-4">
|
||||
<i class="bi bi-trash2"></i>
|
||||
</button>
|
||||
<div class="mx-auto">
|
||||
<!-- <button type="button" id="newVenueTabLeft" class="btn btn-company rounded-4 me-1" disabled>
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
</button> -->
|
||||
<button type="submit" id="saveVenue" class="btn btn-company rounded-4 px-4" form="venueForm">
|
||||
<!-- <i class="bi bi-floppy"></i> -->
|
||||
<span class="edit" style="display: none;">Save Edit</span>
|
||||
<span class="create" style="display: none;">Save New</span>
|
||||
</button>
|
||||
<!-- <button type="button" id="newVenueTabRight" class="btn btn-company rounded-4 ms-1">
|
||||
<i class="bi bi-chevron-right"></i>
|
||||
</button> -->
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-secondary rounded-4" data-bs-dismiss="modal">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toastContainer" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{% static 'js/mainapp/venues.js' %}"></script>
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||
<script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
|
||||
<script src="{% static 'js/mainapp/venues.js' %}" data-csrfmiddlewaretoken="{{ csrf_token }}"></script>
|
||||
{% endblock scripts %}
|
||||
|
@ -10,6 +10,7 @@ urlpatterns = [
|
||||
path('venues/get-waters/<int:venue_id>', views.get_venue_waters, name="get-venue-waters"),
|
||||
path('venues/<int:venue_id>', views.venue_details, name="venue-details"),
|
||||
path("venues/api/<int:venue_id>", views.get_venue_details, name="venue-details"),
|
||||
path("venues/api/create", views.create_venue, name="create-venue"),
|
||||
|
||||
# path('bulk-peg/', views.bulk_create_pegs, name='bulk-peg'),
|
||||
path('get-angler-data/', views.get_angler_page_data, name='get-angler-data'),
|
||||
|
@ -18,7 +18,11 @@ from .models import Venue, Waters
|
||||
|
||||
|
||||
def index(request):
|
||||
return render(request, 'index.html')
|
||||
|
||||
venues = Venue.objects.all()
|
||||
context = {"venues": venues, "venue_types": Venue.VENUE_TYPES}
|
||||
|
||||
return render(request, 'index.html', context)
|
||||
|
||||
def results(request):
|
||||
return render(request, 'results.html')
|
||||
@ -47,6 +51,31 @@ def venue_details(request, venue_id):
|
||||
|
||||
return render(request, 'venue_details.html', context)
|
||||
|
||||
def create_venue(request):
|
||||
|
||||
if request.method != "POST":
|
||||
return JsonResponse({"error", "Method not allowed"}, status=403)
|
||||
|
||||
test = request.POST
|
||||
|
||||
attributes = {
|
||||
name: request.POST.get(name) for name in
|
||||
[field.name for field in Venue._meta.get_fields()]
|
||||
}
|
||||
venue_id = request.POST.get("id")
|
||||
|
||||
if venue_id:
|
||||
venue = Venue.objects.get(id=venue_id)
|
||||
for k, v in attributes.items():
|
||||
setattr(venue, k, v)
|
||||
|
||||
venue.save()
|
||||
return JsonResponse({"success": "successful update"}, status=200)
|
||||
|
||||
del attributes["id"]
|
||||
Venue.objects.create(**attributes)
|
||||
return JsonResponse({"success": "successful creation"}, status=200)
|
||||
|
||||
def get_venue_details(request, venue_id: int):
|
||||
|
||||
try:
|
||||
|
BIN
src/static/img/logo-horizontal.webp
Normal file
BIN
src/static/img/logo-horizontal.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
src/static/img/logo-icon-alt.webp
Normal file
BIN
src/static/img/logo-icon-alt.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
src/static/img/logo-icon.webp
Normal file
BIN
src/static/img/logo-icon.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
src/static/img/logo-text-alt.webp
Normal file
BIN
src/static/img/logo-text-alt.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
src/static/img/logo-text.webp
Normal file
BIN
src/static/img/logo-text.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
@ -1,17 +1,77 @@
|
||||
$(".sidebar-collapse-button").on("click", function () {
|
||||
// $(".sidebar-collapse-button").on("click", function () {
|
||||
|
||||
const sidebar = $("#sidebar")
|
||||
const content = $("#webContent")
|
||||
const collapsed = !sidebar.hasClass("sidebar-enlarged");
|
||||
// const sidebar = $("#sidebar")
|
||||
// const content = $("#webContent")
|
||||
// const collapsed = !sidebar.hasClass("sidebar-enlarged");
|
||||
|
||||
if (collapsed) {
|
||||
sidebar.addClass("sidebar-enlarged");
|
||||
sidebar.find(".nav-item").tooltip("disable");
|
||||
content.addClass("webcontent-collapsed")
|
||||
}
|
||||
else {
|
||||
sidebar.removeClass("sidebar-enlarged");
|
||||
sidebar.find(".nav-item").tooltip("enable");
|
||||
content.removeClass("webcontent-collapsed")
|
||||
}
|
||||
});
|
||||
// if (collapsed) {
|
||||
// sidebar.addClass("sidebar-enlarged");
|
||||
// sidebar.find(".nav-item").tooltip("disable");
|
||||
// content.addClass("webcontent-collapsed")
|
||||
// }
|
||||
// else {
|
||||
// sidebar.removeClass("sidebar-enlarged");
|
||||
// sidebar.find(".nav-item").tooltip("enable");
|
||||
// content.removeClass("webcontent-collapsed")
|
||||
// }
|
||||
// });
|
||||
|
||||
$(document).ready(function() {
|
||||
const getStoredTheme = () => localStorage.getItem("theme");
|
||||
const setStoredTheme = theme => localStorage.setItem("theme", theme);
|
||||
const getPreferredTheme = () => {
|
||||
const storedTheme = getStoredTheme();
|
||||
if (storedTheme) return storedTheme;
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
};
|
||||
|
||||
const setTheme = theme => {
|
||||
if (theme === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
theme = "dark";
|
||||
}
|
||||
$("body").attr("data-bs-theme", theme);
|
||||
};
|
||||
|
||||
const getThemeIcon = theme => {
|
||||
return {
|
||||
"auto": "diamond-half",
|
||||
"light": "sun",
|
||||
"dark": "moon-stars",
|
||||
}[theme];
|
||||
};
|
||||
|
||||
const showActiveTheme = (theme, focus = false) => {
|
||||
const themeSwitcherButton = $("#themeSwitcher");
|
||||
if (!themeSwitcherButton) {
|
||||
warn("theme switcher button not found");
|
||||
return;
|
||||
}
|
||||
|
||||
// Swap the shown icon
|
||||
const themeSwitcherIcon = $(themeSwitcherButton).find("i.bi");
|
||||
const newIcon = getThemeIcon(theme);
|
||||
themeSwitcherIcon.removeClass().addClass(`bi bi-${newIcon}`);
|
||||
|
||||
if (focus) themeSwitcherButton.focus();
|
||||
};
|
||||
|
||||
$("#themeSwitcher").on("click", function() {
|
||||
// 1. determine the current theme
|
||||
const theme = getStoredTheme();
|
||||
|
||||
// 2. rotate to the next theme
|
||||
const themes = ["light", "dark", "auto"];
|
||||
const nextIndex = themes.indexOf(theme) + 1;
|
||||
const nextTheme = nextIndex >= themes.length ? themes[0] : themes[nextIndex];
|
||||
|
||||
// 3. apply the new theme
|
||||
setStoredTheme(nextTheme);
|
||||
setTheme(nextTheme);
|
||||
showActiveTheme(nextTheme);
|
||||
});
|
||||
|
||||
var theme = getPreferredTheme();
|
||||
setTheme(theme);
|
||||
showActiveTheme(theme);
|
||||
|
||||
});
|
386
src/static/js/mainapp/_venues.js
Normal file
386
src/static/js/mainapp/_venues.js
Normal file
@ -0,0 +1,386 @@
|
||||
var marker = null;
|
||||
map = null;
|
||||
originalMapCoords = [51.509865, -0.118092];
|
||||
isGeocodingInProgress = false;
|
||||
scriptData = document.currentScript.dataset;
|
||||
|
||||
const formControls = [
|
||||
// Details Tab
|
||||
{
|
||||
id: "venueName",
|
||||
validation: function (element) {
|
||||
const value = element.val(); // FIELD IS VALID IF:
|
||||
return (!element.attr("required") || value.trim() !== ""); // - element is not required OR not empty
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
const minlength = element.attr("minlength");
|
||||
return `Enter a venue name longer than ${minlength} characters`;
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venueType",
|
||||
validation: function (element) {
|
||||
const value = element.val(); // FIELD IS VALID IF:
|
||||
return (!element.attr("required") || value !== null); // - element is not required OR not empty
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Please selected a type of venue";
|
||||
}
|
||||
},
|
||||
// Address Tab
|
||||
{
|
||||
id: "venueStreetAddress",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the street address of the venue";
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venueCity",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the town or city of the venue";
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venueProvence",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the provence of the venue";
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venuePostCode",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the postal code of the venue";
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venueLatitude",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the latitude of the venue";
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "venueLongitude",
|
||||
validation: function (element) {
|
||||
const value = element.val();
|
||||
return (!element.attr("required") || value.trim() !== "");
|
||||
},
|
||||
errorMessage: function (element) {
|
||||
return "Enter the longitude of the venue";
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
$("#newVenueAddressTabBtn").on("shown.bs.tab", function() {
|
||||
|
||||
if (!map) {
|
||||
var tileLayer = L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: false,
|
||||
})
|
||||
|
||||
map = L.map("locationMap", {
|
||||
center: originalMapCoords,
|
||||
zoom:8,
|
||||
layers: [tileLayer]
|
||||
});
|
||||
|
||||
const UKSouthWest = L.latLng(49.823809, -8.649357);
|
||||
const UKNorthEast = L.latLng(60.905124, 2.637773);
|
||||
const UKBounds = L.latLngBounds(UKSouthWest, UKNorthEast);
|
||||
|
||||
map.setMaxBounds(UKBounds);
|
||||
}
|
||||
|
||||
venueCoords = {
|
||||
lat: $("#venueLatitude").val(),
|
||||
lng: $("#venueLongitude").val()
|
||||
};
|
||||
if (venueCoords.lat && venueCoords.lng) {
|
||||
map.setView(new L.LatLng(venueCoords.lat, venueCoords.lng), 15);
|
||||
marker = L.marker(venueCoords).addTo(map);
|
||||
}
|
||||
|
||||
map.on('click', function (e) {
|
||||
if (isGeocodingInProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
toggleLoadingMap(true);
|
||||
var coordinates = e.latlng;
|
||||
|
||||
// Create a point feature from the clicked coordinates
|
||||
var clickedPoint = turf.point([coordinates.lng, coordinates.lat]);
|
||||
|
||||
// Define the UK boundary polygon coordinates (simplified for illustration)
|
||||
var ukBoundary = turf.polygon([
|
||||
[
|
||||
[-8.647, 59.688], // Northwest corner
|
||||
[-8.647, 49.784], // Southwest corner
|
||||
[1.768, 49.784], // Southeast corner
|
||||
[1.768, 59.688], // Northeast corner
|
||||
[-8.647, 59.688] // Close the polygon
|
||||
]
|
||||
]);
|
||||
|
||||
if (marker) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
|
||||
marker = L.marker(coordinates).addTo(map);
|
||||
var isInsideUK = turf.booleanPointInPolygon(clickedPoint, ukBoundary);
|
||||
|
||||
if (!isInsideUK) {
|
||||
alert("Please select a point within the UK");
|
||||
map.removeLayer(marker);
|
||||
toggleLoadingMap(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${coordinates.lat}&lon=${coordinates.lng}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.address; // check promise first
|
||||
|
||||
toggleLoadingMap(false);
|
||||
$("#venueStreetAddress").val(data.address.road || '');
|
||||
$("#venueCity").val(data.address.village || data.address.town || data.address.city);
|
||||
$("#venueProvence").val(data.address.county || data.address.state_district);
|
||||
$("#venuePostCode").val(data.address.postcode || '');
|
||||
// $("#venueCountry").val(data.address.country || '');
|
||||
$("#venueLatitude").val(coordinates.lat);
|
||||
$("#venueLongitude").val(coordinates.lng);
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(function() {map.invalidateSize(false)}, 200)
|
||||
});
|
||||
|
||||
function toggleLoadingMap(isLoading) {
|
||||
isGeocodingInProgress = isLoading;
|
||||
$("#saveVenue").prop("disabled", isLoading);
|
||||
$("#venueStreetAddress").prop("disabled", isLoading)
|
||||
$("#venueCity").prop("disabled", isLoading)
|
||||
$("#venueProvence").prop("disabled", isLoading)
|
||||
$("#venuePostCode").prop("disabled", isLoading)
|
||||
// $("#venueCountry").prop("disabled", isLoading)
|
||||
if (isLoading) {
|
||||
$("#locationMapOverlay").show();
|
||||
}
|
||||
else {
|
||||
$("#locationMapOverlay").hide();
|
||||
}
|
||||
}
|
||||
|
||||
$("#venueModal").on("hidden.bs.modal", function() {
|
||||
// Reset the map if we are done
|
||||
if (map) {
|
||||
map.setView(originalMapCoords, 8);
|
||||
|
||||
if (marker) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function openVenueModal(venue_id) {
|
||||
$("#venueModal").data("venue-id", venue_id);
|
||||
const detailsTab = new bootstrap.Tab("#newVenueDetailsTabBtn");
|
||||
detailsTab.show(); // back to the first tab
|
||||
|
||||
$("#venueForm .form-control, #venueForm .form-select").removeClass("is-valid is-invalid");
|
||||
$("#venueForm .invalid-feedback").text("");
|
||||
|
||||
if (venue_id == -1) {
|
||||
$("#venueModal .edit").hide();
|
||||
$("#venueModal .create").show();
|
||||
|
||||
$("#venueName").val("");
|
||||
$("#venueType").val("").change();
|
||||
$("#venueDescription").val("");
|
||||
$("#venueExtraNotes").val("");
|
||||
|
||||
$("#venueStreetAddress").val("");
|
||||
$("#venueCity").val("");
|
||||
$("#venueProvence").val("");
|
||||
$("#venuePostCode").val("");
|
||||
// $("#venueCountry").val("");
|
||||
$("#venueLatitude").val("");
|
||||
$("#venueLongitude").val("");
|
||||
|
||||
$("#venuePhone").val("");
|
||||
$("#venueEmail").val("");
|
||||
$("#venueWebsite").val("");
|
||||
|
||||
$("#venueTwitter").val("");
|
||||
$("#venueFacebook").val("");
|
||||
$("#venueInstagram").val("");
|
||||
}
|
||||
else {
|
||||
$("#venueModal .edit").show();
|
||||
$("#venueModal .create").hide();
|
||||
|
||||
$.ajax({
|
||||
url: `/venues/api/${venue_id}`,
|
||||
method: 'get',
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
const venue = response.data;
|
||||
|
||||
$("#venueName").val(venue.name);
|
||||
$("#venueType").val(venue.venue_type).change();
|
||||
$("#venueDescription").val(venue.description);
|
||||
$("#venueExtraNotes").val(venue.extra_notes);
|
||||
|
||||
$("#venueStreetAddress").val(venue.street_address);
|
||||
$("#venueCity").val(venue.city);
|
||||
$("#venueProvence").val(venue.provence);
|
||||
$("#venuePostCode").val(venue.postal_code);
|
||||
// $("#venueCountry").val(venue.country);
|
||||
$("#venueLatitude").val(venue.latitude);
|
||||
$("#venueLongitude").val(venue.longitude);
|
||||
|
||||
$("#venuePhone").val(venue.phone_number);
|
||||
$("#venueEmail").val(venue.email_address);
|
||||
$("#venueWebsite").val(venue.website_url);
|
||||
|
||||
$("#venueTwitter").val(venue.twitter_url);
|
||||
$("#venueFacebook").val(venue.facebook_url);
|
||||
$("#venueInstagram").val(venue.instagram_url);
|
||||
},
|
||||
error: function(error) {
|
||||
alert("error: " + JSON.stringify(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
new bootstrap.Modal("#venueModal").show();
|
||||
}
|
||||
|
||||
$("#venueForm").on("submit", function(event) {
|
||||
event.preventDefault();
|
||||
const valid = validateVenue();
|
||||
if (valid) saveVenue();
|
||||
});
|
||||
|
||||
function validateVenue() {
|
||||
|
||||
// Reset the validation indicators and messages
|
||||
$("#venueForm .form-control, #venueForm .form-select").removeClass("is-valid is-invalid");
|
||||
$("#venueForm .invalid-feedback").text("");
|
||||
|
||||
var valid = true;
|
||||
|
||||
formControls.forEach(function(control) {
|
||||
var element = $("#" + control.id);
|
||||
if (!control.validation(element)) {
|
||||
element.addClass("is-invalid");
|
||||
element.siblings(".invalid-feedback").text(control.errorMessage(element));
|
||||
valid = false;
|
||||
}
|
||||
else {
|
||||
element.addClass("is-valid");
|
||||
}
|
||||
});
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
function saveVenue() {
|
||||
var data = {
|
||||
name: $("#venueName").val(),
|
||||
description: $("#venueDescription").val(),
|
||||
extra_notes: "* placeholder *",
|
||||
venue_type: $("#venueType").val(),
|
||||
|
||||
street_address: $("#venueStreetAddress").val(),
|
||||
city: $("#venueCity").val(),
|
||||
provence: $("#venueProvence").val(),
|
||||
postal_code: $("#venuePostCode").val(),
|
||||
country: $("#venueCountry").val(),
|
||||
longitude: $("#venueLongitude").val(),
|
||||
latitude: $("#venueLatitude").val(),
|
||||
|
||||
phone_number: $("#venuePhone").val(),
|
||||
email_address: $("#venueEmail").val(),
|
||||
website_url: $("#venueWebsite").val(),
|
||||
|
||||
twitter_url: $("#venueTwitter").val(),
|
||||
facebook_url: $("#venueFacebook").val(),
|
||||
instagram_url: $("#venueInstagram").val(),
|
||||
|
||||
csrfmiddlewaretoken: scriptData.csrfmiddlewaretoken,
|
||||
active: 1
|
||||
}
|
||||
|
||||
const venue_id = $("#venueModal").data("venue-id");
|
||||
data.id = venue_id > -1 ? venue_id : null;
|
||||
|
||||
$.ajax({
|
||||
url: `/venues/api/create`,
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
data: data,
|
||||
success: function(response) {
|
||||
window.location.reload();
|
||||
},
|
||||
error: function(error) {
|
||||
alert("error: " + JSON.stringify(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#newVenueTabLeft").on("click", function() {
|
||||
|
||||
const currentTab = $("#newVenueTabBtns .nav-link.active").parent();
|
||||
const previousTabParent = currentTab.prev();
|
||||
const previousTab = previousTabParent.find(".nav-link");
|
||||
previousTab.click();
|
||||
|
||||
if (previousTabParent.is(":first-child")) {
|
||||
$("#newVenueTabLeft").prop("disabled", true);
|
||||
$("#newVenueTabRight").prop("disabled", false);
|
||||
}
|
||||
else {
|
||||
$("#newVenueTabRight").prop("disabled", false);
|
||||
$("#saveVenue").hide();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$("#newVenueTabRight").on("click", function() {
|
||||
|
||||
const currentTab = $("#newVenueTabBtns .nav-link.active").parent();
|
||||
const nextTabParent = currentTab.next();
|
||||
const nextTab = nextTabParent.find(".nav-link");
|
||||
nextTab.click();
|
||||
|
||||
if (nextTabParent.is(":last-child")) {
|
||||
$("#newVenueTabRight").prop("disabled", true);
|
||||
$("#saveVenue").show();
|
||||
$("#newVenueTabLeft").prop("disabled", false);
|
||||
}
|
||||
else {
|
||||
$("#newVenueTabLeft").prop("disabled", false);
|
||||
}
|
||||
|
||||
});
|
@ -1,72 +1,156 @@
|
||||
// function getWaters(venueID) {
|
||||
// $.ajax({
|
||||
// url: `/venues/get-waters/${venueID}`,
|
||||
// type: "GET",
|
||||
// "dataType": "json",
|
||||
// success: function (data) {
|
||||
// alert(JSON.stringify(data));
|
||||
// },
|
||||
// error: function (error) {
|
||||
// alert("error: " + error);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
function openVenueModal(venue_id) {
|
||||
if (venue_id == -1) {
|
||||
$("#venueModal .edit").hide();
|
||||
$("#venueModal .create").show();
|
||||
// showPage($("#newVenuePages .page:first"));
|
||||
$("#detailsTab").click();
|
||||
setTimeout(() => { $("#venueName").focus() }, 300);
|
||||
new bootstrap.Modal("#venueModal").show();
|
||||
}
|
||||
|
||||
$("#venueName").val("");
|
||||
$("#venueDescription").val("");
|
||||
$("#venueType").val("FISHERY").change();
|
||||
function showPage(page) {
|
||||
if (page.length === 0) return;
|
||||
$("#newVenuePages .page").removeClass("active");
|
||||
page.addClass("active");
|
||||
|
||||
$("#venueStreetAddress").val("");
|
||||
$("#venueCity").val("");
|
||||
$("#venueProvence").val("");
|
||||
$("#venuePostCode").val("")
|
||||
|
||||
$("#venuePhone").val("");
|
||||
$("#venueEmail").val("");
|
||||
$("#venueWebsite").val("");
|
||||
|
||||
$("#venueTwitter").val("");
|
||||
$("#venueFacebook").val("");
|
||||
$("#venueInstagram").val("");
|
||||
if (page.index() === 0) {
|
||||
$("#newVenueBack").hide();
|
||||
$("#newVenueNext").show();
|
||||
$("#newVenueFinished").hide();
|
||||
}
|
||||
else if (page.index() + 1 === $("#newVenuePages .page").length) {
|
||||
$("#newVenueBack").show();
|
||||
$("#newVenueNext").hide();
|
||||
$("#newVenueFinished").show();
|
||||
}
|
||||
else {
|
||||
$("#venueModal .edit").show();
|
||||
$("#venueModal .create").hide();
|
||||
|
||||
$.ajax({
|
||||
url: `/venues/api/${venue_id}`,
|
||||
method: 'get',
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
const venue = response.data;
|
||||
|
||||
$("#venueName").val(venue.name);
|
||||
$("#venueDescription").val(venue.description);
|
||||
$("#venueType").val(venue.venue_type).change();
|
||||
|
||||
$("#venueStreetAddress").val(venue.street_address);
|
||||
$("#venueCity").val(venue.city);
|
||||
$("#venueProvence").val(venue.provence);
|
||||
$("#venuePostCode").val(venue.postal_code)
|
||||
|
||||
$("#venuePhone").val(venue.phone_number);
|
||||
$("#venueEmail").val(venue.email_address);
|
||||
$("#venueWebsite").val(venue.website_url);
|
||||
|
||||
$("#venueTwitter").val(venue.twitter_url);
|
||||
$("#venueFacebook").val(venue.facebook_url);
|
||||
$("#venueInstagram").val(venue.instagram);
|
||||
},
|
||||
error: function(error) {
|
||||
alert("error: " + JSON.stringify(error));
|
||||
}
|
||||
});
|
||||
$("#newVenueBack").show();
|
||||
$("#newVenueNext").show();
|
||||
$("#newVenueFinished").hide();
|
||||
}
|
||||
}
|
||||
|
||||
new bootstrap.Modal("#venueModal").show();
|
||||
}
|
||||
$("#newVenueNext").on("click", function() {
|
||||
const currentPage = $("#newVenuePages .page.active");
|
||||
showPage(currentPage.next(".page"));
|
||||
});
|
||||
|
||||
$("#newVenueBack").on("click", function() {
|
||||
const currentPage = $("#newVenuePages .page.active");
|
||||
showPage(currentPage.prev(".page"));
|
||||
});
|
||||
|
||||
let map;
|
||||
|
||||
async function initMap() {
|
||||
const position = { lat: 54.7023545, lng: -3.2765753 };
|
||||
const { Map } = await google.maps.importLibrary("maps");
|
||||
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
|
||||
|
||||
map = new Map($("#allLocationsMap")[0], {
|
||||
zoom: 6,
|
||||
restriction: {
|
||||
latLngBounds: {
|
||||
north: 58.804,
|
||||
east: 2,
|
||||
south: 49.864,
|
||||
west: -8
|
||||
},
|
||||
strictBounds: true
|
||||
},
|
||||
center: position,
|
||||
mapId: "ALL_LOCATIONS_MAP",
|
||||
disableDefaultUI: true,
|
||||
});
|
||||
|
||||
window.initAutocomplete();
|
||||
|
||||
// const marker = new AdvancedMarkerElement({
|
||||
// map: map,
|
||||
// position: position,
|
||||
// title: "Test"
|
||||
// });
|
||||
|
||||
|
||||
|
||||
// const infoWindow = new google.maps.InfoWindow();
|
||||
// const infoWindowContent = $("#venueSearchResults")[0]
|
||||
// infoWindow.setContent(infoWindowContent);
|
||||
|
||||
// autoComplete.addListener("place_changed", () => {
|
||||
// // infoWindow.close();
|
||||
|
||||
// const place = autoComplete.getPlace();
|
||||
// alert(JSON.stringify(place, null, 4));
|
||||
|
||||
|
||||
// if (!place.geometry || !place.geometry.location) {
|
||||
// alert("Couldn't find place");
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
let autocomplete;
|
||||
|
||||
function initAutocomplete() {
|
||||
|
||||
autocomplete = new google.maps.places.Autocomplete(
|
||||
$("#venueSearch")[0],
|
||||
{
|
||||
componentRestrictions: { country: "gb" },
|
||||
fields: ["address_components", "geometry"],
|
||||
types: ["address"],
|
||||
strictBounds: false
|
||||
}
|
||||
)
|
||||
|
||||
autocomplete.addListener("place_changed", () => {
|
||||
const place = autocomplete.getPlace();
|
||||
|
||||
if (!place.geometry || !place.geometry.location) {
|
||||
alert("couldn't find this place");
|
||||
return;
|
||||
}
|
||||
|
||||
alert(JSON.stringify(place, null, 4));
|
||||
fillAddress(place);
|
||||
});
|
||||
}
|
||||
|
||||
window.initAutocomplete = initAutocomplete;
|
||||
|
||||
function fillAddressControl(component, types, fieldSelector, component_attr="long_name") {
|
||||
if (types.some(type => component.types.includes(type))) {
|
||||
$(fieldSelector).val(component[component_attr]);
|
||||
}
|
||||
}
|
||||
|
||||
function fillAddress(place) {
|
||||
|
||||
// Clear the fields first, because sometimes we cant find data to replace them.
|
||||
$("#venueSearchResults").show();
|
||||
$("#venueSearchHelper").hide();
|
||||
$("#addressContent input[readonly], #addressContent input[readonly='readonly']").val("");
|
||||
|
||||
place.address_components.forEach(component => {
|
||||
fillAddressControl(component, ["street_number"], "#venueStreetNum");
|
||||
fillAddressControl(component, ["route"], "#venueStreet");
|
||||
fillAddressControl(component, ["postal_town", "locality"], "#venueCity");
|
||||
fillAddressControl(component, ["administrative_area_level_2"], "#venueCounty");
|
||||
fillAddressControl(component, ["postal_code"], "#venuePost");
|
||||
fillAddressControl(component, ["country"], "#venueCountry");
|
||||
});
|
||||
|
||||
$("#venueLat").val(place.geometry.location.lat);
|
||||
$("#venueLng").val(place.geometry.location.lng);
|
||||
|
||||
// place.geometry.forEach(item => {
|
||||
// fillAddressControl(item, ["lat"], "#venueLat", "lat");
|
||||
// fillAddressControl(item, ["lng"], "#venueLng", "lng");
|
||||
// });
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
initMap();
|
||||
});
|
195
src/static/scss/_base.scss
Normal file
195
src/static/scss/_base.scss
Normal file
@ -0,0 +1,195 @@
|
||||
#webContent {
|
||||
margin-left: 80px;
|
||||
transition: margin 400ms ease-in-out;
|
||||
|
||||
&.webcontent-collapsed {
|
||||
margin-left: 280px !important;
|
||||
}
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
|
||||
color: white;
|
||||
background-color: #04385c;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
z-index: 3;
|
||||
padding: 1rem 0;
|
||||
|
||||
transition: width 400ms ease-in-out;
|
||||
overflow: hidden;
|
||||
|
||||
.sidebar-collapse-button {
|
||||
|
||||
display: inline-block;
|
||||
color: white;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: transform 200ms ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
&.sidebar-enlarged {
|
||||
width: 280px !important;
|
||||
|
||||
.sidebar-collapse-button { transform: rotate(-180deg); }
|
||||
|
||||
a.nav-link {
|
||||
text-align: start !important;
|
||||
|
||||
i.bi {
|
||||
margin: 0 1rem 0 .5rem !important;
|
||||
}
|
||||
|
||||
span.sidebar-item-text {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.sidebar-enlarged) {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#sidebar-brand {
|
||||
|
||||
max-width: 120px;
|
||||
align-self: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
padding: 0 .5rem;
|
||||
|
||||
}
|
||||
|
||||
ul.sidebar-items {
|
||||
|
||||
flex-direction: column;
|
||||
margin-bottom: auto;
|
||||
|
||||
li.nav-item {
|
||||
|
||||
a.nav-link {
|
||||
|
||||
color: inherit;
|
||||
transition: all 200ms;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover { background-color: rgba(0, 0, 0, 0.15); }
|
||||
|
||||
i.bi {
|
||||
// transition: all 200ms ease-in-out;
|
||||
// margin: 0 auto;
|
||||
}
|
||||
|
||||
span.sidebar-item-text {
|
||||
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// .card-badge-container {
|
||||
// position: relative;
|
||||
|
||||
// .card-badge {
|
||||
// aspect-ratio: 1 / 1;
|
||||
|
||||
// height: calc(100% + 20px);
|
||||
|
||||
// position: absolute;
|
||||
// top: calc(-30% - 21px);
|
||||
// left: -26px;
|
||||
|
||||
// background-color: #04385c;
|
||||
// border-bottom: 30px;
|
||||
// border-left: 30px;
|
||||
// border-right: 30px;
|
||||
|
||||
// transform: rotate(45deg);
|
||||
// // -webkit-transform: rotate(45deg);
|
||||
// }
|
||||
// }
|
||||
|
||||
#newVenueTabBtns {
|
||||
|
||||
// border-radius: 50rem;
|
||||
overflow: hidden;
|
||||
width: fit-content;
|
||||
|
||||
.nav-item > .nav-link {
|
||||
// border-radius: 1rem !important;
|
||||
|
||||
color: #04385c;
|
||||
|
||||
&.active {
|
||||
color: white;
|
||||
background-color: #04385c;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.btn-facing-left {
|
||||
border-top-left-radius: 1.2rem !important;
|
||||
border-bottom-left-radius: 1.2rem !important;
|
||||
border-top-right-radius: 0.8rem !important;
|
||||
border-bottom-right-radius: 0.8rem !important;
|
||||
}
|
||||
|
||||
.btn-facing-right {
|
||||
border-top-left-radius: 0.8rem !important;
|
||||
border-bottom-left-radius: 0.8rem !important;
|
||||
border-top-right-radius: 1.2rem !important;
|
||||
border-bottom-right-radius: 1.2rem !important;
|
||||
}
|
||||
|
||||
#venueModal .modal-content {
|
||||
min-height: 550px;
|
||||
}
|
||||
|
||||
#locationMapOverlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7); /* Darkened overlay with 70% opacity */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000; /* Ensure the overlay is above the map */
|
||||
}
|
||||
|
||||
.spinner {
|
||||
border: 4px solid rgba(255, 255, 255, 0.3); /* Light border for the spinner */
|
||||
border-top: 4px solid #3498db; /* Blue spinner */
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.venue-textarea {
|
||||
resize: none;
|
||||
min-height: 152px !important;
|
||||
}
|
@ -1,3 +1,166 @@
|
||||
|
||||
$primary-colour: #04385c;
|
||||
$primary-hover-colour: #085c8d;
|
||||
$danger-colour: #dc3545;
|
||||
$danger-subtle-colour: #f8d7da;
|
||||
$danger-emphasis-colour: #58151c;
|
||||
$secondary-emphasis-colour:red;
|
||||
$secondary-subtle-colour:red;
|
||||
$border-color: #dee2e6;
|
||||
$body-bg :#000;
|
||||
|
||||
.bg-primary {
|
||||
background-color: $primary-colour !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
&.btn-primary {
|
||||
border-color: $primary-colour;
|
||||
background-color: $primary-colour;
|
||||
transition: background-color 0.3s, border-color 0.3s;
|
||||
&:hover {
|
||||
border-color: $primary-hover-colour;
|
||||
background-color: $primary-hover-colour;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-outline-primary {
|
||||
color: $primary-colour;
|
||||
border-color: $primary-colour;
|
||||
transition: background-color 0.3s, border-color 0.3s;
|
||||
&:hover {
|
||||
color: white;
|
||||
border-color: $primary-hover-colour;
|
||||
background-color: $primary-hover-colour
|
||||
}
|
||||
.btn-check:checked + & {
|
||||
border-color: $primary-colour;
|
||||
background-color: $primary-colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.venue-description {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 5;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
max-width: 100%
|
||||
}
|
||||
|
||||
.nav-pills {
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
color: $primary-colour;
|
||||
&.active {
|
||||
color: white;
|
||||
background-color: $primary-colour;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-hover-primary {
|
||||
transition: color 0.3s;
|
||||
&:hover { color: $primary-colour !important; }
|
||||
}
|
||||
|
||||
.tooltip-inner { text-align: left; }
|
||||
|
||||
// Width Fit Content
|
||||
.w-fc { width: fit-content; }
|
||||
.mw-fc { min-width: fit-content; }
|
||||
.mxw-fc { max-width: fit-content; }
|
||||
|
||||
.hover-fill-secondary {
|
||||
background-color: transparent;
|
||||
transition: color 0.3s, background-color 0.3s;
|
||||
&:hover {
|
||||
color: $secondary-emphasis-colour;
|
||||
background-color: $secondary-subtle-colour;
|
||||
}
|
||||
}
|
||||
|
||||
.hover-fill-danger {
|
||||
background-color: transparent;
|
||||
transition: color 0.3s, background-color 0.3s;
|
||||
&:hover {
|
||||
color: $danger-emphasis-colour;
|
||||
background-color: $danger-subtle-colour;
|
||||
}
|
||||
}
|
||||
|
||||
.hover-fill-primary {
|
||||
background-color: transparent;
|
||||
transition: color 0.3s, background-color 0.3s;
|
||||
&:hover {
|
||||
color: white;
|
||||
background-color: $primary-hover-colour;
|
||||
}
|
||||
}
|
||||
|
||||
.separator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
line-height: normal;
|
||||
&::before,&::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
&:not(:empty)::before {
|
||||
margin-right: .75em;
|
||||
}
|
||||
&:not(:empty)::after {
|
||||
margin-left: .75em;
|
||||
}
|
||||
}
|
||||
|
||||
.fluid-hover-zoom {
|
||||
transition:
|
||||
.3s transform cubic-bezier(.155,1.105,.295,1.12),
|
||||
.3s box-shadow,
|
||||
.3s -webkit-transform cubic-bezier(.155,1.105,.295,1.12);
|
||||
backface-visibility: hidden;
|
||||
&:hover {
|
||||
transform: scale(1.035);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
.dropdown-item {
|
||||
&:active {
|
||||
color: black;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.venue-textarea {
|
||||
resize: none;
|
||||
min-height: 152px !important;
|
||||
}
|
||||
|
||||
#newVenuePages .page {
|
||||
display: none;
|
||||
&.active {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#webContent {
|
||||
margin-left: 80px;
|
||||
transition: margin 400ms ease-in-out;
|
||||
@ -103,45 +266,50 @@
|
||||
|
||||
}
|
||||
|
||||
.card-badge-container {
|
||||
position: relative;
|
||||
|
||||
.card-badge {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: -30px;
|
||||
|
||||
background-color: #04385c;
|
||||
border-bottom: 30px;
|
||||
border-left: 30px;
|
||||
border-right: 30px;
|
||||
|
||||
transform: rotate(45deg);
|
||||
-webkit-transform: rotate(45deg);
|
||||
}
|
||||
.pac-container {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
#newVenueTabBtns {
|
||||
// .card-badge-container {
|
||||
// position: relative;
|
||||
|
||||
border-radius: 50rem;
|
||||
overflow: hidden;
|
||||
width: fit-content;
|
||||
// .card-badge {
|
||||
// aspect-ratio: 1 / 1;
|
||||
|
||||
.nav-item > .nav-link {
|
||||
border-radius: 1rem !important;
|
||||
// height: calc(100% + 20px);
|
||||
|
||||
color: #04385c;
|
||||
// position: absolute;
|
||||
// top: calc(-30% - 21px);
|
||||
// left: -26px;
|
||||
|
||||
&.active {
|
||||
color: white;
|
||||
background-color: #04385c;
|
||||
}
|
||||
}
|
||||
// background-color: #04385c;
|
||||
// border-bottom: 30px;
|
||||
// border-left: 30px;
|
||||
// border-right: 30px;
|
||||
|
||||
}
|
||||
// transform: rotate(45deg);
|
||||
// // -webkit-transform: rotate(45deg);
|
||||
// }
|
||||
// }
|
||||
|
||||
// #newVenueTabBtns {
|
||||
|
||||
// // border-radius: 50rem;
|
||||
// overflow: hidden;
|
||||
// width: fit-content;
|
||||
|
||||
// .nav-item > .nav-link {
|
||||
// // border-radius: 1rem !important;
|
||||
|
||||
// color: #04385c;
|
||||
|
||||
// &.active {
|
||||
// color: white;
|
||||
// background-color: #04385c;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
.btn-facing-left {
|
||||
border-top-left-radius: 1.2rem !important;
|
||||
@ -157,6 +325,102 @@
|
||||
border-bottom-right-radius: 1.2rem !important;
|
||||
}
|
||||
|
||||
// bootstrap md breakpoint
|
||||
@media (min-width: 768px) {
|
||||
#sidebarNavigation {
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
#venueModal .modal-content > .row:first {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
#sidebarNavigation {
|
||||
border-radius: 0.375rem;
|
||||
overflow-y: hidden;
|
||||
width: fit-content;
|
||||
margin: 0.75rem auto;
|
||||
.modal-sidebar .modal-sidebar-btn {
|
||||
padding: 0.5rem 1rem !important;
|
||||
width: fit-content !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#venueModal .modal-content {
|
||||
min-height: 550px;
|
||||
overflow: hidden;
|
||||
.modal-sidebar {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
.modal-sidebar-btn {
|
||||
background-color: inherit;
|
||||
text-align: inherit;
|
||||
border: 0;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
padding: 0.75rem 1.5rem;
|
||||
display: block;
|
||||
width: 100%;
|
||||
transition: background-color 0.15s, color 0.15s;
|
||||
&:hover {
|
||||
background-color: $primary-hover-colour;
|
||||
color: white;
|
||||
}
|
||||
// &:active {
|
||||
// background-color: $primary-colour;
|
||||
// color: white;
|
||||
// }
|
||||
&.active {
|
||||
background-color: $primary-colour !important;
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tab-content > .active {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
#venueModal
|
||||
|
||||
.location-map {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7); /* Darkened overlay with 70% opacity */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000; /* Ensure the overlay is above the map */
|
||||
}
|
||||
|
||||
.spinner {
|
||||
border: 4px solid rgba(255, 255, 255, 0.3); /* Light border for the spinner */
|
||||
border-top: 4px solid #3498db; /* Blue spinner */
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.venue-textarea {
|
||||
resize: none;
|
||||
min-height: 152px !important;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .group-radio-btns label {
|
||||
color: white !important;
|
||||
}
|
101
src/templates/_base.html
Normal file
101
src/templates/_base.html
Normal file
@ -0,0 +1,101 @@
|
||||
{% load compress %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{% endblock title %}Angling Trust Results</title>
|
||||
|
||||
{% load static %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'icons/font/bootstrap-icons.min.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/custom.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}" media="screen">
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/x-scss" href="{% static 'scss/base.scss' %}" media="screen">
|
||||
{% endcompress %}
|
||||
{% include 'fonts.html' %}
|
||||
{% block style %}
|
||||
{% endblock style %}
|
||||
</head>
|
||||
<body class="font-helvetica mw-100">
|
||||
<div class="container">
|
||||
|
||||
|
||||
<div class="d-flex align-content-stretch h-100 align-self-stretch">
|
||||
<aside id="sidebar" class="shadow-lg font-raleway">
|
||||
<a id="sidebar-brand" class="mb-3 mb-md-0" href="/">
|
||||
<img src="{% static 'img/at-logo.png' %}" alt="" class="w-100">
|
||||
</a>
|
||||
<hr class="mx-2">
|
||||
<ul class="sidebar-items nav nav-pills">
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Home">
|
||||
<a class="nav-link py-3" href="/">
|
||||
<i class="bi bi-house-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Home</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Anglers">
|
||||
<a class="nav-link py-3" href="/anglers">
|
||||
<i class="bi bi-people-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Anglers</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Venues and Waters">
|
||||
<a class="nav-link py-3" href="/venues">
|
||||
<i class="bi bi-droplet-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Venues and Waters</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Matches">
|
||||
<a class="nav-link py-3" href="#">
|
||||
<i class="bi bi-award-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Matches</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Scoreboard">
|
||||
<a class="nav-link py-3" href="#">
|
||||
<i class="bi bi-clipboard-data-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Scoreboard</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="sidebar-items nav nav-pills mb-0">
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Admin">
|
||||
<a class="nav-link py-3" href="/admin">
|
||||
<i class="bi bi-person-fill-gear fs-4"></i>
|
||||
<span class="sidebar-item-text">Administration</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr class="mx-2">
|
||||
<button class="sidebar-collapse-button">
|
||||
<i class="bi bi-chevron-double-right"></i>
|
||||
</button>
|
||||
</aside>
|
||||
<div class="flex-grow-1 d-flex flex-column" id="webContent">
|
||||
<div class="bg-body-secondary shadow-sm p-3 align-items-center" id="pageHeader" style="display: none;"> <!-- style="display: flex;" -->
|
||||
<h1 class="h2 mb-0" id="headerTitle"></h1>
|
||||
<div class="ms-auto">
|
||||
{% block header_buttons %}
|
||||
{% endblock header_buttons %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 d-flex overflow-auto">
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="{% static 'js/jquery-3.6.3.min.js' %}"></script>
|
||||
<script src="{% static 'js/jquery.validate.min.js' %}"></script>
|
||||
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
|
||||
<script src="{% static 'js/custom.js' %}"></script>
|
||||
<script src="{% static 'js/base.js' %}"></script>
|
||||
{% block scripts %}
|
||||
{% endblock scripts %}
|
||||
</body>
|
||||
</html>
|
@ -1,3 +1,4 @@
|
||||
{% load static %}
|
||||
{% load compress %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@ -6,11 +7,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{% endblock title %}Angling Trust Results</title>
|
||||
|
||||
{% load static %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/custom.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'icons/font/bootstrap-icons.min.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/custom.css' %}" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}" media="screen">
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/x-scss" href="{% static 'scss/base.scss' %}" media="screen">
|
||||
{% endcompress %}
|
||||
@ -18,80 +17,113 @@
|
||||
{% block style %}
|
||||
{% endblock style %}
|
||||
</head>
|
||||
<body class="font-helvetica mw-100">
|
||||
<body class="overflow-y-auto font-montserrat bg-body-tertiary">
|
||||
|
||||
<div class="d-flex align-content-stretch h-100 align-self-stretch">
|
||||
<aside id="sidebar" class="shadow-lg font-raleway">
|
||||
<a id="sidebar-brand" class="mb-3 mb-md-0" href="/">
|
||||
<img src="{% static 'img/at-logo.png' %}" alt="" class="w-100">
|
||||
<nav id="navbar" class="navbar navbar-expand-lg navbar-dark" style="background-color: #04385c;">
|
||||
<div class="container-fluid">
|
||||
<a href="#" class="navbar-brand mx-auto ms-sm-4 me-sm-5 user-select-none">
|
||||
<img src="{% static 'img/logo-icon-alt.webp' %}" class="me-1" height="45px" alt="Brand Logo">
|
||||
<img src="{% static 'img/logo-text-alt.webp' %}" height="40px" alt="Brand Logo">
|
||||
</a>
|
||||
<hr class="mx-2">
|
||||
<ul class="sidebar-items nav nav-pills">
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Home">
|
||||
<a class="nav-link py-3" href="/">
|
||||
<i class="bi bi-house-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Home</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Anglers">
|
||||
<a class="nav-link py-3" href="/anglers">
|
||||
<i class="bi bi-people-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Anglers</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Venues and Waters">
|
||||
<a class="nav-link py-3" href="/venues">
|
||||
<i class="bi bi-droplet-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Venues and Waters</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Matches">
|
||||
<a class="nav-link py-3" href="#">
|
||||
<i class="bi bi-award-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Matches</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Scoreboard">
|
||||
<a class="nav-link py-3" href="#">
|
||||
<i class="bi bi-clipboard-data-fill fs-4"></i>
|
||||
<span class="sidebar-item-text">Scoreboard</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="sidebar-items nav nav-pills mb-0">
|
||||
<li class="nav-item" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-custom-class="light-tooltip" data-bs-title="Admin">
|
||||
<a class="nav-link py-3" href="/admin">
|
||||
<i class="bi bi-person-fill-gear fs-4"></i>
|
||||
<span class="sidebar-item-text">Administration</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr class="mx-2">
|
||||
<button class="sidebar-collapse-button">
|
||||
<i class="bi bi-chevron-double-right"></i>
|
||||
<button class="navbar-toggler mx-auto my-3 my-sm-0 me-sm-4" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</aside>
|
||||
<div class="flex-grow-1 d-flex flex-column" id="webContent">
|
||||
<div class="bg-body-secondary shadow-sm p-3 align-items-center" id="pageHeader" style="display: none;"> <!-- style="display: flex;" -->
|
||||
<h1 class="h2 mb-0" id="headerTitle"></h1>
|
||||
<div class="ms-auto">
|
||||
{% block header_buttons %}
|
||||
{% endblock header_buttons %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 d-flex overflow-auto">
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
<div id="navbarCollapse" class="collapse navbar-collapse mx-4 mx-lg-0 mt-3 mt-lg-0">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0 fw-bold small">
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link pe-3">Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link pe-3 active">Venues & Waters</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link pe-3">Other Page</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr class="d-lg-none">
|
||||
<ul class="navbar-nav mb-2 mb-lg-0 me-0 me-lg-4 flex-row flex-wrap">
|
||||
<li class="nav-item mb-2 mb-lg-0">
|
||||
<button id="themeSwitcher" class="btn btn-outline-light border-0 border-secondary-subtle d-flex align-items-center justify-content-center me-3">
|
||||
<i class="bi"></i>
|
||||
<span class="d-lg-none ms-2">Theme</span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item mb-2 mb-lg-0 dropdown position-relative">
|
||||
<button class="btn btn-outline-light border-0 border-secondary-subtle d-flex align-items-center justify-content-center me-3" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-bell"></i>
|
||||
<span class="d-lg-none ms-2">Notifications</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end position-absolute me-3 p-3" style="min-width: 15rem;">
|
||||
<li class="text-center text-body-secondary small">
|
||||
There are no notifications right now
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item mb-2 mb-lg-0 ms-auto ms-lg-0 dropdown position-relative">
|
||||
<button class="btn btn-outline-light rounded-pill border-secondary-subtle d-flex align-items-center justify-content-center me-3" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-person me-2"></i>
|
||||
<span class="d-lg-none me-2">Administrator</span>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end position-absolute me-3">
|
||||
<li>
|
||||
<a href="" class="dropdown-item">
|
||||
<i class="bi bi-gear me-2"></i>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="" class="dropdown-item text-danger">
|
||||
<i class="bi bi-box-arrow-right me-2"></i>
|
||||
Logout
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
<footer class="bg-dark text-light">
|
||||
<div class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<h3>
|
||||
<img src="{% static 'img/at-logo.png' %}" width="200px" alt="">
|
||||
</h3>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<h5>Links</h5>
|
||||
<ul class="list-unstyled ps-3">
|
||||
<li>
|
||||
<a href="#" class="text-reset text-decoration-none">Dashboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-reset text-decoration-none">Venues & Waters</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-reset text-decoration-none">Other</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<h5>Contact</h5>
|
||||
<ul>
|
||||
placeholder
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="{% static 'js/jquery-3.6.3.min.js' %}"></script>
|
||||
<script src="{% static 'js/jquery.validate.min.js' %}"></script>
|
||||
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
|
||||
<script src="{% static 'js/custom.js' %}"></script>
|
||||
<!-- <script src="{% static 'js/custom.js' %}"></script> -->
|
||||
<script src="{% static 'js/base.js' %}"></script>
|
||||
{% block scripts %}
|
||||
{% endblock scripts %}
|
||||
|
@ -1,6 +1,18 @@
|
||||
{% load static %}
|
||||
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("{% static 'fonts/Montserrat/ExtraBold.ttf' %}") format("truetype");
|
||||
font-weight: bolder;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("{% static 'fonts/Montserrat/Bold.ttf' %}") format("truetype");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("{% static 'fonts/Montserrat/Regular.ttf' %}") format("truetype");
|
||||
|
Loading…
x
Reference in New Issue
Block a user